Changing/Fluctuating Analog Input

I need help getting a stabile reading from an analog input using a Nano 3.0. I am trying to measure a regulated 3.3v power source, but the reading changes depending on whether or not the USB cable is connected (even though the power source does not change). I have tried using the Nano’s own 3.3v power-out supply as a reference, but it changes, too, when the USB cable is connected!

Pins sensorValue2 and sensorValue3 are both 3.3v from different sources.

The code I am using is as follows:

#include <LiquidCrystal.h>

const int analogInPin1 = A1;
const int analogInPin2 = A3;
const int analogInPin3 = A2;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

int sensorValue1 = 0;
int sensorValue2 = 0;
int sensorValue3 = 0;

void setup() {
  lcd.begin(16, 2);
  lcd.print("VCC1  V3.3  VCC2");
void loop() {
  sensorValue1 = analogRead(analogInPin1);            
  sensorValue2 = analogRead(analogInPin2);            
  sensorValue3 = analogRead(analogInPin3);            
  lcd.setCursor(0, 1);
  lcd.setCursor(6, 1);
  lcd.setCursor(12, 1);

What is the VIN voltage when you disconnect the USB?

Regulated 5v, but I have tried changing that, too, between 3.3v and up to doesn't seem to affect it (same result, in other words).

The most likely cause for change of ADC values is a different voltage feeding the chip.
This sketch reads the ADC value while compensating for VIN courtesy of retrolefty. Modified slightly by me.
Hopefully it works on the nano. Can be modified to print to LCD instead of serial.

// Function created to obtain chip's actual Vcc voltage value, using internal bandgap reference
// This demonstrates ability to read processors Vcc voltage and the ability to maintain A/D calibration with changing Vcc
// Now works for 168/328 and mega boards.
// Thanks to "Coding Badly" for direct register control for A/D mux
// 1/9/10 "retrolefty"
int battVolts;   // made global for wider avaliblity throughout a sketch if needed, example a low voltage alarm, etc

void setup(void)
/*     Serial.print("volts X 100");
     Serial.println( "\r\n\r\n" );*/
void loop(void)
     battVolts=getBandgap();  //Determins what actual Vcc is, (X 100), based on known bandgap voltage
     Serial.print("Battery Vcc volts =  ");
     Serial.print("Analog pin 0 voltage = ");
     Serial.println((float)map(analogRead(0), 0, 1023, 0, battVolts)/100);

int getBandgap(void) // Returns actual value of Vcc (x 100)
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
     // For mega boards
     const long InternalReferenceVoltage = 1115L;  // Adjust this value to your boards specific internal BG voltage x1000
        // REFS1 REFS0          --> 0 1, AVcc internal ref. -Selects AVcc reference
        // MUX4 MUX3 MUX2 MUX1 MUX0  --> 11110 1.1V (VBG)         -Selects channel 30, bandgap voltage, to measure
     ADMUX = (0<<REFS1) | (1<<REFS0) | (0<<ADLAR)| (0<<MUX5) | (1<<MUX4) | (1<<MUX3) | (1<<MUX2) | (1<<MUX1) | (0<<MUX0);
     // For 168/328 boards
     const long InternalReferenceVoltage = 1056L;  // Adjust this value to your boards specific internal BG voltage x1000
        // REFS1 REFS0          --> 0 1, AVcc internal ref. -Selects AVcc external reference
        // MUX3 MUX2 MUX1 MUX0  --> 1110 1.1V (VBG)         -Selects channel 14, bandgap voltage, to measure
     ADMUX = (0<<REFS1) | (1<<REFS0) | (0<<ADLAR) | (1<<MUX3) | (1<<MUX2) | (1<<MUX1) | (0<<MUX0);
     delay(50);  // Let mux settle a little to get a more stable A/D conversion
        // Start a conversion  
     ADCSRA |= _BV( ADSC );
        // Wait for it to complete
     while( ( (ADCSRA & (1<<ADSC)) != 0 ) );
        // Scale the value
     int results = (((InternalReferenceVoltage * 1023L) / ADC) + 5L) / 10L; // calculates for straight line value 
     return results;

but the reading changes depending on whether or not the USB cable is connected (even though the power source does not change).

What is Vin? If Vin is not at least 7.5V or higher then USB will always be selected.

What does "changes" mean. What actual ADC values are you reading?

That code didn't change much: Analog reading is now 464 with USB (with AND without external 5V power), and 399 on external power. Using the same math I utilized with the Nano's known 3.3V, I get a reading of 2.08V with USB, and 1.78V without. (The original program gave analog readings of 822/external 5V only, 722/USB AND external 5V supplied, and 595/USB only.)

When USB IS hooked up, enabling/disabling external power makes no difference in measurement. MY regulated 5V measures the same as the Nano's 5V output either way. It is only 3.3V that I am having trouble with.

Since the external 3.3V source I am measuring doesn't change, why is the analog reading fluctuating so much?? Is the Nano's power regulator that bad?


I just hooked it back up to 9V for grins, and I'm getting a different reading from the Nano's 3.3V out (even though it's not really changing). I'm going to re-program from scratch using the Nano's 3.3V AND 5V for reference - wish me luck.

Also, thank you for your patience; although I have been programming since I was 9 years old (back in the "old days" of the TRS-80 Model I), this is my first foray into the physical programming world. Tons of fun! :slight_smile: Arduino is awesome!

I have tried everything from 5-12V with the same result.

The analog read changes, not the voltage I am reading. ADC?