paulv
Posts: 558
Joined: Tue Jan 15, 2013 12:10 pm
Location: Netherlands

RPi Power Supply w. UPS, one button control

Tue Apr 26, 2016 9:26 am

[Update Sep-17]
A friend and I designed a UPS for the more power hungry Models. Have a look here :
viewtopic.php?f=29&t=192959


[Edited diagram and text]
Following previous designs for my RPi, in particular the one-button-start-stop method, and several UPS based supplies, I wanted to see if I could combine the two and make it more simple and advanced at the same time.

The one-button-start-stop solution can be found here
viewtopic.php?f=91&t=129357
My latest UPS based supply can be found here :
viewtopic.php?f=37&t=132201&p=882125#p882125

In the previous designs I stayed away from Li-ion type batteries due to the complex charging mechanism and the risk of mishaps when you get that part wrong. However, in order to reduce size these 3.7V cells are the way to go if you can make them work.

The time was right to give that a try. In my earlier designs, I used a diode OR to combine the 5V coming from the wall-wart and “mixing” that with the voltage coming from the battery. This voltage was then fed to a Booster-Buck board which boosted the mixed voltage to about 8V and then reduced (Buck’ed) it to the 5V1 going to the Pi.

I found a couple of Li-ion charger boards and controllers, and ordered a couple of li-ion cells so I thought I was off to a good start. It was really easy to get the charging portion right and learn more about the charging sequence, the over voltage protection and the end-of-charge point.

Unfortunately, I struggled to use the single Li-ion 3.7V cell in my original power supply and switch circuit, because of the voltage drop caused by the Schottky diode mixer. The minimum input voltage that the XL6009S or the LM2577S requires to output the needed 1A current kept giving me problems. It should work reliably, theoretically, but it didn’t. I also tried a few “loss-less” MOSFET circuits as a mixer, but was disappointed in the results by limiting myself to using through-hole parts.

While searching for better DC boost convertors that had a lower input voltage minimum, I stumbled on the Adafruit PowerBoost 1000c board.
https://learn.adafruit.com/adafruit-pow ... t/overview
With this board, I hit the jackpot. It has everything I needed for my RPi supply.

The key features for me where:
Excellent charger capabilities for the Li-ion cell
Simultaneous charging and providing power (loadshare)
A low battery indicator
An integrated voltage boost circuit designed for a Li-ion cell
An integrated power enable pin to cut the output power

This board can charge a cell with a maximum of 1Amp, and can simultaneously power an RPi. The combined current for charging and the output is 1.65Amps, but the RPi gets priority over the charge current. If the main supply cannot provide enough current, the Powerboost will use the cell capacity to boost the output current. This is great for the wildly varying demands an RPi has that can cause a voltage droop which makes the RPi unstable, or even crash.

I tested this supply over a period of about a month now, with two of my Model (1) B's and briefly with my Model 3. I don't have a Model 2 to test for you, but that should work too. If you don't max out all the cores for the Model 3 and don't hang too many power hungry USB devices on it, it should work within the specs, but make sure you check that out.

I designed the following circuit around this board :
li-ion UPS V2.png
li-ion UPS V2.png (62.37 KiB) Viewed 10153 times
[UPDATE]
Due to a longer boot period on later kernels and on some RPi models, the period between applying power to the RPi and the activation of the poweroff overlay has changed. To be safe, replace the 100uF capacitor in the diagram with a 220uF version.

If you followed my other one-button-start-stop circuits, this one has a few changes and improvements. First of all, the main difference is that I needed to add a level shifter to drive the output enable (EN) signal for the board.

Compared to the other designs I published, there are some additional changes that made the circuit less dependent on component tolerances. What I felt was needed was a more solid voltage level on the charge capacitor junction to better support the dual use. (start & stop)

