Step 3: Sine Wave Frequency Detection

Picture of Sine Wave Frequency Detection
Screen shot 2012-09-30 at 8.44.07 PM copy.jpg
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.

byondo7 months ago

Hi Amanda, thank you very much for this instructable! Very useful!

I prefer this simpler code version (integrated with amp treshold), because I want to make a sound analyzer , where you whistle or sing a "oooh" note and then you have the frequency. Making a portable built with a 4 digit display and there it is a perfect gadget for any sound engineer or musician, who wants to know which frequency causes microphones feedbacks.

Does it make any sense collecting a number of measurements and make a mathematical average? as I don't need a fast process, but a slower and more solid (without "garbage" measurements); I tried some "for" cycle with a simple array, but it doesn't seem to add any precision (maybe I don't know where to put it)..

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.