Calibrating atmega328 adc

arduinoatmega

The following circuit is what am using to make a volt meter using an arduino for my psu. It's a 30v psu hence I'll be measuring up to 30v. I don't know why I keep getting random values on the ADC. One minute it's 245 next it's 1024 then it's 0 for some time. Just jumps all over the place. I was told I would only need to supply 1mA to the analogue pin.

Avcc and vcc all decoupled to gnd using 0.1uf non polarised cap.

Here's the sketch code I am using to read the value of the adc

 ![void setup()
    {
      // begin the serial communication
      Serial.begin(19200);
    }

    // variable to hold the analog input value
    int analogValue = 0; 

    void loop()
    {
      // read the analog input on pin 0
      analogValue = analogRead(0);   

      // print as an ASCII-encoded decimal
      Serial.print(analogValue);

      // print a terminal newline character so the AVR Voltmeter
      // will know that it has received the full string
      Serial.print('\n');

      // delay 1 second before the next reading:
      delay(1000);
    }][1]

enter image description here

Best Answer

A few thoughts:

I'm assuming the PSU is DC within the range of 0V - 30V. (i.e no negative or AC voltages)

I don't know much about Arduinos, but do you have to set the pin to an analogue input? (e.g. like you would have to an a PIC) I'm thinking maybe the analogRead routine takes care of it. Also is the ADC reference voltage set correctly? (I notice there is a Aref pin floating on your schematic)

EDIT - Aref pin:

Atmel say:

The reference voltage for the ADC (VREF ) indicates the conversion range for the ADC. Single ended channels that exceed VREF will result in codes close to 0x3FF. VREF can be selected as either AVCC , internal 2.56V reference, or external AREF pin. AVCC is connected to the ADC through a passive switch. The internal 2.56V reference is generated from the internal bandgap reference (VBG) through an internal amplifier. In either case, the external AREF pin is directly connected to the ADC, and the reference voltage can be made more immune to noise by connecting a capacitor between the AREF pin and ground. VREF can also be measured at the AREF pin with a high impedant voltmeter. Note that VREF is a high impedant source, and only a capacitive load should be connected in a system. If the user has a fixed voltage source connected to the AREF pin, the user may not use the other reference voltage options in the application, as they will be shorted to the external voltage. If no external voltage is applied to the AREF pin, the user may switch between AVCC and 2.56V as reference selection. The first ADC conversion result after switching reference voltage source may be inaccurate, and the user is advised to discard this result.

So if the external reference is selected you need to apply a voltage to it. From your comment below it looks like this may be the case. Try connecting it to AVcc (or whatever you want the top of the ADC range to be)
You can optionally add a 100nF cap to ground to reduce noise if necessary also.

Is your 5V supply stable? Have you got bypass caps present? (mentioned but not acutally shown on schematic)

Is your PSU sharing ground with the Arduino? If not this could cause the issues you are seeing.