# Measure square wave frequency

Hello,

I use the following code:

``````// period of pulse accumulation and serial output, milliseconds
#define MainPeriod 10
long previousMillis = 0; // will store last time of the cycle end
volatile unsigned long duration=0; // accumulates pulse width
volatile unsigned int pulsecount=0;
volatile unsigned long previousMicros=0;

void setup()
{
Serial.begin(9600);
attachInterrupt(6, myinthandler, RISING);
}

void loop()
{
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= MainPeriod)
{
previousMillis = currentMillis;
// need to bufferize to avoid glitches
unsigned long _duration = duration;
unsigned long _pulsecount = pulsecount;
duration = 0; // clear counters
pulsecount = 0;
float Freq = 1e6 / float(_duration);
Freq *= _pulsecount; // calculate F
// output time and frequency data to RS232
Serial.print(currentMillis);
Serial.print(" "); // separator!
Serial.print(Freq);
Serial.print(" ");
Serial.print(_pulsecount);
Serial.print(" ");
Serial.println(_duration);
}
}

void myinthandler() // interrupt handler
{
unsigned long currentMicros = micros();
duration += currentMicros - previousMicros;
previousMicros = currentMicros;
pulsecount++;
}
``````

to measure square wave frequency.

The problem is that it can measure 1.5kHz accurately but I need to measure even lower frequency.

What can I do to fix this? Thanks.

ord6: The problem is that it can measure 1.5kHz accurately but I need to measure even lower frequency.

What lower frequency are you trying to measure and is what way is the current sketch giving the wrong answer?

I believe the reason your code has problems measuring slower frequencies is because you call micros() within an ISR. Arduino's API details that micros() relies on interrupts to work and therefore cannot be called within an ISR or it will begin to behave erratically after 1-2ms. A worst case scenario of 1ms means that the lowest frequency that can be reliably measured is 1 khz with frequencies no lower than 500hz ever yielding a correct measurement.

https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/