With the ESP32-S3 PowerFeather making it easy to create ESP32-based solar + LiPo/Li-Ion projects, it’s time to power something bigger! The next logical step is to give your single board computers like the Raspberry Pis some PowerUPS (pun intended). This enables much more computing power on your remote/off-grid projects - maybe something needing a vision, audio processing, or some sort of edge AI.

However, unlike the ESP32-S3 PowerFeather, I will be building this in public with the hardware design (schematic & layout) available from the start. I hope to leverage the stuff I learned and did for ESP32-S3 PowerFeather in this new project; and in turn, the stuff here can also be fed back into it to make it even better.

If you’re interested in supporting this project, please do take a look at what the ESP32-S3 PowerFeather can do. If you like what you see, consider purchasing one to use in your project. The proceeds will be used as to fund the development of PowerUPS.

You can also show your support by following this project, liking or sharing it to other people. You can also join the Discord server for discussion about PowerUPS.

Goals

For now, the primary target are Raspberry Pi Zero’s, but should be also usable for full-sized Raspberry Pi’s  provided there aren’t too many USB devices attached.

As mentioned, the design will be similar to ESP32-S3 PowerFeather, but scaled up to support higher currents. So some of the things that ESP32-S3 PowerFeather can do,  that you can expect PowerUPS to also be able to do are:

But since it is a UPS for Raspberry Pi, I also hope to implement software features like:

However, for this particular UPS, I have additional hardware design goals:

LiPo/Li-Ion are popular because of their high power density. There’s a reason why almost all consumer devices right now use it - it’s well-known and safe enough if treated well.

LiFePo4 has an advantage in lifespan (more charge/discharge cycles) and operating temperature range. However, its biggest advantage by far is it has more stable chemistry, and can take much more abuse without going up in flames. See that stability in action in this video:

LiFePo4 support means users that want to trade off the power density for more safety have that option.

Some other UPS’s already do this, with the UPS connected via pogo pins. I thought it was a good idea so I’m also doing it for PowerUPS. Mounting under the Pi means that it won’t interfere with other HATs - especially cooling solutions. 

Most existing Pi UPS’s have their own USB connectors, and ask their users to use that instead of the Pi’s USB connector. While this is no big deal most of the time, the biggest reason why I want to still support using the Pi’s USB connector is the use of gadget mode. This is especially true on Pi 4 and onwards, where the USB input  also has data, and can be configured such that the Pi can act as a USB device. If the UPS advises users to not use the Pi's USB connector, then they can't also use gadget mode.

Initial Design

Components Selection

Here, I went with the BQ25622E, which is a higher max charging current version of the charger IC used in the ESP32-S3 PowerFeather,  the BQ25628E (3 A vs 2 A). Other than that, the footprint, registers, functionality and behavior seems to be mostly the same so I can take advantage of the existing circuit design and SDK code for the PowerFeather.

The LC709204F in the ESP32-S3 PowerFeather is great but it doesn’t support LiFePo4 - which we aim to support with this board. There doesn’t seem to be too many fuel gauges that support this chemistry, which might be due to its super flat voltage curve:

I was able to find one though: the MAX17260 from Analog Devices. Its datasheet says it supports LiFePo4. It combines both OCV estimation and coulomb counting, which should help with the aforementioned flat voltage curve. However, we’ll still have to see how well this works.

Like the LC709204F, it supports not just charge estimation, but also health, time-to-full/time-to-empty estimation; as well as the other features such as alarms, compensation for battery temperature/age/load, etc. Since this has coulomb counting, this can be used to more precisely measure battery charge/discharge current than in the ESP32-S3 PowerFeather (uA vs mA).

LiPo/Li-ion is 3.7 V nominal, LiFePo4 3.2 V. But the Raspberry Pi needs 5 V, so we need a boost converter. Since the primary targets are Pi Zeros, we should take a look at what Raspberry Pi themselves recommend for power supplies:

As expected, among the Pi Zero’s, the 2 W is the most power hungry, so it makes sense to target that as the minimum output current. But, if you look at the table, even though the full-sized Pi boards require at least a 2.5 A supply starting from Pi 3B, the bare board active current consumption is much less. It’s the USB peripherals that can increase the current consumption drastically. So even if the PowerUPS is targeted towards Pi Zero’s, it should be usable with the full-sized Pi boards as long as the connected USB devices are kept under check.

