Raspberry Pi battery backup with power control

Premise

I had a Raspberry Pi set up in my car. The problem was it would only run when the car was turned on. I was reluctant to connect it directly to the cars battery for fear of having a drained battery in the morning. So I opted for a stand alone battery system that the Pi could control. It needed to use the cars power when available, and also charge a battery, then without car power, to use an internal battery. It would be alerted to any low power in the battery and also have the ability to turn off the regulator so battery was not consumed.

Hardware

The best device for this was the PowerBoost 1000c. This little unit has all the components to maintain and charge a lithium battery, as well as a buck booster to give 5V over USB out. Swapping from input power to battery is all handled internally with no interruptions. It even has interface pins allow you to control operation.

https://learn.adafruit.com/adafruit-powerboost-1000c-load-share-usb-charge-boost/overview

adafruit_products_2465_top_ORIG.jpg

Circuit Diagram

Here is the wiring between the two units.

It might look confusing but it’s fairly simple. The places to start on the circuit is the EN (Enable) pin on the Powerboost. The Powerboost will always be on, the EN pin floats high. By putting the 10K resistor from EN to GND we pull that pin down permanently turning the Powerboost off.
But what if we want it to run when there is USB power? The connection between USB to EN means that when USB power is available, the EN pin goes high, turning the Powerboost on. The reason for the 10K resistor is to stop a short circuit.
But what if when the Raspberry Pi wants to keep the Powerboost active? The transistor 2N2222 works as a switch. When pin 4 on the Pi goes high, the tranisitor turns on, connecting EN to 5V. Allowing the Powerboost to stay active even if there is no USB power.

The last part is the Low Bat connection. This tells the Pi when the battery is nearing depletion. When ‘Low Bat’ goes low, the Pi will start the shutdown procedure.

NOTE: The Powerboost operating voltage is 5v and the Raspberry Pi logic voltage is 3.3v. This difference would be an issue if more complex communications were happening between the units. But 3.3v is high enough voltage to trigger the 2N2222 transistor, so a step up is not needed for the transistor. The Low Bat pin is only being observed by the Pi, so no current should flow. The pin also shows the battery voltage until it is pulled to GND. The Max voltage is 3.7 for the cell, which is within Pi tolerances. If you are still worried you could put a 1K resistor to limit current, this wouldn’t affect circuit performance.

Code

The first script is what gets run when you type keepAlive into a terminal on the Pi. This bash script lives in /usr/local/bin so it can run without having to be in the directory. All it does it notify the user what is happening and then calls the Python script to run.


#!/bin/bash

# Script to keep the Pi alive until battery runs out

echo "Keeping Pi Alive"

set -x #echo on

sudo python /home/pi/Documents/GPIO/batCheck.py

The other script is a Python script that checks the battery state every minute. It uses RPi.GPIO to access or change the state of the IO pins. It holds the power on while the Pi is running, and checks the battery level. When the battery is low, it notifies the user, then starts a shutdown procedure. This way there is no sudden interruption to anything running, and the Pi can shutdown everything normally.

import RPi.GPIO as GPIO
import time
import subprocess

# -- Set Board NUmber Type -- #
GPIO.setmode(GPIO.BCM)

# -- Pins -- #
pwrPin = 4
batPin = 17

# -- Setup pins -- #
GPIO.setup( pwrPin, GPIO.OUT)
GPIO.setup( batPin, GPIO.IN)

# -- Set the output pin high -- #
GPIO.output( pwrPin, GPIO.HIGH)
# This tells the battery system to keep power turn on
# When the system is turned off then the pin goes low, turning off power.

# -- Loop and check every few seconds -- #
while True:
# -- Check low battery is not active -- #
if not GPIO.input( batPin):
print "LOW BATTERY!"
print "System going down!!"
subprocess.call(["sudo","shutdown","-h","now"])

time.sleep(60)

Conclusion

The system works very well. It works great when I have the Pi in the car but connected to the home wifi. Through SSH I talk and run scripts, but when the power runs out it notifies me and shuts down.

Leave a Reply

Your email address will not be published. Required fields are marked *