What causes FreqMeasure.available() to be unavailable?

turbosupramk3

New member
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.

I am working on a tachometer project. I'm reading anywhere between 50hz and 2000hz using FreqMeasure. As an example, when I am reading 80hz with the sketch below I see the output at the bottom at the bottom of this post, where I get "FreqMeasure NOT available" and engineRpm is 0. However if I were to remove the delay for the Serial.println if statement and let it write as fast as it can, I will get a value for engineRpm. What is causing this? I'm using a Mega 2560.

Code:
#include <FreqMeasure.h>
unsigned long serialLastWriteTestTimeStamp;
unsigned long currentTimeStamp;
#pragma region rpm
    unsigned long lastRpmUpdateTime;
    double sum = 0;
    int count = 0;
    int lastRpmUpdateTimeOut = 5000; // equates to zero rpm if more than two seconds elapse without a frequency
    bool engineRunning = false;
    int engineRpm = 0;
    int getRpm()
    {
        //Serial.println("Inside of getRpm()");
        int rpmHz = 0;
        int rpm = 0;
        if (FreqMeasure.available())
        {
            sum = sum + FreqMeasure.read();
            count = count + 1;
            if (count > 10)  // when set to 100, at 400rpm, the update was too slow for the timeout period
            {
                rpmHz = FreqMeasure.countToFrequency(sum / count);
                sum = 0;
                count = 0;
                lastRpmUpdateTime = (millis() + lastRpmUpdateTimeOut);
                rpm = (rpmHz * 5);
                return rpm;
            }       
        }
        else
        {
            Serial.print(" ** FreqMeasure NOT available, count is: "); Serial.println(count); // USE THIS FOR TROUBLESHOOTING
            lastRpmUpdateTime = 0;
            return rpm;
        }
    }
#pragma endregion rpm
void setup()
{
    Serial.begin(9600);
    while (!Serial)
    {
      ; // Wait for serial to connect
    }
    delay(1000);
    Serial.println("");
    Serial.println("");
    Serial.println("    ***** Start *****    ");
    Serial.println("");   
    serialLastWriteTestTimeStamp = millis();

    // engine rpm
    FreqMeasure.begin();
    lastRpmUpdateTime = 0;
    engineRpm = 0;
}
void loop()
{
    currentTimeStamp = millis();
    engineRpm = getRpm();
    if ((currentTimeStamp - serialLastWriteTestTimeStamp) > 3000) // if I remove this
    {
        Serial.print("loop()"); Serial.print("\tengineRpm: "); Serial.println(engineRpm);
        serialLastWriteTestTimeStamp = millis();
    }
}


09:18:18.157 -> ***** Start *****
09:18:18.191 ->
09:18:18.191 -> ** FreqMeasure NOT available, count is: 0
09:18:18.271 -> ** FreqMeasure NOT available, count is: 1
09:18:18.301 -> ** FreqMeasure NOT available, count is: 5
09:18:18.333 -> ** FreqMeasure NOT available, count is: 9
09:18:18.366 -> ** FreqMeasure NOT available, count is: 2
09:18:18.435 -> ** FreqMeasure NOT available, count is: 5
09:18:18.469 -> ** FreqMeasure NOT available, count is: 9
....
09:18:21.203 -> ** FreqMeasure NOT available, count is: 5
09:18:21.269 -> loop() engineRpm: 0
09:18:21.269 -> ** FreqMeasure NOT available, count is: 10
09:18:21.335 -> ** FreqMeasure NOT available, count is: 3
 
Last edited:
I'm still experiencing this. I've noticed that when I call the function with freqMeasure from loop {} it constantly tells me it isn't available, however if I call the freqmeasure function from another function, it works.

What determines freqmeasure being available or not? Does the check need to be throttled for lower rpms? I added the below code and it's either eliminated or masked the freqmeasure.notavailable errors

Code:
        if ((currentTimeStamp - getRPMTimeStamp) > 250)
        {
            //sendBluetoothData();
            rpm = getRpm();
            getRPMTimeStamp = millis();
        }
 
Last edited:
In your loop(), you are calling getRpm() over and over and over with no delay between calls. On most of these calls, there will be no new data, so your getRpm() will return 0. The ONLY time your getRpm() function will return a non-zero value is on the calls when 10 periods have been accumulated. However, immediately after that call, your loop() will call getRpm() again, which will return 0, and therefore your program will almost certainly print genRpm = 0.

Start from the FreqMeasure example shown below and you will see the difference.
Code:
#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;
    }
  }
}
 
Back
Top