Step 3: Sine Wave Frequency Detection

Next I measured the period of an incoming sine wave, calculated the frequency, and printed the frequency.  To do this I set up a timer in the ADC interrupt that increments each time the interrupt executes (a rate of 38462Hz).  Each time the incoming signal crosses 2.5V with a rising slope I sent the current value of the timer to a variable called "period" and reset the timer to 0.  That code is reproduced below (all takes place within the ADC interrupt).

  prevData = newData;//store previous value
  newData = ADCH;//get value from A0
  if (prevData < 127 && newData >= 127){//if increasing and crossing midpoint
    period = timer;//get period from current timer value
    timer = 0;//reset timer

 timer++;//increment timer

Then in the main loop() function, I calculated the frequency by dividing the timer rate by the period.  I used Serial.print to print these results in the Arduino serial monitor.

  frequency = 38462/period;//timer rate/period
  //print results
  Serial.println(" hz");

Fig 1 shows the signal coming into A0.  The start and end of one cycle measured by timer is indicated by the image note.  Fig 2 shows the output from the serial monitor (command/ctrl+shift+m).  This technique works great for sine waves, but when wave become more complicated (and cross 2.5V more than twice in one cycle) this technique breaks down.

Ketan_Sharma7 months ago

Hi Amanda!

I was making a tengu clone using Arduino and because I wanted it to react to different frequencies in different manner, I tried to use your code for frequency detection, to detect the frequency of square wave output of comparator (which is being fed by an amplified sound wave), however when I tested it, the Serial Monitor says nothing but "inf hz", can you please tell me as to where am I going wrong? I am using an electret microphone and LM358 dual op amp IC for amplification and as a comparator.