Lithium polymer batteries are light and powerful, but they can’t be run completely flat or they are ruined. I’ve been using them for several years to fly model planes, so I have plenty of them around. I’ve also been using them at Raspberry Jam meetings to power some of my Pi demos.
I thought it would be fun to make a circuit so the Pi could monitor its own battery voltage. I used an analog to digital converter (mcp3002) and had the Pi check the battery voltage every minute and shut down when the battery was too low.
You need a way to reduce the Voltage
The main “issue” with this measurement is that the ADC can only handle up to 3.3 Volts (when connected to Pi). A 2 cell lithium polymer (lipo) battery is 8.4V when fully charged and 7.4V when empty (resting Voltage). So we need a way of dropping the voltage from 8.4V to something at or below 3.3V. The cheapest and easiest way to do this is with a voltage divider – essentially two resistors connected across the supply you want to measure. The resistor values are chosen so that the meaured voltage can be divided down to the required level.
I chose fairly high value resistors to ensure a very small amount of wasted current (it’s a duration test after all). I used 100 kOhm (R1) on the GND side and 180 kOhm (R2) on the +ve side. This meant that the input voltage (8.4 max) would be split as follows…
8.4V * 100,000 Ohm / (100,000 + 180,000) Ohm = 3.0V (close enough to 3.3V (3V3) plus a safety margin)
So how did it work?
I tested each element before the ‘final run’ and, although it shut down a few hours earlier than my optimistically projected 15-16 hrs, the system worked perfectly. It shut down after 9.5 hours, when the battery voltage reached the cutoff level of 3.7 V/cell (2 cells, = 7.4V overall).
Considering the size of the battery pack, 9.5 hours is pretty reasonable.
Here’s how I calculated how long the battery should last.
The, rather old, 2 cell lipo has a nominal value of 2000 mAh or 2 Amp.hours
2 Ah * 7.9 V = 15.8 Watt.hours
* 0.85 efficiency = 13.4 Wh (regulator is ~ 85% efficient on 3 cells, so this is a guess for 2 cells)
Model A with Edimax dongle uses 0.81 Watts
13.41 / 0.81 = 16.5 hours
But this was wrong – it conked out after 9.5 hours and the battery only took 1550 mAh on recharging.
Bearing in mind that recharging is not 100% efficient, we can see why it lasted a bit more than half the predicted duration.
Still, 9.5 hours is pretty good for a nice portable application.
So, if you’re still awake after all that electronics and maths, here’s what you need to repeat the experiment for yourself…
Gmail account (to have the script send you an email when it shuts down)
RPi.GPIO (it’s already included in Raspbian since August 2012)
Shopping list of parts
ADC (I used mcp3002)
Resistors for voltage divider
A small capacitor (I used 0.1 uF – this may not be strictly necessary)
Some jumper wires
A breadboard or prototyping board (you could use a Gertboard too)
Download this script
or, straight from Pi command line…
Then you’ll need to open the script and set some variables.
Which lines to tweak?
You MUST set the email variables.
# email variables
fromaddr = 'email@example.com'
toaddr = 'destination email address'
# Googlemail login details
username = 'your googlemail/gmail username'
password = 'your googlemail/gmail password'
Optionally, you can tailor other variables to your needs…
# voltage divider connected to channel 0 of mcp3002
adcs =  # 0 battery voltage divider
reps = 10 # how many times to take each measurement for averaging
cutoff = 7.5 # cutoff voltage for the battery
previous_voltage = cutoff + 1 # initial value
time_between_readings = 60 # seconds between clusters of readings
# Define Pins/Ports
SPICLK = 8 # FOUR SPI ports on the ADC
SPIMISO = 23
SPIMOSI = 24
SPICS = 25
Then save and exit
Hooking it all up
You’ll need to wire up your circuit next. In case it’s not clear, the battery is connected to a 5V regulator, which powers the Pi. We also have direct connections from the battery to the voltage divider.
Running the script
Once your circuit is wired up, power up the Pi with your battery/regulator and run the script. I ran it using screen so I could detach from it and log off (in order not to waste battery power).
Run the script with
sudo python batt_test_raspi.tv.py
If you have SPI enabled, you’ll get a warning, which you can ignore.
You’ll then see it takes a reading every minute and displays the ADC reading, the Voltage measured, and what it’s writing to the log file battery_log.txt (which you can look at afterwards
It looks like this…
Battery log data
2013-03-03 13:29:55, 8.266
2013-03-03 13:30:56, 8.275
2013-03-03 13:31:56, 8.266
2013-03-03 22:57:00, 7.399
2013-03-03 22:58:07, 7.399
Shutting down due to low V at 2013-03-03 22:58:10
No geeky science experiment would be complete without a graph, so here’s a graph of the complete voltage log.
If you happen to be watching in the last two minutes before it switches off, you’ll see it telling you it’s sent an email and giving a shutdown warning. I had the script email my phone so I knew when it had shut down.
I hope this has been fun and educational. :)
If you are going to use this with a higher voltage battery you will need to change the values of the resistors to step the ADC input voltage down to a maximum of 3V3.