Hi all,
I want monitor battery voltage on a Nano board (VIN), Found a lot of chatter about Bandgap, so I thought I would try it out, Problem is it always returns near 5 volts.
USB power result is 5.10 volts
5.72 volt battery result is 5.10 volts
9 volt battery result is 5.44 volts
each has a little fluctuation. I am ok with that. But the big issue is obviously the Readings are not right,
Now this is a Clone board but it appears to be fine for everything else. I have tried using this code to get reading
long readVcc() {
long result; // Read 1.1V reference against AVcc
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Convert
while (bit_is_set(ADCSRA,ADSC));
result = ADCL;
result |= ADCH<<8;
result = 1126400L / result; // Back-calculate AVcc in mV
return result;
}
I have also tried this
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 = 1180L; // 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 * 1024L) / ADC) + 5L) / 10L; // calculates for straight line value
return results;
}
Here is the calling code
void loop()
{
battVolts=getBandgap(); //Determins what actual Vcc is, (X 100), based on known bandgap voltage
mySerial.print("Battery Vcc volts = ");
mySerial.println(battVolts);
mySerial.print("Analog pin 0 voltage = ");
mySerial.println(map(analogRead(0), 0, 1023, 0, battVolts)); // returns roughly 133 - 139
long myval = readVcc();
mySerial.print("Vcc2 volts = ");
mySerial.println(myval);
mySerial.println();
delay(2000);
return;
}
I have to admit, I do not play with the internals of this chip, so this is cut and past as far as the read voltage goes.
The board does have a few things plugged in.
#define pin_cmd 4
#define pin_but1 8
#define pin_rx 10
#define pin_tx 11
#define pin_led1 13
It is a 328 processor in the board.
Anybody else have this issue? Any ideas on what I am doing wrong.
Using a Voltage divider will not work for me, The final creation will be a low power device and I do not want battery life to be shortened.
Thanks in advance
Highflier