Close
0%
0%

[mUPS] Minimal UPS for Raspberry Pi

A short hold-up UPS with automatic safe shutdown and reboot

Similar projects worth following
I needed a way to keep the Raspberry Pi of my robot (see links) alive long enough to be safely shutdown after the main power is removed (via e-stop in my case). I don't want to worry about shutting down, just pull the power. Equally, the RPi should boot when power is reapplied. And I don't need long hold-up times either.

There are solutions out there for this but I wanted to avoid the need for a custom PCB, if possible, and just use off-the-shelf parts so I can be flexible with the arrangement.

I split this out from my main project to make it easier for me to find and update. I'm generally terrible at documenting my projects.

Requirements

  1. Loss of main power should trigger the RPi to shutdown.
  2. Return of main power should boot the RPi.
  3. Power-up should wait until caps are sufficiently charged so RPi can boot cleanly.
  4. Wait for RPi to shut down before removing power (to enable reboot).
  5. Should cope with brief power drop-outs (maintain RPi operation).
  6. (Re)boot after shutdown completes if power returns whilst shutdown is in progress.
  7. Be as simple as possible and relatively low cost.

Prototypes

I'd had originally chosen to base the UPS around a "Raspberry Pi Wemos 18650 Battery Shield V3", essentially the guts of a small powerbank (as I already had some 18650 cells and I could easily access connections and package it in a way that suited me), but that had issues (see logs).

I also went through a couple of iterations of comparator and supercap circuits until I realised it is easier to get the correct behaviour from a µC than from a bunch of analogue components. Easier to tweak the behaviour too.