After initiating the startup process and the full boot, this level (through the button) is also used to powerdown the RPi and it could get too close to the event trigger point, resulting in false interrupts. They are filtered out in software, but this can be avoided all together. In this newer design, I still use the GPIO pull-up parameter on the shutdown_request pin. By the time the button can be used to powerdown the RPi, the voltage at the junction would have been raised to a higher level by the pull-up as soon as the daemon starts to run. I also swapped a resistor for a diode to limit the pull effect from the gpio-poweroff pin to the junction and also the base of the transistor. Without that pull on that junction, I could use a smaller capacitor. With these changes, I could now also use a normal run-of-the-mill NPN transistor, instead of a logic level MOSFET that needs to operate in a 3.5V environment.

NOTE
I noticed that since the last firmware upgrades, the activation time of the overlay moved from about 3.5 sec into the boot sequence to about 5 sec. Depending on the component tolerances, especially for the electrolyte, you may want to increase the value of the charge resistor or the capacitor if the supply cuts out during the boot process. I now recommend 8 sec. to stay safe from further changes.

The software script is quite simple with just two event interrupts; one for the button request to power down, and one for the low-bat level, also to power down :

Code: Select all

#!/usr/bin/python
#-------------------------------------------------------------------------------
# Name:        UPS-li-ion.py
# Purpose:     RPi power supply with Li-ion UPS controller
#
# Author:      paulv
#
# Created:     22-10-2015, modified  26-04-2016
# Copyright:   (c) paulv 2015, 2016
# Licence:     <your licence>
#-------------------------------------------------------------------------------

from time import sleep, time
import subprocess
import RPi.GPIO as GPIO

DEBUG = False
TEST = False

# ----- GPIO setup
POWER_OFF   = 30 # P5-5 is used by dts gpio-poweroff overlay : reserved!
LOW_BATT_P  = 31 # P5-6 critical battery level, active low
STOP_REQ_P  = 29 # P5-4 stop/start button input, active low to shutdown RPi

if DEBUG : GPIO.setwarnings(True)
else : GPIO.setwarnings(False)

# Use the Raspberry Pi BCM numbered pins
GPIO.setmode(GPIO.BCM)

# Low Battery level sensing
GPIO.setup(LOW_BATT_P, GPIO.IN)
# Shutdown request (with extra pull when daemon starts to run)
GPIO.setup(STOP_REQ_P, GPIO.IN, pull_up_down=GPIO.PUD_UP)


