I am using the above linked code to measure frequency of a square wave input to one of the digital pins of an Arduino Uno. The program works perfectly to detect accurate frequencies of square wave signals generated using a function generator. The issue comes when I use my hardware generated square wave and the same program starts giving infinite frequency values. For reference, both square wave signals look identical on an oscilloscope.
Would anybody have any thoughts on what I could be missing here?
You are right. I had to do a global initialization for startTime and stopTime to run the code. I also added pinMode(7,INPUT) to the setup() but still keep seeing 62500 as the frequency which makes me think the time period it's recording is 0. I am using a 0.79Hz square wave as an input.
I noticed that it starts giving the right output for higher frequencies (~1kHz) but not able to do so for lower frequencies that I need it to work for (0.5Hz-1Hz).
unsigned long startTime;
unsigned long stopTime;
float time_period;
float frequency;
void setup() {
Serial.begin(9600);
startTime = 0;
stopTime = 0;
pinMode(2, INPUT);
}
void loop() {
// Serial.println(digitalRead(2));
while (digitalRead(2)) { //wait for low on pin 2
}
while (!digitalRead(2)) { //wait for high on pin 2
}
startTime = micros(); //high detected, set start time
while (digitalRead(2)) { //wait for low on pin 2
}
stopTime = micros(); //low detected, set stop time
time_period = 2* (stopTime - startTime);
frequency = 1000000/time_period;
Serial.println(frequency);
}
Don't you mean 16? 62500 Hz is a 16 microsecond cycle time.
0.79 Hz should be a duration of 1,265,822 microseconds.
The "(Warning: untested and incomplete armchair code fragment. Worth what you paid for it...)" that you quoted above only measures the high part of the wave. If it's a square wave then you would just need to divide the frequency by 2. If it is a pulse wave you will be off by some unknown factor.
Here is the code with some deficiencies corrected:
unsigned long startTime = 0;
unsigned long stopTime = 0;
void setup()
{
Serial.begin(115200);
delay(200);
pinMode(7, INPUT);
Serial.println();
Serial.println("Starting");
}
void loop()
{
while (digitalRead(7) != LOW) //wait for low on pin 7
{
}
while (digitalRead(7) == LOW) //wait for high on pin 7
{
}
startTime = micros(); //high detected, set start time
while (digitalRead(7) != LOW) //wait for low on pin 7
{
}
while (digitalRead(7) == LOW) // wait for end of low on pin 7
{
}
stopTime = micros(); // low detected, set stop time
unsigned long elapsedTime = stopTime - startTime;
Serial.print("Duration in microseconds: ");
Serial.println(elapsedTime);
Serial.print("Frequency in Hz: ");
Serial.println(1000000.0 / elapsedTime);
delay(3000); // Display every 3 seconds
}
Thanks, John. I just tried this code out. This also works perfectly for the 0.79Hz square wave generated using a function generator but not for the one generated using the hardware
If I increase the frequency to 1kHz, it starts working for hardware generated square wave too. I wonder if it's something related to my sampling rate that might be incorrect?