This is the story of the evolution of an uninterruptible power supply for the likes of Raspberry Pi etc. It takes over where various posts about UPS leave off, the last (detailed) entry being “The Dog’s Breakfast” – in the search for a low-cost UPS and for individual micro boards and having been less than happy with much of what is out there. The latest video on this is on Youtube.
The current design has a number of advanced features for a simple, inexpensive UPS - the software incorporates:
- Programmable delays for everything
- Programmable high and low trigger voltages (hysteresis)
- Programmable (piezo) warning alarm (default off)
- Programmable JSON serial state and voltage monitoring
- Programmable voltage correction for component tolerance
- Variable shut-down period with auto-recovery
- Battery voltage automatic logging and OLED graphing
- Variable watchdog timer 1 minute to 255 minutes
- Optional temperature sensing/monitoring and warning
- Low(er) current display on standby
- Simple graphical voltage monitor
- Much cheapness
The hardware is in a state of flux, the design you see above uses a combined Lithium charger and voltage booster. Also looking at a separate charger and dual booster circuits – this is a matter of detail to get a good combination of charge and output. See at the end of this blog entry.
The first attempt
Here is what it COULD look like, we're putting a prototype together but we've already found other uses for some pins so this won't be the last – good job boards are cheap! Aidan put this little number together…
In the prototype, in addition to the charging and buck boost boards, an Atmega 328 board is used (Nano-type board with as low current as possible) and an SSD1306 display (in this case 128px by 32px), a MOSFET and 2 resistors. The most expensive (if you can call it that) items being the battery and display. The display is an SSD1306 32 pixel display. Beware of some UK traders charging laughable amounts - they should be under £2.
I did look at using a graphical library with this – but the only fast one I could find at first was the U8G library and the strange thing about that is – their now defunct original library did a pretty good job of driving these displays – but the one they want you to use now, the U8G2 library – uses up nearly all the RAM on a 328 ON IT’S OWN without any other code… so that went in the bin. Since then I’ve discovered this - http://www.arduinolibraries.info/libraries/ssd1306 and a full graphic demo takes 316 bytes of RAM and 21% of program space – however as it turns out that too had it’s issues – to be fair I wrote in and issues with rectangles and fonts were fixed within days – so I did some good.. eventually however I went back to the original text-only library for reasons I’ll explain later.
In this version there is a 3V7 Lithium battery under the board, a 18650 would do as well. Currently using typical TIP4056 charging board and typical MT3608 voltage booster board, all of which are dirt cheap on AliExpress or even Ebay.
Look at the previous blog entry (“The Dog’s Breakfast”) for details of current hardware all of which is widely available.
I thought it might be nice to have a little graphical display simply showing a log of the battery state over X amount of time. Well, that went from a simple idea to a major waste of time.
Being used to the ESP8266, I don’t worry too much about RAM other than program RAM. A few hundred bytes is neither here nor there. On the Arduino Nano and Uno type boards however it is a lot. With only 2k and with libraries and variables eating into that, you tend to want to keep RAM usage to a minimum.
The SSD1306 chip has an issue in that it is not that easy to READ the internal RAM buffer. So in order to allow arbitrary text and graphics, most libraries maintain a buffer, which in the case of the 128*64 display is 1K bytes and obviously for the 128*32, half of that. This makes a significant DENT in available RAM.
Because of that, I’d originally adopted (and went back to) the ssd1306Ascii library which handles text only. The reason for that is it manages without any buffer, writing directly to the SSD1306 chip. Characters must be on a byte boundary vertically.
I noticed another library which promised low RAM usage and discovered it had PIXEL operations – lovely – except after wasted hours I discovered that in fact there were no miracles – unable to read the state of a RAM location inside the chip – the minimal library offering wrote the pixel required ok, but wiped the adjacent pixels in that vertical byte.. and the point of that? I wrote to the author who suggested I use the buffered version – and guess what – yes, that used a BUFFER.
With my only hope of graphics without eating up much of my RAM gone I went back to the original ASCII only library ---- then it hit me.
The routines for drawing text (discuss here the 32 pixel high display – but the same applies to the larger one) write the character on vertical byte at a time. It occurred to me that if I built up the screen from left to right, putting a bit value into a 32-bit integer – along with any border information, that I could build up a graph complete with border, while using only the 4-byte word – and of course the buffer I use to store data.
And it worked.. and the code online is updated. Forgive the state of the display – I’m keeping the protective cover on it until I’m finished experimenting. I’ve updated the list of features at the top – I have two of these sitting on my bench being tested and up to now, well, I think we have a winner - I just need a decent beeper to test the alarm feature – and they’re on the way from China.
So at this point you may be asking - but what about temperature sensing - well my assumption here is that whatever battery is used will have protection built in - however as I needed it elsewhere I added an optional temperature sensor.. D11. As I had a DHT22 handy I made that temperature and humidity toggling back and forth on the display - and why not – though a Dallas chip would probably be more appropriate and vertainly a hell of a lot smaller. Here's the library - some good unrelated stuff also in there. If you don't fit the sensor, nothing shows - so like the beeper it is entirely optional (and in most cases utterly un-necessary). For now all it does is sound the alarm if the temperature is valid and gets to be over 40c. That value was entirely arbitrary.
The beeper is on D12 but experiments with a piezo element yielded the most pathetically quiet beep so I'm now waiting for one of those little black speakers to turn up.
Along the Way
In the process of experimenting, many different boards were tried out and several finished products – the PIZ-UpTime being one of them. Initially supplied by Pimori, I supplied this board with a 3.2v Lithium battery - of course I had no idea there were two types - 3.2 and 3.7v. Without plugging the board into power, I attached the battery, at which point the board got very hot as did the battery. I contacted Pimori who said that this was because of the wrong battery - which is nonsense as the board has to handle a flat 3v6 battery. Anyway, I sent the board back, they did send me the correct battery which was nice of them and a replacement was supposed to come out and never did. Thankfully the designer, Percy Kawas of Alchemy Power stepped in and sent me a replacement board.
This works well, in that it plugs into a Raspberry Pi Zero and not only provides power to it but also offers a signal to GPIO26 to allow the Pi time to shut down before the battery gives up in the absence of power.
And that is good - but the board does NOT handle some situations - for example once the power signal has been sent to the Pi, if the power actually returns, we have a shut down Pi with no way to resurrect it without pressing the reset button. Not a lot of use if you are not there.
Alchemy Power also do a board suitable for a Raspberry Pi 3 - this is an altogether more meaty job with two batteries...
When I first looked at this board, it seemed that you had to press the reset button if the battery when flat and subsequently recovered - however it seems that the site text is now reworded, if you read the link above it indicates that the unit WILL survive a flat battery. I'll test that at a later date.
One of our readers pointed me to this MP2636 Power Booster and Charger Module, which could be added to the Atmega and make something with a little more power. The claim for the latter is 2.5 amps charging and 2.5 amps output – though I doubt both at the same time.
Meanwhile Aidan and I have progressed with our own (non-commercial board. However, the version you see below has some issues with the PCB – mainly by the time we got the board we’d thought of better ways to do things and decided that two batteries were overkill mainly because of size. The next iteration will have a Raspberry Pi shape so as to be compatible with cases for that computer – and as we know, RPI cases are very cheap.
Well, there is is up to now – software is online for anyone wanting to experiment and the principle is simple enough. Do check the video (link at the top of this blog).