def low_bat_level(LOW_BATT_P):
    '''
    Interrupt service routine that gets called when the li-ion battery voltage
    is getting to a critical level < 3.5V.

    When the low level is detected, the Pi should be
    shutdown to prevent a crash and avoid possible damage to the SD card.
    To avoid jitter in the recognition, a valid signal is deemed correct when
    it is low for a 2 sec period within a 4 sec window.
    '''

    # if we're here, we have a low bat alarm
    # remove event detection to avoid glitch detections
    GPIO.remove_event_detect(LOW_BATT_P)

    if TEST : print "Batt low detected"

    # start to count the logic levels by sampling 8 x roughly
    # every 250 mSec = 2S, which is then also the largest false detection
    # period we can skip.
    edge_start = time()
    cnt = 0
    while (time() - edge_start) <= 4 : # check within a 4 Sec window
        if TEST : print "batt low ; cnt = ", cnt
        sleep(0.25) # check every 250 mSec
        if GPIO.input(LOW_BATT_P) == 0 : # Looking for valid low batt levels
            cnt += 1
        else: # when we have captured a glitch, start all over again
            cnt = 0

        # With 8 consecutive levels, or when the max time is up, leave.
        if cnt == 8 :
            break

    if cnt == 8 :
        if TEST : # acknowledge but continue running
            print "Low battery level is real"
            sleep(2)
            # setup the event detection for the low batt level again
            GPIO.add_event_detect(LOW_BATT_P, GPIO.FALLING, callback=low_bat_level, bouncetime=20)
            return
        else:
            subprocess.call(['logger "Critical battery level, RPi is shutting down"'], shell=True)
            print "Critical battery level, shutting down RPi now!"
            subprocess.call(['poweroff --poweroff'], shell=True, \
                stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            sleep(20) # do not return, wait it out here.
    else:
        if TEST : print "False battery alarm ", cnt
        sleep(2)
        GPIO.add_event_detect(LOW_BATT_P, GPIO.FALLING, callback=low_bat_level, bouncetime=20)
        return


def stop_req(STOP_REQ_P):
    '''
    Interrupt service routine that gets called when the start/stop button
    is pressed while the RPi is running.

    When this event is detected the Pi should be shutdown.
    To avoid incorrect button presses, the button must be pressed for >4 seconds
    otherwise, it is deemed an invalid press.
    '''

    # remove event detection to avoid false detections
    GPIO.remove_event_detect(STOP_REQ_P)

    if TEST: print "Stop request detected"

    edge_start = time()
    cnt = 0
    while (time() - edge_start) <= 7 : # check within a 7 Sec window
        if DEBUG : print "Stop button ; cnt = ", cnt
        sleep(1) # check every second
        if GPIO.input(STOP_REQ_P) == 0 : # Looking for valid low batt levels
            cnt += 1
        else: # when we have captured a glitch, start all over again
            cnt = 0

        # With 5 consecutive levels, or when the max time is up, leave.
        if cnt == 5 :
            break

    if cnt == 5 :
        if TEST : # acknowledge but continue running
            print "Shutdown request is valid"
            # wait for the cap to charge back to a logic level 1 to avoid false hits
            sleep(7)
            # setup the event detection again
            GPIO.add_event_detect(STOP_REQ_P, GPIO.FALLING, callback=stop_req, bouncetime=20)
            return
        else:
            subprocess.call(['logger "Shutdown requested, RPi is shutting down"'], shell=True)
            print "Shutdown requested, shutting down RPi now!"
            subprocess.call(['poweroff --poweroff'], shell=True, \
                stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            sleep(20) # do not return, wait it out here.
    else:
        if TEST : print "Invalid button press"
        sleep(2)
        GPIO.add_event_detect(STOP_REQ_P, GPIO.FALLING, callback=stop_req, bouncetime=20)
        return


def main():

    # add an entry to /var/log/syslog
    subprocess.call(['logger "RPi supply daemon started"'], shell=True)

    # setup the event detection for the low batt level
    GPIO.add_event_detect(LOW_BATT_P, GPIO.FALLING, callback=low_bat_level, bouncetime=20)
    # setup the event detection for the start-stop button
    GPIO.add_event_detect(STOP_REQ_P, GPIO.FALLING, callback=stop_req, bouncetime=20)

    try:

        while True:
            if TEST:
                print "low_bat  = ", GPIO.input(LOW_BATT_P), "stop_req = ", GPIO.input(STOP_REQ_P)
            sleep(5)

    except KeyboardInterrupt: # Ctrl-C
        if DEBUG : print "Closing GPIO channels"
        GPIO.cleanup([LOW_BATT_P, STOP_REQ_P])


if __name__ == '__main__':
    main()
To install this daemon at boot, I took the simple method of adding it to cron.
Add this to crontab (crontab –e) to get the daemon started :

Code: Select all

@reboot sudo /usr/bin/python /home/pi/UPS-li-ion.py
The device tree overlay gpio-poweroff is installed by editing /boot/config.txt and by adding this to the end of the file:

Code: Select all

# Enable Poweroff
dtoverlay=gpio-poweroff,gpiopin=30
The only complexity in the Python script is caused by the “filtering” of the occasional misfiring of the RPI-GPIO event detection. You can read more about that in a post I wrote about Characterizing GPIO input pins :
viewtopic.php?f=29&t=133740

In any case, my goal was to provide a power supply with a simple one-button start-stop method, and a power backup to prevent power related crashes and damage to my SD cards. This design works really well. Here are two pictures on how I implemented this.
IMG_3008.JPG
IMG_3008.JPG (39.34 KiB) Viewed 10459 times
IMG_3010.JPG
IMG_3010.JPG (30.79 KiB) Viewed 10459 times
I did not implement the sensing of the main supply because I don’t need it. If you do, it only takes two resistors and a smoothing capacitor.

Note that this will not be a complete solution for embedded systems that need to have a fully automatic start mechanism. To add that, you need a hardware watchdog like the one I used in my automatic power supply.

I hope this helps to provide better power to the RPi.

Enjoy!

I also designed a supply that can be used in "embedded" or in autonomous applications. Look here : viewtopic.php?f=37&t=150358
Last edited by paulv on Mon Sep 11, 2017 8:15 am, edited 10 times in total.

User avatar
MarkHaysHarris777
Posts: 1820
Joined: Mon Mar 23, 2015 7:39 am
Location: Rochester, MN
Contact: Website

Re: RPi Power Supply w. UPS, one button control

Tue Apr 26, 2016 9:41 am

~very cool ! Thanks for sharing... :)
marcus
:ugeek:

guitaristbryan
Posts: 3
Joined: Fri Apr 22, 2016 8:22 pm

Re: RPi Power Supply w. UPS, one button control

Tue Apr 26, 2016 5:10 pm

Nice post - I am not able to pull up your schematic. I'm doing a similar project and wrote a question about it here.
I could use your help about where to put the diode and how the "switching" works when going from USB operation/charging of battery to pure battery power when you disconnect from the source.

http://i.imgur.com/y6V7zJz.jpg

Any ideas?
Thanks!

viewtopic.php?f=41&t=145550&p=959417#p959417

paulv
Posts: 558
Joined: Tue Jan 15, 2013 12:10 pm
Location: Netherlands

Re: RPi Power Supply w. UPS, one button control

Wed Apr 27, 2016 8:29 am

Brian,

The diode you have in the bottom of your diagram should be moved to the output of the battery booster.
In essence the two supplies should each have diodes with the cathodes pointing towards the RPi.
The Or-ing of the two diodes ensures that the higher voltage presented at the anodes will win and supply the RPi. In your case, you have to carefully tune the voltage of the supplies such that the wall-wart one always "wins" the tug of war. The difference should be at least 100mV, but not much more, otherwise the Pi will notice the drop and may reboot. This is why I use a different place to put the OR in my designs.

Look at this post as an example for a detailed description of what I mean.
viewtopic.php?f=37&t=102015

Be aware of the voltage drop of the diodes you use for the OR. A normal diode like a 1N400x will drop 0.6V. A Schottkey diode like a 1N5819 (1Amp) or 1N5822 (3 Amp) will drop only about half that voltage.

Lastly, if you connect your supply to the P1 connector, you will eliminate the over-voltage protection for the RPi. There is a 6 V protection but that only works if a fuse gets tripped. You bypass the fuse, such that something can go up in smoke. Your battery can supply a lot of Amps, so you have to be extra careful. Look for the RPi schematics of the model you use for details. I suggest you put a fuse between the diode OR and the Pi. The size of the fuse depends on the model Pi you have and what you feed through the USB ports from it.

PS If you "right-click" on the diagrams in this forum, you are presented with a possibility to view them full screen. The reason for the small size has to do with the file size limitation for attachments of files on the forum.

User avatar
CynicOdys
Posts: 6
Joined: Thu Jun 02, 2016 8:40 am

Re: RPi Power Supply w. UPS, one button control

Thu Jun 02, 2016 3:46 pm

Awesome post!

Just a few quick questions though,

1) I know that Rpi 2 uses at least 2 Amps and let's assume that I need another extra Amp for a servo, can the adafruit charger support that Amperage? Because If I remember correctly it has a limit of 1 Amp(which is not enough even for Rpi 2 alone)

