arduino program to measure time interval between two peaks

Hai friends,

I am working on PPG so as a part of it I need to find the interval between the sinusoidal waveform.
I have been trying to find the time intervals between peaks of sinusoidal wave and the code is provided below, when I run the code it shows the value as 4294925424. Someone please sort the mistake in my code!!!

testedarduinocodeforppg.ino (1.03 KB)

int count = 0; Should be unsigned, maybe even unsigned long .

Hello Larry,

I have changed the count to unsigned and even unsigned long but it shows the same (2^32)-1 value.

Prior I wish to know whether my program logic correct.

Thank you Larry,

Is the sine wave offset so it stays between 0 and 5 volts? .

To Larry:

Yes I provided the offset and it stays between 0 to 5v

• Put some in comments so we can following your thinking.
• Press CTRL T to format your code.
• To get help, you must show us your complete sketch. Attach your code using the </> icon on the left side of the posting menu.

EDIT:
What is the frequency range?
You know this would be so much simpler if you squared the sine wave off and did this digitally

else if (now == prev)
this may never happen or take a very long time.
.

Larry I didn't get you so I have posted the whole code, sorry if it annoys you and the frequency ranges from 0.5-5Hz.

``````int ain = A2;            //Analog pin to read signals
int now = 0;            //checks current status of analog pin 2
int prev= 0;            //checks previous state
unsigned long count = 0;

unsigned long firstpulse = 0;
unsigned long totaltime = 0;
unsigned long lastpulse = 0;

void setup() {
// put your setup code here, to run once:
pinMode(ain,INPUT);
Serial.begin(115200);
}

void loop() {
// put your main code here, to run repeatedly:
delay(100);
if(now!=prev)
{
if( now >= prev)
{
prev = now;
Serial.println("Current value is greater than previous value");
}

else
{
if(count == 0)
{
firstpulse = millis();
count += 1;
}

else if(count >= 1)
{
count += 1;
lastpulse = millis();
}
}
}
else if (now == prev)
{
Serial.println(lastpulse - firstpulse);
Serial.print("----->Count:");
Serial.print(count);
Serial.println("--------------");
firstpulse = lastpulse;
lastpulse = 0;
count = 0;
}
}
``````

Is there a reason why you are doing the calculation using an analog input. You could square the waveform and do the calculation on a digital input. Which is easier.

//have we reached a maximum level? if( now >= prev) {

For two analog readings to be the same, may take a very long time as there is input noise, time delays in your program and input fluctuations. (you may miss several/numerous cycles til you reach the same levels)

What are you thinking is happening here? else if (now == prev)

Time

This isn’t what you want but might give you some ideas:

``````int analogInput = A0;
int thisReading = 0;

byte hysteresis = 10;
byte flag = 0;

unsigned long startMicros = 0;
unsigned long lastPeakMicros = 0;

void setup()
{
// put your setup code here, to run once:
Serial.begin(115200);

//Debug
pinMode(13,OUTPUT);

} //END of setup()

void loop()
{

//Debug
if(thisReading >= 512 + hysteresis)
{
digitalWrite(13,LOW); //Turn on LED
}
else if(thisReading <= 512 - hysteresis)
{
digitalWrite(13,HIGH); //Turn off LED
}
//End of debug

//have we gone above 512
if(flag == 0 && thisReading >= 512 + hysteresis)
{
flag = 1;
//record this time
startMicros = micros();
}

//have we gone below 512
if(flag == 1 && thisReading < 512 - hysteresis)
{
//Print the time it took form 512+hys to 512-hys
Serial.print("It took " );
Serial.print(micros() - startMicros);
Serial.println(" micro seconds for 1/2 cycle." );
flag = 0;
}
} //END of loop()
``````

If the sine wave signal is regular (ie not frequency modulated) and you are simply trying to determine the frequency, you can simply do this with a digital pin and an interrupt.
The interrupt service routine, which is triggered by a status change on the digital pin, simply counts the number of times it is triggered (once per zero crossing) in a unit time.
As is clear also from Larryd’s code, your use of millis() (milliseconds) to measure time intervals in a 5KHz signal is too rough to yield usable results.