0

Regardless of whatever voltage at A0, the software is always returning high (1023)

volatile unsigned char* ADmux = (unsigned char*) 0x7C;
volatile unsigned char* ADCSRa = (unsigned char*) 0x7A;
volatile unsigned char* ADCSRb = (unsigned char*) 0x7B;
volatile unsigned char* ADCh = (unsigned char*) 0x79;
volatile unsigned char* ADCl = (unsigned char*) 0x78;
int Voltage;

void adc_init()
{
  *ADmux = 0x00; // setting entire register to 0's notably setting Refs1 and refs0 to 0's meaning reference voltage is AREF
  *ADCSRa = 0b10000111; //Sets most significant bit to 1, which is the ADC enable bit, and the 3 least signifcant bits are the prescalar, which is 128

}

unsigned int adc_read( unsigned char adc_channel)
{
  *ADmux = *ADmux | 0b00000000;// set mux bits to 0 to test A0 regardless of whatever adc_channel is
  *ADCSRa = *ADCSRa | 0b01000000; // set ADSC bit high to start conversion

  while(*ADCSRa & 0b01000000);//wait until ADSC goes low, indicated conversion is complete

  return ADC; //return bits in the adc registers
}


void setup() {
   // put your setup code here, to run once:
   Serial.begin(9600);
   adc_init(); // initializes the adc
}

void loop() {
  // put your main code here, to run repeatedly:

  Voltage = adc_read(0b00000); // calls on adc_read

  Serial.print(Voltage); // prints voltage reading
  Serial.write("\n");

}

And here is a schematic of the circuit:

schematic

simulate this circuit – Schematic created using CircuitLab

I have combed over chapter 26 of the atmega2560 document and the descriptions of each register, but I am at a loss. Why is the contents of the adc registers always filled with 1's regardless of the voltage at a0?

  • what do you read if you remove R1? – jsotola Nov 15 at 5:39
  • @jsotola it still reads 1023 – ClockwerkSC Nov 15 at 5:41
  • What IDE do you use, if any? Make sure MUX5, at ADCSRB:3 is set to 0, as well as ADTS2:0 at ADCSRB 2:0 to enable free running mode. – towe Nov 15 at 7:20
  • I got the program to work by setting refs0 to 1. So this means that the reference voltage switched from AREF to AVCC. Does anyone know why this small change makes it work? Isn't AREF 5V by default? – ClockwerkSC Nov 15 at 7:30
  • @towe I'm using the default Arduino IDE. – ClockwerkSC Nov 15 at 7:31
3

First, let me give a couple of suggestions on the programming style. There is no point in defining your own variables for accessing the hardware registers: the avr-libc does that for you, you just have to #include <avr/io.h>. Actually, you don't have to #include anything: the Arduino IDE automatically #includes Arduino.h, which in turn #includes avr/io.h.

Next, the same avr-libc also defines macros for the bit names, so you don't have to explicitly write binary numbers in your own code (which is error-prone). And a couple of utility macros that you can use to make the code a little bit more readable. For example:

void adc_init()
{
    ADMUX  = _BV(REFS0);  // ADC reference = AVCC
    ADCSRA = _BV(ADEN)    // enable the ADC
           | _BV(ADPS2)   // set prescaler to 128
           | _BV(ADPS1)   // ditto
           | _BV(ADPS0);  // ditto
}

unsigned int adc_read(unsigned char adc_channel)
{
    ADMUX   = _BV(REFS0) | (adc_channel & 7);  // select channel
    ADCSRA |= _BV(ADSC);  // start conversion

    // Conversion is complete when ADSC goes low.
    loop_until_bit_is_clear(ADCSRA, ADSC);

    return ADC;  // return the adc data register
}

Now, let's answer your actual question. When you set both REFS0 and REFS1 to 0, the voltage reference is stated to be “AREF, internal V REF turned off”. The implication is that you are supposed to bring your own voltage reference and connect it to the AREF pin. Otherwise AREF is left as a floating input. This is illustrated in the schematic of the ADC. Here is the relevant part:

AREF input MOSFET

As you see here, REFS0 is used to connect AREF to one of the other possible references: either AVCC or the internal bandgap. If REFS0 is zero, the transistor depicted above is off, and AREF is left floating.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.