# Measuring frequency of sine wave

Hi guys! I need to measure frequency of sine wave. I try to applyzero-crossing method. I have an interrupt triggered every 250microsec to control if analog read equals middle point of the signal(zerocrossing), also an overflow interrupt to save elapsed time from first middle point of wave to second one. However it does not run as it should be. Please help me. Many thanks.

``````#include <avr/interrupt.h>
#include <avr/io.h>
float sensorValue1;
float maxValue1 = 0;
float rms1=0;
float minValue1 = 1000;

float sensorValue2;
float maxValue2 = 0;
float rms2=0;
float minValue2 = 1000;

float sensordig1;
float mid1;

unsigned int second = 0;
unsigned int count = 0;

ISR(TIMER2_COMPA_vect){
if(sensorValue1==mid1){

Serial.print("s:");
Serial.println(second);
Serial.print("m:");
Serial.println(count);
TCNT2=0;

}

}

ISR(TIMER2_OVF_vect){
count++;               //Increments the interrupt counter
if(count ==4000){//one sec. count 0.00025 sec=250micro
second++;
count = 0;           //Resets the interrupt counter
}
TIFR2 = 0x00;//clear overflow flag
//TCNT2=0;
}

void setup() {

cli();//stop interrupts
TCCR2A=0;
TCCR2B=0;
TCNT2=0;
OCR2A=62;
TCCR2A |=(1<<WGM21);
TCCR2B |=(1<<CS21 | 1<<CS20);
//TIMSK2 |=(1<<OCIE2A);
TIFR1 = (1 << OCIE1A) | (1 << OCIE1B);    // Clear Interrupt flag Match A and B
TIMSK1 = (1 << OCIE1A) | (1 << OCIE1B);
sei();
Serial.begin(9600);
}

void loop() {
//MAX1 VALUE
if (sensorValue1 >= maxValue1) {
maxValue1 = sensorValue1;
}
if (sensorValue1 <= maxValue1) {
maxadc1= maxValue1* (5.2 / 1023.0);
}

//MIN1 VALUE
while(sensorValue1<minValue1){
minValue1= sensorValue1;

}
minadc1=minValue1* (5.2 / 1023.0);

mid1 = (maxValue1+minValue1)/ 2;
sensordig1=sensorValue1* (5.2 / 1023.0);

//MAX2 VALUE
if (sensorValue2 > maxValue2) {
maxValue2 = sensorValue2;
}
if (sensorValue2 <= maxValue2) {
maxadc2= maxValue2* (5.2 / 1023.0);
}
//MIN2 DEĞER
while(sensorValue2<minValue2){
minValue2= sensorValue2;

}
minadc2=minValue2* (5.2 / 1023.0);

Serial.print("first max value: ");
Serial.print("first min value: ");
Serial.print("first rms value: ");
Serial.println(rms1);

}
``````

What is the problem? Describe how it does run.

Scale the input signal to the requirements of the processing system (UNO).
Use a peaking circuit to convert one lobe of the sine into a pulse.
count the pulses over a gate time.
scale the output to a usefull range.
display the results.

You are trying to use the Serial interface from an ISR - you can't do this since the
Serial interface is interrupt driven and you are already in an ISR. It would also
take far far too long to complete if it did work (ISR should do at little as possible and
exit).

measurement of sine wave can be done by loading the code below and connecting the frequency source having amplitude below 5v.

i also connect the lcd to get out put on screen. if you do not need you can skip that the out put frequency you get is in integer.

#include <LiquidCrystal.h>
unsigned long input=12;

unsigned long high_time;
unsigned long low_time;
float time_period;
int frequency;
LiquidCrystal lcd(4,5,6,7,8,9);
void setup()
{
Serial.begin(9600);
pinMode(input,INPUT);
lcd.begin(16, 2);
}
void loop()
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print(“Frequency Meter”);

high_time=pulseIn(input,HIGH);
low_time=pulseIn(input,LOW);

time_period=high_time+low_time;
time_period=time_period/1000;
frequency=1000/time_period;

lcd.setCursor(0,1);
lcd.print(frequency);
lcd.print(" Hz");
Serial.print(frequency);
delay(500);
}

Hi,

What is the frequency range you are trying to measure.

Can you please post a copy of your input circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Tom.... 