Maker Pro
Maker Pro

Wrong values from ADC Arduino - frequnecy meter

Hi there!

I'm building a frequency meter using as input a sine wave between 0.05V-0.55V (from a peak detector) and a frequency range between 5Khz-10Khz. I tried to change the sampling rate (I need at least 20Khz) to 76Khz (setting 16 prescaler from ADCSRA register), but the resulting data from ADC it's a constant (=255). I didn't find anything which could cause this constant output.

Having a higher sampling rate means that I could find more precisely the max amplitudes and then I could measure the time period between two max amplitudes resulting the frequency.

Any help or tips would be much appreciated! Thanks in advance!

The output: https://www.dropbox.com/s/jyguxpz8k18zsco/output.png?dl=0

The input: https://www.dropbox.com/s/94ou221vn89ndj0/sine_wave.jpg?dl=0

Code:
const int MAX_RESULTS = 256;
volatile int results [MAX_RESULTS];
volatile int resultNumber;

void setup() {
  ADMUX = 0x20; // set A0 analog input
  ADCSRA = 0xEC;// set 16 prescaler, enable ADC and interrupts and start ADC measurements
  Serial.begin(115200);
}

  ISR (ADC_vect)
{
   results[resultNumber++] = ADCH;
   if(resultNumber == MAX_RESULTS)
   {
     ADCSRA = 0;  // turn off ADC
   }

}

void loop () {
  while (resultNumber < MAX_RESULTS)
   { }

 for (int i = 0; i < MAX_RESULTS; i++)
  {
   Serial.println (results[i]);
  }
  //start a new conversion
  resultNumber = 0;
  ADCSRA = 0xEC;
}
 

Harald Kapp

Moderator
Moderator
Not this..??
No, not this.
This loop waits until resultNumber exceeds the max. number of entries in the array (volatile int results [MAX_RESULTS];)
resultNumber is incremented within the ADC interrupt routine (results[resultNumber++] = ADCH;)

Otherwise @RazvanT19 would never get to the point where the array contents are printed, but he obviously does.
 

bertus

Moderator
Hello,

Looking at the wave, the sampling rate is to low.
Some signals have a clear peak, but some have two points at a lower value.
The real peak will be between the two points.

Bertus
 

Harald Kapp

Moderator
Moderator
how to calculate the frequency
Select an arbitrary threshold, e.g. at the value 10 (the equivalent value in hex from the ADC).
Measure the interval (time) T between two rising edges crossing that threshold (or falling edges, which one doesn't matter). Since you know the sample rate you get the time by T = (number of samples between edges)/sampling frequency.
Calculate f = 1/T
To improve accuracy, take more than one interval, e.g. take 10 intervals and divide multiply the calculated frequency by that number (10 in the example). This will average out uncertainties of the measurement.
 
Last edited:
Top