Ok, so the target output current is at least 2 A. But there is one more potential limiting factor, and that is, how much the charger IC can output to the 5 V boost regulator. The relevant specs are in the BQ25622E’s recommended operating conditions:

First is the output current I(SW), which is 3.5 A, which comes from the bucked down external DC source. Assuming the lower nominal voltage of a LiFePo4 cell and 90 % efficient boost converter: 

0.9 * 3.2 V  * 3.5 A = 5 V * x
x = 2.02 A

Just barely within the target. But I think this shouldn’t be too much of a problem, since with the BQ25622E, the battery can supplement this, with continuous discharge current of 6 A and peaks of 10 A. Doing the similar calculations, it’s very much sufficient, I think:

0.9 * 3.2 V  * 6 A = 5 * x
x = 3.78 A

The boost converter I landed on is the FAN48623 from Onsemi. It's a 5 V, 2.5 A boost converter which is even higher than the target current. Plus, It’s super efficient, at least according to the datasheet (between 90 - 92 % efficient when input voltage is 3.2 V and output 5 V @ 2 A):

There are other boost convert similar in efficiency and output capability, but one thing that made me choose this was a built-in bypass mode. I thiink this could be handy in terms of power saving when the Pi is shutdown, since I don’t plan on creating another power rail for the control circuitry.

As I mentioned previously, I didn’t want to create a 3.3 V rail for the control circuitry. Also, I wanted to be able to control and monitor devices on the 5 V rail (such as MOSFETS and sense resistors), so I decided on using a 5 V capable microcontroller. 

I came across the AVR DB microcontroller family from Microchip, with an interesting feature: MVIO. The microcontroller supports a 2nd IO voltage domain, kind of like having a built-in level shifter. This comes in handy, since the Pi communicates with 3.3 V logic level, but I wanted the rest of the circuitry in 5 V. For that, I don’t need extra ICs.

The AVR CPU of course is not very powerful, but for this application processing power is not necessary. This microcontroller is basically there to act as a middleman between the Pi software and the charger/fuel gauge, and to do some digital / analog IO.

Also, I’m not sure yet, but I might base the firmware on Arduino DxCore + PlatformIO to make it extra hackable (especially since MPLAB X can be a pain).

Other Notes

The following is a simplified illustration on how I want to try and handle switching between the 5 V output from the boost converter and the USB input.

When no USB 5 V is present, the ideal diode is conducting. This induces voltage across the sense resistor which is detected by the microcontroller, which turns off the load switch to the charger IC.

Consequently when USB 5 V is plugged in, the ideal diode stops conducting, reducing voltage across the sense resistor which the microcontroller again detects and turns on the load switch.

SPICE simulation with the ideal diode controller, NCV68261, and the NMOS seem to indicate that this should be able to work, but I guess I would find out with the first prototype.

For faster response, turning on/off the load switch based on the sense resistor voltage will be done asynchronously with a combination of:

The 5 V USB input to the Pi should also be protected, in cases where the 5 V boost converter output is higher than it. Part of the design is a small separate board that incorporates the same ideal diode circuit used at the 5 V boost output stage above.

Imagine a case where a battery is about to run out, the Pi is shut down, and the ideal diode is turned off (the NCV68621 has an enable pin). According to the FAN48623’s datasheet, its quiescent current can get up to 140 uA if boost is enabled. But with bypass, it should effectively short the boost input and output, and the boost circuitry can be disabled, resulting in a quiescent current of 6 uA. This enables the UPS to wait for a longer period without external supply.

Furthermore, in this situation, the voltage can be as low as 2.4 V. Fortunately, the AVR DB microcontroller can run down to 1.8 V - enabling it to detect a safe voltage where the battery is charged enough to turn on the Raspberry Pi.

Closing Notes

As mentioned, KiCAD schematic and layout GitHub repo is linked in this project. so please check it out.  I will be waiting a few days before I submit the design to Elecrow (which also manufactures ESP32-S3 PowerFeather) to see if people can find mistakes in the design, or *I* find mistakes after looking at it with fresher eyes.