The latest design still uses hassle-free supercaps to provide the hold-up, coupled with a small Arduino to handle the delays and conditional switching (a Nano, Mini, Trinket or similar should do). The supercaps, as a bonus, support the peak power demands of the RPi, allowing me to get away with using a smaller power supply. In theory, anyway. I'm still testing the latest version...

  • 1 × DPDT relay, 5V coil. Opto-isolated to protect the µC.
  • 1 × Arduino Nano Or your favourite µC module

  • Before you kill your RPi...

    Paul Crouch06/02/2020 at 15:33 0 comments

    I have twice now killed a GPIO input pin by forgetting that 5V is greater than 3V3. This is annoying, but at least it's not the whole Pi. I updated the schematic to include the simple potential divider that I keep forgetting (circled in red). The values aren't too critical, here I've selected them to keep the output (input into the Pi) below 3V even if the input gets to 5.1V.

  • Configuring a RPi for mUPS

    Paul Crouch05/27/2020 at 21:32 0 comments

    This is what I did, based on my experience (not a lot) and research (not enough?). There may be better ways to do it. Feel free to tell me what I'm doing wrong in the comments ;-)

    Basics:

    • Using Ubuntu MATE 18.04 for RPi, downloaded 22 May 2020 (lost password and hadn't done anything with previous ROS install so didn't mind starting over).
    • 16GB Sandisk µSD
    • Wired Ethernet connection (already setup). Otherwise, pre-configure WiFi with wpa_supplicant.conf
    • KVM switch for easy use of GUI.

    Install OS

    • Unzip (7-zip)
    • Flash .img to SD (balenaEtcher)
    • Insert & power-on

    Check, set and update via config tool

    Boot to GUI or CLI etc…

    sudo raspi-config

    May as well update everything…

    sudo apt-get update && sudo apt-get upgrade

    Not necessary, but useful

    Edit /boot/config.txt and add/change both of these...

    dtparam=pwrt_led_trigger=heartbeat   #nice load indicator
    
    dtparam=watchdog=on

    Create/copy-in the mUPS.py file

    (filenames are case-sensitive!)

    #########################################################################################
    # mUPS.py handles UPS/main-power switch-over and RPi shutdown for Droidbot.
    # P.Crouch
    # Rev3
    # May 2020
    #
    # *** Developed for my own use and provided as-is, with no guarantees ***
    #
    # RPi signals to mUPS when it is up. mUPS tells Pi to shutdown and waits for RPi_UP
    # to go low before removing power.
    #########################################################################################
    RPi_UP=21       # pin 40
    RPi_SD=27       # pin 11
    
    Read more »

  • Testing new code

    Paul Crouch05/22/2020 at 16:07 0 comments

    I've reworked things as the Coronavirus chaos has given me some time to revisit the design.

    I've just fixed some issues in the new code and tested it again and it seems to work with no odd behaviour! That's a start.

    Next, connect supercaps and relay...

  • Simply a dead battery, sort of

    Paul Crouch04/16/2019 at 21:03 0 comments

    I pulled the UPS out again last night l so I could get at things to investigate the problem. Here’s what I found: 

    • The battery voltage dropped to ~2.5V after the Pi started booting.
    • It behaved the same when the Pi was powered directly from the 18650 boost circuit (with the rest of the circuit disconnected).
    • Another 18650 cell was swapped in and the Pi booted fine and ran until I shut it down manually.
    • With the new cell in place and the rest of the circuit connected it all functioned as expected.

    So I've concluded that the cell had become discharged, as it is permanently powering the boost circuit, and wasn't able to support the Pi's power requirements for boot up. I knew that the on-off switch only disconnects the output to the USB socket, but underestimated the boost circuits drain and the impact it would have when used in this manner. Compounding the problem is the DC-DC converter supplying the Pi and the cell; it can't deliver enough current to both charge the depleted cell and allow the Pi to boot.

    Raspberry Pi UPS in Droidbot 07

    After my last post, I had a brief discussion with Bud Bennett and I began to re-evaluate my approach. I don't actually need the option of a keep-alive mode where I can choose to keep the Pi running for minutes/hours after main power loss instead of shutting down straight away. I added it because I could. So I don't need the selectable delay provided by the µC or the indicator LEDs, again, only included because I could. The Pi is quite capable of shutting down based on the state of a GPIO pin driven from a simple divider hanging off the main supply, I just had the µC do it for flexibility. I only have to provide enough power for ~30sec. So have I over complicated it? I do that sometimes. 

    I could use a beefier converter capable of providing more current and ensure the cell is also disconnected from the circuit at switch off, but that's a PITA. I want to keep it simple and low cost so it'd be easy to make another for any Pi project. I'm avoiding doing a custom PCB as I'd like to stick to off-the-shelf parts so it's quick and easy to duplicate. If you need me, I've gone back to the drawing board.

  • Hold fire!

    Paul Crouch04/14/2019 at 13:02 0 comments

    Dammit! I went to use the Pi and the bloody thing wouldn't power up properly. The power LED lights and the activity LED briefly flickers. A USB meter showed the Pi supply voltage drops to ~3.6V after a short time. Not enough for the Pi to boot.

    Maybe I've messed up the wiring and I've got some current going somewhere it shouldn't and something is overheating? I need to pull it apart again to investigate.

  • Version 1, kinda.

    Paul Crouch04/11/2019 at 18:17 0 comments

    I'm calling it version 1 with the intention of revisiting it to address some lose ends and make some improvements. Version 2 will come when I need a longer hold-up, rather than the (almost) immediate shutdown.

    You can find my excuses elsewhere as to why it's taken so long and why this documentation is a bit thin, but here's the short version of events:

    • I needed a UPS for the Raspberry Pi to handle sudden power loss and prevent file corruption.
    • The "Wemo 18650 Battery Shield" will output whilst taking power and it's cheap. I like cheap.
    • The RPi can't be trusted to shut it's own power off so I looked for the smallest, cheapest Arduino-type board (to minimise faffing) to handle the delay-if-then logic. I got a couple of DigiSpark boards (clones as it turned out) and cobbled together the code and connections.
    • Saw some odd behaviour, maybe the DigiSpark board isn't what I need.
    • Worked around the issue, circuit and code seem to work on the bench until the RPi is actually connected (instead of manually simulating the I/O signals).
    • (some time later) Sick of the DigiSpark; I switch to the trusty Nano, then add some traffic-light LEDs for indication and because I can.
    • More odd behaviour; looks like back-feeding through the µC inputs. I should really disconnect the GND too.
    • I transplant a small DPDT relay onto the opto-isolated "arduino" relay board and re-wire again to also break the GND this time.
    Twenty-third-time lucky?
    • Dammit! Killed a Pi pin by forgetting 5V > 3V3. Moved to next GPIO and added a pot.div.
    • Success!?! Tested the UPS with the RPi two or three times, mounted both in the head and moved on to power distribution but I'm waiting on some parts that got delayed in transit, so I'm using the time to write this. Below is the schematic I did a few days(?) ago.
    UPS diagram (not showing GPIO potential divider!)
    UPS diagram (not showing GPIO potential divider!)

    Arduino

    3 - RPi_UP (DI), RPi GPIO output - high after boot, low just before complete shutdown.

    2 - RPi_SD (DO), RPi GPIO input - active-high to trigger shutdown of RPi (through pot.div; 5V >> 3V3). 

    Not Used: A0 - ADC to 18650 battery, 4V - disconnect load from battery when voltage drops.

    4 - Main Power present/not present (DI).

    Not Used: 5 - Keep alive/immediate select switch (DI)*

    6 - Relay (DO) - active-high opto-isolated (N.O. contacts). Opens to disconnect battery.

    7 - Amber UP LED.

    8 - Red SD LED.

    9 - Green MPP LED.

    *Mode selection input:

    Not Used: Keep alive = 0V - waits until battery is low before shutting down and disconnecting.

    Keep alive = N.C. - immediate safe shutdown and disconnect.

    Raspberry Pi

    RPi signals to UPS when it is up. UPS tells Pi to shutdown and waits for RPi_UP to go low before removing power.

    RPi_UP=21       # GPIO output - high after boot, goes low a few seconds before complete shutdown. RPi_SD=17       # GPIO input - active-high to trigger shutdown of RPi (through pot.div; 5V >> 3V3).

View all 6 project logs

Enjoy this project?

Share

Discussions

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates