Go Down

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

chung

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 _SIGNLE_CONVERSION_MODE 101

#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) 
  while(1){     
  }
}

ISR(ADC_vect)
{
  uint8_t lowPart = ADCL;
  uint16_t myMeasurement = ADCH<<8 | lowPart;
  if (mode==_SIGNLE_CONVERSION_MODE) {
    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?
An Arduino development board costs €20~60. A pack of 20 Zener diodes to protect your board from almost certain damage costs less than €1...

dc42

Read the atmega328p datasheet. Here is an excerpt:

Quote
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.

fungus


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