Connect with us

Wrong values from ADC Arduino - frequnecy meter

Discussion in 'Microcontrollers, Programming and IoT' started by RazvanT19, Apr 21, 2020.

Scroll to continue with content
  1. RazvanT19

    RazvanT19

    3
    0
    Apr 21, 2020
    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;
    }
     
  2. Harald Kapp

    Harald Kapp Moderator Moderator

    9,887
    2,096
    Nov 17, 2011
  3. Bluejets

    Bluejets

    3,990
    824
    Oct 5, 2014
    Code:
     
    while (resultNumber < MAX_RESULTS)
       { }
          
    Not this..??
     
  4. Harald Kapp

    Harald Kapp Moderator Moderator

    9,887
    2,096
    Nov 17, 2011
    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.
     
  5. RazvanT19

    RazvanT19

    3
    0
    Apr 21, 2020
    Last edited by a moderator: Apr 21, 2020
  6. bertus

    bertus Moderator

    541
    179
    Nov 8, 2019
    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
     
  7. RazvanT19

    RazvanT19

    3
    0
    Apr 21, 2020
    I don't think that the sampling rate is too low, now it's round about 76Khz.
     
  8. Harald Kapp

    Harald Kapp Moderator Moderator

    9,887
    2,096
    Nov 17, 2011
    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: Apr 24, 2020
Ask a Question
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.
Electronics Point Logo
Continue to site
Quote of the day

-