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 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.begin(1200);
/* Serial.print("volts X 100");
Serial.println( "\r\n\r\n" );*/
delay(100);
}
void loop(void)
{
battVolts=getBandgap(); //Determins what actual Vcc is, (X 100), based on known bandgap voltage
Serial.print("Battery Vcc volts = ");
Serial.println((float)battVolts/100);
Serial.print("Analog pin 0 voltage = ");
Serial.println((float)map(analogRead(0), 0, 1023, 0, battVolts)/100);
Serial.println();
delay(250);
}
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);
#else
// 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);
#endif
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;
}
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! Arduino is awesome!