Skip to main content
Arduino

Return to Question

replaced http://arduino.stackexchange.com/ with https://arduino.stackexchange.com/
Source Link
Source Link
Paul Grime
  • 211
  • 3
  • 10

Measure different Vcc using 1.1V bandgap

When I power my ATmega328P chip from 5.16V and 3.3V, there doesn't seem to be a single bandgap voltage compensation figure that works for both.

I'm using the following sketch, and I need the following InternalReferenceVoltage values to read the correct voltage from A0:

  • 1255L to correctly output 5.16V.
  • 1358L to correctly output 3.3V.

I have a couple of questions:

  • Should I be able to use a single InternalReferenceVoltage compensation value whe powering the ATmega328P from different voltages?
  • Aren't both of these values outside the specced 1.0 to 1.2 range?

The code is from, http://forum.arduino.cc/index.php?topic=56750.msg407897#msg407897, retolefty post @ Mar 28, 2011, 02:27 pm.

#include <SPI.h>
void setup()
{
 delay(5000);
 Serial.begin(115200);
}
void loop(void)
{
 // Determines what actual Vcc is, (X 100), based on known bandgap voltage
 int battVolts = readVcc1();
 Serial.print("Battery Vcc volts = ");
 Serial.println(battVolts);
 Serial.print("Analog pin 0 voltage = ");
 Serial.println(map(analogRead(0), 0, 1023, 0, battVolts));
 Serial.println();
 delay(1000);
}
// Returns actual value of Vcc (x 100)
int readVcc1()
{
 uint8_t oldADMUX = ADMUX;
 const long InternalReferenceVoltage = 1255L; // Adjust this value to your boards specific internal BG voltage x1000
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
 // For mega boards
 // 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
 // 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
 ADMUX = oldADMUX;
 return results;
}

I have read these other references to try and find a solution:

AltStyle によって変換されたページ (->オリジナル) /