2)Also,Is is possible to replace the quite expensive Adafruit charger with something much much cheaper, like this ( http://m.banggood.com/37V-Liion-Battery ... 28948.html ) or any other chinese pcb or we will have quality problems?

*edit*
3) I just found this ( http://www.amazon.com/SMAKN%C2%AE-Lithi ... B00WDQIA9W ) but i am not sure whether it can be used as a ups.

Thanks in advance for your time :)

paulv
Posts: 558
Joined: Tue Jan 15, 2013 12:10 pm
Location: Netherlands

Re: RPi Power Supply w. UPS, one button control

Fri Jun 03, 2016 7:28 am

Hi CynicOdys,

First of all, I think you need to verify that an RPi uses 2Amp minimum. In my experience, they seldom do, because it depends on what it is doing. Only if you run your core(s) flat out, that may be the case. Then there are the USB peripherals to take into account.

According to the information Adafruit has on their website, the charge rate for the cell is maxed at 1 Amp. The way I read the specs, the Powerboost can supply 1.65Amps to the output, while charging a cell at the same time. The output demands have a higher priority over the charging process. If the current demand of the RPi is momentarily higher than the main power can deliver, the Powerboost will use the capacity of the cell to boost the output.
This should be plenty for both the RPi-2 and 3, but depends on what you hang on to the USB ports. If this poses a problem, you can reduce the max charge rate to 500mA by changing a resistor on the board. (I wish they added a way to jumper that selection)

