UPS (Uninteruptible Power Supply) solutions for the Raspberry Pi are available, but generally at rather high prices in comparison to that of the Pi itself. Some time ago, the Geekworm Raspi UPS HAT Board became available on Chinese webshops such as Banggood and DealExtreme. It appears an interesting deal, but it depends on your usage scenario whether it is suitable as an UPS.
I evaluated the functionality of this product and reverse engineered it. This article provides information such as a circuit drawing, and suggestions for modification.
You may copy and use information presented here for your personal purposes, but please do not republish any of it on a website or in any other media. You are welcome to link to this website instead! Thank you.
Important Warning: Following any instructions or suggestions given here is at your own risk! Not only are the components and the PCB of the UPS HAT board easily broken, it uses a Lithium Ion battery which, especially if improperly handled or operated, might explode and/or cause a fire!
If you have questions or comments, you could leave me a message using this website's contact page.
I want to use a "headless" Raspberry Pi for home automation. The problem with using a Pi as is, is the risk of blackouts. It is known that when the power to the Pi is cut without warning, SD card data corruption may occur, and the Pi may not even be able to start up again when the blackout ends. Obviously, this is not acceptable; the Pi must reliably resume operation, without needing any intervention, when power is restored. A UPS allows the Pi to continue operating on battery power, for at least long enough to do a proper shutdown.
Desired UPS functionality
A suitable UPS solution would need to do the following:
- Enable the Pi to continue operating on battery power, when external power is lost.
- Let the Pi know that this has occurred, so that it can do a proper shutdown before the battery is drained.
- Monitor whether the Pi is still running or if it is executing a shutdown, and after shutdown is complete, switch the Pi off.
- Switch on the Pi again when the external power returns.
The Geekworm Raspi UPS HAT board satisfies point 1 and 2, but not 3 and 4, as explained below.
- When the external power is lost, the UPS HAT board is able to keep the Pi powered.
- The UPS HAT board contains a battery status IC that can report the battery charge level to the Pi. If this level decreases to a certain low value, the Pi may decide to execute a shutdown.
- The board does not detect whether the Pi has shut down. It will simply continue to provide power to the Pi until the battery runs out. And in case the external power returns before that happens, the Pi will forever remain in the shut down state, as it can only start up again when switched off and on.
- When the external power is applied, the Pi is not automatically switched on. You need to push the button on the UPS HAT board for this to happen.
Another issue with the UPS HAT board is that, when external power is lost and returns, the board will not resume charging the battery. The only way to get it charging again is to press the button, which also switches off the Pi! So, even after a short blackout, the battery will stop being recharged, and on subsequent blackouts the battery will be further drained, until it is empty.
So, while there are scenarios where the Geekworm UPS HAT board can be of use, such as protecting against SD card corruption when the Pi is used as a small desktop computer, it's not suitable as a UPS solution for an unsupervised appliance.
Examining the board in detail
One wonders, however, whether it could be made into a proper UPS by some simple modification? A problem is that detailed technical information is not available. Even the type numbers of two IC's on the board are ground off to make reverse engineering difficult.
In a forum topic discussing this Geekworm UPS board, some information was already uncovered. This was of help in reverse engineering the circuit. Now, only the make and type of IC U3 remains a significant mystery. The circuit diagram, as I derived it, is shown below:
Reverse engineered circuit diagram of the UPS HAT board
U1 is ETA Solutions ETA1096, a synchronous step-up converter IC that can convert the external input voltage or the battery voltage to the 5V needed to power the Raspberry Pi. The circuit is similar to the Typical Application circuit shown in the datasheet, except for the addition of D3, Q2 and Q1, whose function appears to be to help the IC start up.
U2 is Maxim MAX17048, an IC that can report the battery status to the Pi via the I2C protocol. This function is separate from the rest of the circuit.
The make and type of U3 remains unknown, but it appears to be a power bank specific IC. Its pin function names as shown in the circuit diagram are my own interpretation. The way it is connected suggests that it can operate as a synchronous buck converter for charging the battery from the 5V input voltage. However, measurements show that when external power is not present, the IC reverses the converter operation, starting to boost the battery voltage to 5V at the input.
My guess is that in powerbanks using this IC, the input and output USB connectors will be wired in parallel. By combining the 5V input and output, and multiplexing the indicator LEDs, its designers got away with using only 8 pins.
Update: It looks like U3 is ETA Solutions ETA9741! Unfortunately, what information I found about it so far is mostly in Chinese.
When the external power goes off, until U3 changes DC/DC converter mode, Vin is only provided by the battery via D2/D4. So during around 1.2 seconds, Vin is seen to drop to around 3.2V. That is one reason why U1 is needed. Also, when the battery is fairly empty, more charging current is drawn from the USB charger, and its voltage is pulled down, with ripple valleys reaching ca. 4.5V. During all this, U1 keeps providing a pretty clean 5V.
The initial voltage at U3 pin 5 is around 0.7V. When this is pulled down even lower, by pressing the button for about a second, U3 reacts by pulling this voltage up to ca. 4.3V. Via R1, this makes U1 start up and power the Pi. In this state, when the Pi is not connected, I observed there was very little current consumption by the UPS board, about the amount necessary to light the indication LEDs. This suggests that, when the Pi is being powered, U3 stops to charge the battery, even if the LED indication suggests otherwise.
The first thing I tried was to connect R1 to the battery voltage, instead of to U3 pin 5.
After this modification, the Raspberry Pi is continuously powered, either from external power or from the battery. If a mains powered USB charger is connected to the micro-USB input, the battery is charged as well, with according LED indication (one of the LEDs will be blinking, unless the battery is full). If the USB charger is taken out of the mains socket, the LED indication changes to showing the battery level without any LED blinking.
Note: for proper operation, it appears that U3 needs to see a large enough capacitance on the input. Therefore, external power is not to be removed by disconnecting the USB cable, but only by removing mains input from the USB charger (this is also what happens when a blackout occurs in actual operation).
I checked that, when the mains power to the USB charger is removed and re-applied, now the battery charging is actually resumed. After a while, the battery was fully charged.
Since this is a relatively simple modification, and it may be useful to owners of the Geekworm Raspi UPS board, I am providing more details >>> here <<<
Taking it a step (or two...) further
So far, the following functions remain to be implemented:
- The Pi should be switched on when external power is first applied or has returned, and the battery is sufficiently charged.
- When external power is lost, this must be signalled to the Pi, so it can execute a proper shutdown before the battery runs out.
- After the Pi executes a shutdown, it must be powered down, to be automatically restarted when the external power returns.
This may be done by adding a simple microcontroller.
Adding a microcontroller to supervise the UPS operation
The microcontroller I used is the Microchip PIC18LF2520. Note that the reason I went with this, is that I happen to have scrap boards with this part on it. It's surely not the optimal (lowest cost) part for this application.
Although this project is not completed, my approach may give you some idea of what is involved. The circuit I added (with minor details omitted) is shown below.
Circuit added to the UPS HAT board
The LED12, LED34 and LEDC signals are connected to I/O pins so that the firmware may detect whether external power is present or not. As noted, when external power is not present, U3 reverses DC/DC converter operation and provides 5V on Vin from the battery. That means you cannot simply detect the presence of external power by monitoring this voltage; it is around 5V in both cases. Instead, my firmware relies on the indicator LEDs, assuming that external power is present in case of "charging" indications (when one of the LEDs is blinking), and also when all four LEDs are continuously on. A minor limitation of this approach is that, when running on battery power while the battery is still nearly fully charged, all four LEDs are on as well, so the Pi can only be notified about the loss of external power after the battery has drained to "3/4 full". However, in practice this is not really a problem.
A short description of the firmware is as follows:
When the microcontroller first starts up, it checks that (according to the LED indication) the external power is present, and that the battery is at least 1/4 charged, before it switches on the Pi. After that, when it detects that the external power is lost, it signals this to the Pi by pulling its GPIO20 pin low. A script that runs on the Pi, and that monitors this I/O pin, will then execute a shutdown, indicating this to the microcontroller by setting GPIO21 high. After a delay, allowing the Pi to complete the shutdown process, the microcontroller switches off the Pi. When external power has returned, and if battery level is sufficient, it switches the Pi on again.
The modified UPS HAT board
Getting it to work
I found that when the microcontroller sets the BOOST_EN line to high, there is a short glitch in the input voltage; it drops to 3.5V during maybe 10 microseconds. That appears to cause a reset of both U3 and the microcontroller, so that the Pi immediately gets switched off again. I suspect this glitch is caused by Q1 which abruptly connects the input capacitance (mostly C4, as the output capacitor in the USB charger is connected via a length of cable) to the discharged capacitance at the output (C18 and the input capacitors of the Pi). I tried to fix this by removing R14 (disabling Q1). Now the Pi (I tested with a Raspberry Pi Model B+) could start up normally.
Note: according to its datasheet, the "Startup Current Limit" of the ETA1096 has a typical value of 2.5A; besides this, it does not have a soft-start function. Depending on the model of USB charger (e.g. how much current it can deliver and how large its output capacitance is) a dip in the input voltage may still occur.
At first, I had connected the Vdd of the microcontroller directly to Vin, but I was seeing occasional resets of the microcontroller, especially on return of the external power. While the microcontroller is able to run within a wide range of voltages, its operation may be disrupted if the supply voltage changes too suddenly. I added 3.3V LDO U5 to stabilize the voltage. Because Vin may temporarily drop below 3.2V when the external power is lost, I connected it to the battery voltage instead. Now, the microcontroller may still reset if the battery voltage drops far below 3.4V, but long before that, the Pi should have shut down and be switched off already, so a reset will do no harm.
Issues to fix:
- More testing under various conditions.
- The Geekworm UPS HAT board, as is, is not suitable as the UPS solution for a Raspberry Pi that is used as an unsupervised appliance.
- It looks possible to modify the board to implement the desired functions, but the necessary modifications are not trivial.
- The fact that U3 remains a "black box", whose behaviour must be inferred from observations, gives less confidence in the correct operation than I would like.