Go Down

Topic: Measurement not acquired by ADC @8MHz. (Read 3528 times) previous topic - next topic


I'm trying to get a measurement from my ADC on an Arduino Uno rev3 using different prescaling factors. I have connected a pot at A0 to be able to modify the voltage. When the measurement is higher than 300, a pulse is output at pin 6, otherwise a constant value is output. Here is my source code:

Code: [Select]

#include <Arduino.h>
#include <avr/io.h>
#include <avr/interrupt.h>

#define _FREE_RUNNING_MODE 100

#define mode _FREE_RUNNING_MODE

#define prescalingFactor 2

int main(void)

  DDRC &= ~(1<<DDC0); // Pin A0 as Input
  DDRD |=  (1<<PIND7);//Pin 6 on arduino as output
  if (prescalingFactor==16){
    ADCSRA |= 1<<ADPS2;
  else if (prescalingFactor==2){
    ADCSRA |= 1<<ADPS0;
  else if (prescalingFactor==4){
    ADCSRA |= 1<<ADPS1;
  else {
    //default to 128
    ADCSRA |= 1<<ADPS2 | 1<<ADPS1 | 1<<ADPS0;
  ADMUX |= (1<<REFS0) | (1<<REFS1); // Internal 1.1V reference
  if (mode==_FREE_RUNNING_MODE){
    ADCSRB &= ~((1<<ADTS2)|(1<<ADTS1)|(1<<ADTS0));//ADC in free-running mode
    ADCSRA |= (1<<ADATE);//Signal source, in this case is the free-running
  ADCSRA |= 1<<ADIE; // Enable the interrupt
  ADCSRA |= 1<<ADEN;// Enable the ADR
  sei();// Enable Interrupts (Global)

  ADCSRA |= 1<<ADSC;//Start first conversion (necessary always) 

  uint8_t lowPart = ADCL;
  uint16_t myMeasurement = ADCH<<8 | lowPart;
    ADCSRA |= 1<<ADSC;
  }//trigger new conversion
  if (myMeasurement>=300){
    PIND ^= 1<<PIND6;//flip pin 6 on arduino

For debugging I use Serial.println(myMeasurement); inside the while(1){} loop. Everything works as expected for every prescaling factor greater than 2 (4,8,...,128). But, when I set the prescaler's division factor to 2 (i.e. 8MHz):

  • I constantly get a pulse at the output, meaning that it seems that myMeasurement>300 holds true regardless of the position of the potentiometer.

  • If I use Serial.println for debugging, I get the measurement 1023 always.

Any ideas? Why isn't my measurement updated on runtime?


Read the atmega328p datasheet. Here is an excerpt:

By default, the successive approximation circuitry requires an input clock frequency between 50kHz and 200kHz to get maximum resolution. If a lower resolution than 10 bits is needed, the input clock frequency to the ADC can be higher than 200kHz to get a higher sample rate.

See also section 29.8 to find the maximum ADC clock frequency.
Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.


Any ideas? Why isn't my measurement updated on runtime?

The part of the datasheet that explains how to set the prescalar also discusses the limits of the ADC...
No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

Go Up