Just supplying a charger for the cell does not give you the complete solution. I tried and experimented with several chargers in the chip form and with complete boards like the one you showed with your link. The trick is also to boost the power from a low level of 2V5 upwards to 5V2 with 2 Amps, and to be able to switch that power on/off. As I mentioned in my post, I tried that, but did not find a good solution.

By the time you have gathered all that stuff separately, you may as well get everything on one little pcb, which is why I went for the Adafruit Powerboost. They probably cost more, but work very well in our intended application.

I'm not sure the Amazon offering can do what you want. The only way to find out is to get one and try it out. I'm sure that over time we'll see better solutions coming available, so we all should keep our eyes open, and publish what we find.
I also hope that a manufacturer sees the potential of adding my design to that of the Powerboost circuitry (which is just a standard "data sheet" implementation of both chips) on a single pcb and make that available to RPi users. That would be really interesting!

In any case, thank you for adding the information.
Last edited by paulv on Wed Jun 15, 2016 8:45 pm, edited 1 time in total.

User avatar
CynicOdys
Posts: 6
Joined: Thu Jun 02, 2016 8:40 am

Re: RPi Power Supply w. UPS, one button control

Fri Jun 03, 2016 10:16 am

Hey,

Thank you for that quite detailed reply.

I did a little bit of research over at Adafruit's forums and apparently the powerboost has a limit of 1.1 (although some would say 1.8).Also according to an admin, the Rpi 2 pushes the chip at it's Amps limits and it's downright inappropriate for Rpi3. That's because the power management chip (mcpXXXX) has tight amp limits(actually this is the component that forces that 1.1limit) and in order to raise the Amp allowance you have to change the chip and actively redesign the whole board. (all this info came from their forums)

I am thinking about ordering that Amazon thingie and trying to make a simple switch mechanism with diodes and what-not, between the main supply and the battery, something that would actually take 2 different supplies for the battery and my Rpi)
According to the amazon customer reviews, this pcb is perfect for making a powerbank,whoever it does not state whether it has a "pass-through" mechanism so when battery is full, the input goes directly to output.Also it get's quite hot and one guy had to use a fire hoze :lol: to put it out.(scary stuff)

Lastly, I found that a dirt cheap pc ups is close in price range to our custom circuit and has a 7000mah battery, which powers a pc for 5 min or Rpi for 5 lifetimes(hours).Also it poses no amp limit so we can hook up whatever we want.

Cheers and thank you for your contribution with this and the other ups circuits, for people like me (noobs) it quite educative.

paulv
Posts: 558
Joined: Tue Jan 15, 2013 12:10 pm
Location: Netherlands

Re: RPi Power Supply w. UPS, one button control

Fri Jun 03, 2016 1:08 pm

Thank you for that info.
I'll keep that in mind and update the Forum post.
I have several model 1 B's and one A I use for most (embedded) applications, and only just got model 3 for general computing things.

Please consider writing about your experience with the Amazon thingy!

Enjoy!

User avatar
CynicOdys
Posts: 6
Joined: Thu Jun 02, 2016 8:40 am

Re: RPi Power Supply w. UPS, one button control

Fri Jun 03, 2016 6:35 pm

