In this post, I build a couple supercapacitor UPS boards for my raspberry pi projects.
For my Convergent restoration, I decided to build an RASCSI to replace some failing SCSI hard drives. The RASCSI is a SCSI emulator built using a raspberry pi. Problem with these types of emulators is that if you carelessly power off the host computer (which was a perfectly acceptable thing to do back in the 80s), you end up also unsafely shutting down the pi — which can cause corruption of the SD-Card, loss of in-memory data, etc.
Back when I built David Gesswein’s MFM Emulator, he included a supercapacitor UPS that provided power just long enough to safely shut down a beaglebone. I figured the same thing would work for a raspberry pi.
An uninterruptable power supply can serve several purposes:
- To provide resiliency when power brownouts occur. Sometimes power will be disrupted for a very short time, just long enough to cause a CPU to reset. A UPS can smooth out these brownouts and provide consistent power.
- For moderate time outages, a UPS can provide enough power to safely shut down the computer. Data is saved, corruption is prevented.
- For long term outages, a UPS can provide power that keeps the computer operational for the duration of the outage — you can keep working while the power is out.
For my use case, a SCSI emulator in a vintage PC, purposes (1) and (2) are valid, but purpose (3) is unnecessary. I wanted the RASCSI to be able to save its data properly when the power is cut. I have no need for it to continue working during a prolonged power disruption. I need about 30 seconds of uptime.
For this level of backup, a supercapacitor UPS is ideal. Supercapacitors charge quickly. Supercapacitors have a good lifespan over many charge/discharge cycles. The vintage computers I’m working on, there might be months between the times when I power the computer on — there’s no need to keep a battery charged during those months.
Basic Design for a 12V to 5V UPS
The supercapacitor bank is comprised of 5 capacitors each one 10F with a 2.7V rating. In parallel with each capacitor is a shunt regulator that limits the voltage on the cap to approximately 2.5V. This leads to an overall limit of approximately 12.5V, and any voltage across the capacitor bank in excess of that will probably be burned off by the shunt regulators as heat. The supercapacitors are charged by a 3W resistor — David Gesswein’s schematic called from an 8.2 ohm resistor, whereas I believe I used (and perhaps his BOM used) a 10 ohm. Either is probably in the ballpark. This resistor limits the rate at which the supercapacitor can charge. A jumper, JP1 allows you to either:
- Enable the capacitor bank by shorting pins 1 and 2
- Disable the capacitor bank by leaving the jumper removed
- Discharge (and disable) the bank by shorting pins 2 and 3. This is good for working on the circuit.
There are two diodes that control the flow of voltage. D1 prevents electricity from flowing back out the input. D5 prevents electricity from bypassing the current limiting resistor. A couple additional TVS diodes (D2, D3) are optional protections for transient spikes.
One of two voltage regulators may be chosen:
- U$6 is a murata DC/DC converter, OKR-T/1.5-W12-C, same one as used in David’s BOM.
- IC1 is a 7805 footprint, intended to be used with an EZ-SBC buck converter. EZSBC sells these neat little converters that are drop ins for a 7805. PSU5A is rated at 2.5A, and while I’ve used it in other projects, I have not used it here.
These voltage regulators supply power to not only the device (i.e. the Raspberry pi) being powered by the UPS, but also power to the supervisory microcontroller.
A MOSFET switch, Q1, is used as a high-side switch to control power to the device being protected by the UPS. This allows us to turn off the power when the battery gets low, and it allows us to force a reboot by power-cycling the device. It also allows us to prevent power from flowing on start-up until the batteries are sufficiently charged.
U1 is an ATTINY85 microcontroller that serves as a supervisor for the UPS. It constantly monitors both input and battery power via a couple voltage dividers. It supports an I2C interface so the host device (the raspberry pi) can check on battery status. It runs an internal state machine that progresses through various states (capacitor charge, power-on, power-loss, wait-for-reboot, etc). Code for this microcontroller is present in my github repo, linked at the bottom of this page. The microcontroller has an ICSP header so it can be programmed in circuit.
There’s a variety of headers and connectors for various functions. I tried to include both old-school 4-pin HDD and FDD connectors, as well as barrel jacks, and even a USB-A connector for power out.
Implementation, 12V to 5V Supercapacitor UPS
Below is a picture of the PCB I had manufactured at jlcpcb:
Design, 5V to 5V Supercapacitor UPS
The 12V-to-5V UPS fit my need, but I figured, why not try to make this as a hat that I can use with a raspberry pi, directly, off of 5V?
The overall design is similar to the 12V-to-5V UPS, with the following notable differences:
- Rather than 5 Supercap stages, there are just two. At 2.5V each, that allows us to store up to 5V of electricity.
- The microcontroller runs directly off of the input voltage / supercap voltage. The low-voltage version of the ATTINY85 tolerates voltages from 1.8V to 5.5V.
- The boost converter has been replaced with one of three options.
Boost converter options:
- The first option is a Pololu 1.5A buck/boost module. This was the option that I showed in the video. Having a buck/boost module is technically unnecessary — since the input voltage is a maximum of 5V, we never really need to “buck”, but only to boost. The MOSFET switch is not used with this option; we can turn the buck/boost module on/off.
- The second option is a Pololu 8A boost module. This is much better choice for trying to run a raspberry pi 4, since it can easily supply the 2.5A that the pi4 requires, and its efficiency doesn’t plummet as bad as the first option when the capacitor votlage level drops. As of 9/6/2020, I have not tried building this option yet — but it is my recommended design. I’ll update this notice once it’s been proven working. As with option (1), the MOSFET switch is not necessary, we can just turn the converter on/off.
- The third option is to use a MOSFET, without using a boost converter. This will lead to an output voltage that drops as the supercaps discharge. It might be useful for devices that are tolerant of a voltage range of 3V to 5V. One of my plans is to see how low I can power a raspberry pi before it fails and shuts down. This option is not recommended, but what the heck, it’ll be an interesting experiment.
Implementation, 5V to 5V Supercapacitor Hat
As can be seen in the video, this one didn’t quite pan out for me when it cam to powering the raspberry pi4. First, due to several factors (voltage drop on the power cable, voltage drop on the charging resistor, voltage drop on the diodes), we only charged the supercaps up to about 4.25V. This was enough with the 1.5A buck/boost module to boot up and operate the pi, but once we run off the batteries, it only takes about 10 seconds for voltage to drop down to about 3.4V, at which the buck/boost module start to have difficulty powering the pi (the buck/boost module becomes less efficient as voltage drops), the pi4 goes undervolt, and shuts off.
It did work fine on a pi zero w.
I am in the process of switching this module out for the 8A boost module, that I think will be more efficient at lower voltages.
My github repo at https://github.com/sbelectronics/ups contains source code for both the microcontroller and for a python daemon that runs on the raspberry pi.
The python daemon continuously watches the input voltage, and when the input voltage drops, it runs
/sbin/shutdown. Then, during the shutdown sequence of the pi, after the root filesystem has been remounted readonly, a
systemd shutdown script will send an I2C command to the UPS to tell it to power off. The UPS powers off, and then waits for a power-up event (and supercap charge) before it’ll turn the pi back on.
- David Gesswein’s MFM Emulator was the inspiration for the 12V-to-5V module.
- TinyWireS was used to implement an I2C slave on the ATTINY85
- My github repo at https://github.com/sbelectronics/ups has the code.