PaulStoffregen / FreqMeasure

Measures the elapsed time during each cycle of an input frequency.
http://www.pjrc.com/teensy/td_libs_FreqMeasure.html
69 stars 31 forks source link

First measure is wrong #6

Open evansgl opened 8 years ago

evansgl commented 8 years ago

I noticed first reading is wrong. I use your library to measure light intensity using a TSL237 sensor. First measure is always wrong so what I do is to drop the first reading and use the second one.

Thanks

mrguen commented 6 years ago

I have the same issue. Sometimes the value is null, other times it is a little value.

PaulStoffregen commented 6 years ago

From email:

I just found the error in your FreqMeasure code that gives false results on the first measurement. It is simply that there isn't any time marker to substract. There needs to be at least two interrupts to get the first measure.

Here is a possible fix

ISR(TIMER_CAPTURE_VECTOR)
{
uint16_t capture_lsw;
uint32_t capture, period;
uint8_t i;
bool first = true; //MOD TG 03 april 2018

// get the timer capture
capture_lsw = capture_read();
// Handle the case where but capture and overflow interrupts were pending
// (eg, interrupts were disabled for a while), or where the overflow occurred
// while this ISR was starting up.  However, if we read a 16 bit number that
// is very close to overflow, then ignore any overflow since it probably
// just happened.
if (capture_overflow() && capture_lsw < 0xFF00) {
capture_overflow_reset();
capture_msw++;
}
// compute the waveform period
capture = ((uint32_t)capture_msw << 16) | capture_lsw;
period = capture - capture_previous;

// MOD TG 03 april 2018
if (capture_previous > 0) first = false;

capture_previous = capture;

// store it into the buffer
// MOD TG 03 april 2018 if the measure is valid i.e. there was already a time mark capture_previous

if (!first) {
i = buffer_head + 1;
if (i >= FREQMEASURE_BUFFER_LEN) i = 0;
if (i != buffer_tail) {
buffer_value[i] = period;
buffer_head = i;
}
}
}