Battery voltage checking

// 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(38400);
    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(battVolts);
    Serial.print("Analog pin 0 voltage = ");
    Serial.println(map(analogRead(0), 0, 1023, 0, battVolts));
    Serial.println();
    delay(1000);
}

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;
    
}

Could you please format your code as following:

In which you replace:


// This #include statement was automatically added by the Spark IDE.
# include "WebServer.h"

By your code.
This formats your code in a way that makes it infinitely more readable, and would be greatly appreciated!

The code is for arduino not for spark core device

took it from here
http://forum.arduino.cc/index.php/topic,92074.0.html

I’m aware of that, but by putting (any) code between those “```cpp” tags, it formats the code, so it’s a lot easier to be read on the forum. If you could edit your original post and try it, I’m sure you’ll agree on the difference :wink:
(wrong signs, use the ones in the picture above! They should be the ` signs)

It won’t change anything in the code, but makes is so much easier to read, and therefor debug/port/edit, for those trying to read it. Thanks in advance!

Got it . fixed .
Still the idea is i dont want to debug the code because this wont work on spark … i just uploaded it as exemple so you understand what kind of function i needed.
one that can read board voltage.

Thanks

Hi @Gentmat

I fixed your code posting above in the way that @Moors7 suggested (thanks!). You can go back and edit posts for this sort of thing–click on the little pencil.

Unfortunately the STM032 chip on the Spark core does not have a bandgap reference so this type of self-measurement is not easy on the Spark core. You could add an external band-gap reference like the LM185/285/385 series and use the internal ADC or you could add a battery voltage IC like these:

or

4 Likes