Battery monitor -- By ripper121

Battery Monitor

Author :  ripper121

A simple app to measure the battery level (%) and voltage (mV).

You need to add 2 Resistors to the Backpack.

GND -[330kOhm]- A1 -[100kOhm]- VBAT

I protected the PCB with some tape, because if you touch the Voltage Divider or A1 it influences the readout.


//importe the Gamebuino library and the gb object
#define ADC_PIN A1
#define ADC_PIN_OFFSET 165 //in mV (measured ADC from µC)-(Measured voltage on Pin with Multimeter)
#define ADC_PIN_MAXVOLT 3201
#define BATTERY_FULL 4190 //in mV measured when Battery Full on VBAT
#define BATTERY_EMPTY 3000 //in mV on LiPo dont go Lower!

GND -[330kOhm]- A1 -[100kOhm]- VBAT
When the Battery Voltage is 4.200V the Voltage on A1 is 3.223V
void setup() {
// put your setup code here, to run once:
pinMode(ADC_PIN, INPUT);

int adcPinVolt = 0, batteryVolt = 0;
byte batteryPercent = 0;
void loop() {
// put your main code here, to run repeatedly:
while (!gb.update());

adcPinVolt = ((3300 / 1023) * analogRead(ADC_PIN)) + ADC_PIN_OFFSET;
batteryVolt = map(adcPinVolt, 0, ADC_PIN_MAXVOLT, 0, BATTERY_FULL);
batteryPercent = map(batteryVolt, BATTERY_EMPTY, BATTERY_FULL, 0, 100);
if (batteryPercent > 100)
batteryPercent = 100;

gb.display.drawRect(10, 20, 60, 34);
gb.display.drawLine(70, 31, 70, 42);
gb.display.drawLine(71, 32, 71, 41);
if (batteryPercent >= 60)
else if (batteryPercent >= 30 && batteryPercent <= 59)
gb.display.fillRect(11, 21, map(batteryPercent, 0 , 100, 0, 58), 32);

gb.display.setCursor(30, 30);
gb.display.setCursor(32, 36);

See more
Author :  jicehel

Thanks, nice job but when i use my META and have to check the battery level, i will probably not have my backpack near. The solution could be to hack directly the console but it's unsafe. a solution could be maybe a little ergonomical backpack to keep when moving but who will not bother when playing / moving or put this function on a playing backpack with a joypad and a wifi connection.

Author :  Godzil

Interesting idea, but a few comments, Lithium battery voltage is not linear while discharging, so you will not get a really useful information for most of the run time 

Roughly, it will stay at around 80% for a long time, then drop really quickly up to completely depleted.

Also it really depends on where the ADC VREF is connected on the SAMD, if they use the battery, your reading will always be wrong especially when the battery voltage will start to really drop.

And I do hope they are using VBAT because the output of a buckboost (if they use convert the 3.7V to 5V) is probably way too noisy for an ADC to works well....

Author :  ripper121

They use a buck boost. 

I have no datasheet from the battery and also no schematics from the meta, because they are not open source. 

So I can't do it any better. 

Author :  Voxel5000

Nice job     !!! 

Author :  Godzil

I know I know

Author :  Aurélien Rodot

Nice project ! :)

A few considerations :

@Godzil : yes the battery voltage is not linear, that's why on The Classic have few thresholds : full, not full, critical

VBAT is directly connected to the battery "+", and 3V3 is output from a buck converter.

The problem with that solution is that even when the Gamebuino is OFF, it will have a continuous leak current that will empty the battery. So, you better not leave your Gamebuino with this backpack for a month or it will empty itself.

@jicehel : you can keep the backpack on your Gamebuino all the time, it's design to fit in the case without protruding :)

Author :  ripper121

Yes will be better with a mosfet and 1Mohm pull-up to turn on the measurement 

Author :  Aurélien Rodot

Good idea. But then is would use 2 pins just for battery measurement... that's why I eventually decided to keeps the pins free by default in case you want to do something else with them :)

Author :  Godzil

That's true that this design would drain the battery, but with the current value, we are at (3.7/430000 = 0.0000086 A so about 8.6 uA which is nearly negligeable. Just setting the resistor value to 10* would divide the current by 10. (860nA)

On a ~1000 mAh battery fully charged 8.6uA of consumption is would have a runtime of about ~116216 hours or about ~13 years. I think the battery would have self discharge way before.

The biggest issue with resistor based is that you will need 0.1% precision resistor to get a proper reading, standard 10% the value will be consistent on one platform but will differ on another one...

Author :  Aurélien Rodot

Problem is that you cannot use super-high resistance values are your are saying or the analog reading will be inconsistent. That's because analog reading works by filling a little capacitor, and if your source don't provide enough current to fill it you'll get inaccurate readings. To overcome this on the Gamebuino Classic, I added an external capacitor to the voltage divider, so that it can fill the analog reading cap. I also do several readings and average them.

On the META I removed all the current leaks possible to avoid the high self-discharge the Classic suffered.

Else you could use an external circuitry to light up a RED LED when the battery is about to die, this way you don't have to re-compile games to show battery level. I'm sure you can find ready made circuits which does that.

Author :  DFX2KX

the self-dischage issue can be a serious issue if you don't know about it.

On that note, let me go plug my classic in before it burns out it's new battery... That explains a lot, actually.

Author :  ripper121

I dont think that it was a problem of the current draw of 8.6uA, because that will need years, the self discharge of the Battery is higher.

Also the battery has a protection circuit which will turn off when the voltage is to low.

Author :  Aurélien Rodot

Also the battery has a protection circuit which will turn off when the voltage is to low.

...theoretically. Experience proved otherwise ;)