| ||
Shopping Cart Download Website |
Home | Products | Teensy | Blog | Forum |
You are here: Teensy Teensyduino Libraries FreqMeasure |
|
FreqMeasure LibraryFreqMeasure measures the elapsed time during each cycle of an input frequency. See FreqCount vs FreqMeasure below to choose the best library. FreqMeasure works well for RPM (rotations per minute) tachometer applications.
Update: FreqMeasureMulti can measure up to 8 frequencies simultaneously on Teensy 3.x, or up to 6 signals on Teensy LC.
Hardware RequirementsFreqMeasure requires the input frequency as a digital level signal on a specific pin.
If the input signal may have noise or could be a high frequency, adding a low pass filter is a good idea.
An amplifier may be needed if the input signal is a sine wave or small AC signal which can not directly drive a TTL logic level input. Basic UsageFreqMeasure.begin();Begin frequency measurement. FreqMeasure.available();Returns the number of measurements available to read, or 0 (false) if none are unread. If your program spends time on other tasks and a relatively fast waveform is being measured, several readings may be available. FreqMeasure.read();Read a measurement. An unsigned long (32 bits) containing the number of timer cycles that elapsed during one cycle of the waveform. Each measurement begins immediately after the prior one without any delay, so several measurements may be averaged together for better resolution. FreqMeasure.countToFrequency(count);Convert the 32 bit unsigned long numbers from read() to actual frequency. FreqMeasure.end();Stop frequency measurement. PWM (analogWrite) functionality may be used again. Timer CyclesNormally FreqMeasure.countToFrequency() is used to convert the raw timer cycle count numbers into actual frequency numbers. But if you wish to work with the raw timer counts, knowledge of the timer counting frequency is needed.On Teensy 4.0, 4.1, MicroMod, the timers count at the "IPG" peripheral clock, which is normally 150 MHz. This frequency can be accessed with F_BUS_ACTUAL. On Teensy 3.2, 3.5, 3.6, the timers count at the "BUS" frequency. Normally this is 60 MHz on Teensy 3.5 & 3.6, or 48 MHz or 36 MHz on Teensy 3.2. On Teensy LC, the timers count at 24 MHz. On Teensy 2.0 and Teensy++ 2.0, the timers count at the CPU frequency, 16 MHz. Example ProgramOpen from the menu: File > Examples > FreqMeasure > Serial_Output#include <FreqMeasure.h> void setup() { Serial.begin(57600); FreqMeasure.begin(); } double sum=0; int count=0; void loop() { if (FreqMeasure.available()) { // average several reading together sum = sum + FreqMeasure.read(); count = count + 1; if (count > 30) { float frequency = FreqMeasure.countToFrequency(sum / count); Serial.println(frequency); sum = 0; count = 0; } } }
Zero HandlingBecause FreqMeasure works on a per-cycle time frame, it is impossible to directly measure zero frequency. When displaying frequency, such as the LCD_Output example, if the input frequency stops, the most recent measurement will remain on the display.To detect zero, a timeout must be implemented. On simple approach would be to record the millis() time when FreqMeasure.available() returns true. When it returns false, check if too much time as elapsed and update the output to show zero. CPU RequirementsAt the end of each cycle, an interrupt routine runs. The actual capture of elapsed time is done by hardware, so some interrupt latency is acceptable.At relatively low frequencies, under 1 kHz, only minimal CPU time is used. However, as the frequency increases, the interrupt demands more CPU time. A hardware low-pass filter is recommended if the input frequency could possibly be much higher than several kHz. If interrupts are disabled for more than 1 cycle of the waveform, the measurement can span 2 or more cycles. Libraries which disable interrupts for long times (eg, NewSoftSerial) can be problematic. FreqCount vs FreqMeasureFreqCount: best for 1 kHz to 8 MHz (up to 65 MHz with Teensy 3.0 & 3.1)FreqMeasure: best for 0.1 Hz to 1 kHz
FreqCount measures the number of cycles that occur during a fixed "gate interval" time. This works well for relatively high frequencies, because many cycles are likely to be counted during gate interval. At lower frequencies, very few cycles are counted, giving limited resolution. FreqMeasure measures the elapsed time during a single cycle. This works well for relatively low frequencies, because a substantial time elapses. At higher frequencies, the short time can only be measured at the processor's clock speed, which results in limited resolution. Other Arduino Compatible BoardsFreqMeasure can be used on Arduino, Sanguino and probably other boards. See the file util/capture.h for details to port to other AVR-based boards.Arduino Mega's pin 49 may be used by the SPI library, or SPI-based libraries like Ethernet or SD. You may need to edit FreqMeasure's util/capture.h to use ICP5 (pin 48) instead of ICP4. Seeeduino GPRS requires editing FreqMeasureCapture.h. This this issue report for details. Other Frequency MeasurementMartin Nawrath's FreqCounter and FreqPeriod are similar to FreqCount and FreqMeasure. I originally ported FreqCounter to Teensy, but could not get it to work reliably. It did work, but had trouble at certain frequencies, and requires a "compensation" factor for accurate results. Ultimately I wrote a FreqCount from scratch, using a thin hardware abstraction layer for easy porting to different boards, and accurate results without a compensation factor. I also used a more Arduino-like API (begin, available, read) and designed for continuously repeating measurements. I did not try to use FreqPeriod. |