StevenD
New member
Hello.
I've got a project with the main purpose is to get the period of two frequencies. The frequency I care about is about 33 kHz. Based on some initial testing it seems that I need to get this period reliably to 1 nanosecond resolution (.1 would be ideal). I am using a Teensy 4.0 using two interrupt function to read the pulses. I currently have a working prototype where I can accurately read both signals and I can get my 1 nanosecond resolution if I read the pulses for about a second.
My original implementation was to use interrupt functions to increment a counter, then at a set amount of delay total the pulses and get period (time/frequency) in micro seconds. This worked, but even with one second of counting time if I missed a single pulse it would be different enough to not be desirable. I am pretty sure the problem there was I could read the pulses and time accurately, but the first and last pulse may or may not have triggered, and as I said in a static system I would see changes that based on the hardware we bought for this project would make it undesireable.
With that in mind, I changed from reading pulses in a fixed time to reading a number of pulses and when I had roughly what I knew to be about one seconds worth of pulses I would then trigger an if condition and grab the time. This is working much better and I can pretty reliably get the period to within .5 nanoseconds.
My questions are:
There's quite a bit more code, but I will include the important bits relevant to this message below. Also of note, the TPeriod is vastly more important than the XPeriod. If there is a way to prioritize it above everything else.
I've got a project with the main purpose is to get the period of two frequencies. The frequency I care about is about 33 kHz. Based on some initial testing it seems that I need to get this period reliably to 1 nanosecond resolution (.1 would be ideal). I am using a Teensy 4.0 using two interrupt function to read the pulses. I currently have a working prototype where I can accurately read both signals and I can get my 1 nanosecond resolution if I read the pulses for about a second.
My original implementation was to use interrupt functions to increment a counter, then at a set amount of delay total the pulses and get period (time/frequency) in micro seconds. This worked, but even with one second of counting time if I missed a single pulse it would be different enough to not be desirable. I am pretty sure the problem there was I could read the pulses and time accurately, but the first and last pulse may or may not have triggered, and as I said in a static system I would see changes that based on the hardware we bought for this project would make it undesireable.
With that in mind, I changed from reading pulses in a fixed time to reading a number of pulses and when I had roughly what I knew to be about one seconds worth of pulses I would then trigger an if condition and grab the time. This is working much better and I can pretty reliably get the period to within .5 nanoseconds.
My questions are:
- Can I get this period faster (within 1 nanosecond resolution)? (10 - 100 ms would be a goal)
- 2. Is there a better way to do this
There's quite a bit more code, but I will include the important bits relevant to this message below. Also of note, the TPeriod is vastly more important than the XPeriod. If there is a way to prioritize it above everything else.
Code:
volatile unsigned long presCount = 0;
volatile unsigned long tempCount = 0;
double xPeriod, TPeriod;
unsigned long lastMicros;
//Interrupt functions called when associated DI goes high
void pulse() {
tempCount = tempCount + 1;
}
void pulse2() {
presCount = presCount + 1;
if ( presCount > U16FromRegMap(134) ) { //This is a settable variable, but ~33000 for my case
double deltaMicros = (micros() - lastMicros);
//Get average period
xPeriod = deltaMicros / tempCount;
TPeriod = deltaMicros / presCount;
presCount = 0;
tempCount = 0;
lastMicros = micros();
}
}
void setup()
{
//Set the frequency counter pins
pinMode(3, INPUT_PULLDOWN);
attachInterrupt(digitalPinToInterrupt(3), pulse, RISING);
pinMode(9, INPUT_PULLDOWN);
attachInterrupt(digitalPinToInterrupt(9), pulse2, RISING);
lastMicros = micros();
}
void loop()
{
//Nothing really here relevant to the period calculations
delay(100);
}