I have concluded that building a custom psu for the rpi that can also support various goodies and not just rpi in idle server mode, is really not worth the effort and money. You can either buy a ready hat made by modmypie or just use the cheapest mains psu around

Fun fact though: I just saw that that my oneplus power bank has the exact same structure as that amazon pcb (USBA-mini-USBA) and have the same Amp limit(2A from one port, or 1A at each), my spider sense tells me that they use the same pcb or something very similar.

So, what I want to say is that the powerbank costs 20 euro + shipping and has a capacity of 10000mah. So, with 20 eu you buy a huge battery and a good charging circuit on top of a sort of quality check (oneplus is pretty decent). Maybe it's worth buying one and fiddling with it.
https://oneplus.net/gr/oneplus-power-bank

Cheers and see you around mate

(for the sake of the post, I concluded to use an old mains PSU and focus on other aspects of my IoT smart home project, for which you can read here http://odyslam.github.io/ )

redM0nk
Posts: 1
Joined: Wed Jun 15, 2016 5:40 pm

Re: RPi Power Supply w. UPS, one button control

Wed Jun 15, 2016 11:24 pm

Hello guys,

I am also trying to do something similar using Powerboost and raspberry pi (A+). In my use case, the raspberry pi is remotely located and is powered by Powerboost 1000c. The powerboost is connected with a battery (lipo) and a solar panel (similar to wall charger like V_usb).
In my understanding, whenever V_bat > 3.5v (critical voltage), LBO is HIGH, in other case otherwise it is pulled down to LOW

We can classify the Raspberry Pi operation into the following cases:
Case 1: V_usb (solar power) == ON and LBO == HIGH -- Trivial
V_usb will power Rpi
Case 2: V_usb == ON and LBO == LOW -- Trivial
V_usb will power Rpi and charge the battery
Case 3: V_usb == OFF and LBO == HIGH
Rpi will be powered by the battery
Case 4: V_usb == OFF and LBO == LOW
Shutdown the Rpi and wait for the solar panel to re-charge the battery

So far with the help of community, I came up with the following circuit:
rpi.png
Rpi safe shutdown circuit
rpi.png (55.47 KiB) Viewed 9610 times
The idea behind the circuit is as follows:
The diodes (A, B) are used in parallel to create a logic OR gate, the purpose is to keep the power ON if either V_usb==ON or LBO==High. The output of the logical OR gate is fed to the capacitor+resistor discharging circuit, which takes around 10secs to discharge after the power is switched OFF (i.e. V_usb==OFF and LBO==Low) which is enough time to execute a shutdown script on the PI.
So far the circuit works as expected i.e. Keep the Pi ON if either V_usb==ON or LBO==High, otherwise execute complete shutdown.w
But, since the powerboost chip is not disabled after the complete shutdown, it draws the power which can damage the battery. To handle this issue, what I did was fed the capacitor voltage to the base of a PNP transistor, where the collector is grounded and the emitter is connected to the Enable pin on Powerboost. The idea is to ground the En pin as soon as the capacitor is completely discharged (to disable the powerboost chip).

Now what happens is after the capacitor is completely discharged (10 secs after LBO==LOW and V_usb==OFF is detected), the chip is disabled with the help of the above logic. But, right after that the LBO pin is detected as High (I am not sure why this is happening, but I think it is because there is no load on the powerboost chip and that's why LBO goes high again). This causes pi to boot up again, but since the battery is at the critical voltage and there is no solar power the pi goes back to sleep. Essentially the above logic is causing pi to boot in a loop (boot --> shutdown). Is there way I can avoid this undesired bootup+shutdown behavior :?: ?

Any help is appreciated. Thanks

paulv
Posts: 558
Joined: Tue Jan 15, 2013 12:10 pm
Location: Netherlands

Re: RPi Power Supply w. UPS, one button control

Thu Jun 16, 2016 6:00 am

redm0nk,

Have a look here for a complete (embedded) solution where an RPi is at a remote location using a Powerboost:
viewtopic.php?f=37&t=150358

Enjoy!

Return to “Automation, sensing and robotics”