An ARM microcontroller board with built-in battery and power management, all in a compact package that fits in your pocket.
Why? I've built a lot of wearable lighting projects and got tired of wiring together the same 3 parts: arduino, charging controller & battery. They always felt janky and flat lipo batteries can explode if they get damaged (especially if you're wearing it!). I wanted something compact, rugged, and could pump out enough current for a lot of blinkenlights without any additional parts. What I've ended up with is this little beast with 4 onboard PWM MOSFETs, each driving up to 2.3A per channel!!! Develop your project faster with onboard LEDs attached to each PWM output which lets you test and play without wiring anything up.
The controller should have everything you need on a single PCB: MCU, battery, USB, charger, buttons, and LEDs for status and debugging.
It needs to easily fit inside a pocket or in the palm of your hand.
You should be able to throw it around without much concern for damage. The problem with the typical lithium pouch cell batteries, is they will explode if they get bent or punctured. This project will use a cylindrical lithium battery so it can take some abuse.
This will have 2 buttons: One satisfying on/off push button and another tactile momentary button which can be programmed to do anything (i.e. cycle through modes).
On most LED controllers, the single button for both power and mode selection is horrible! To turn it off, you either have to press and hold for an undetermined amount or cycle through all modes to get it to stop blinking. Not a very good user experience at all.
This is a prototype I've been working on for a couple months now. With all the same features as the main ThunderPack board, but much, much smaller! (40mm x 19 mm)
It also has an on-board 16Mb flash chip and a DotStar status LED. (both of these are also getting added to the next version of the standard ThunderPack board).
Due to it's size, I did have to drop a couple things:
Individual physical LEDs on the PWM outputs.
USB ESD protection.
This board is perfect for wearable applications that need to be lightweight.
I've been building this prototype into a leather choker, similar to this Adafruit's Tutorial, for a friend. However, in my version the board is truly integrated with the choker with the switch poking through a slot in the leather and the LEDs mounted to a custom flex PCB from OSH park. I'll post pics and more info soon.
I'm playing with a couple more prototypes for the next version of the board. Here are some of the things I'm thinking about:
On-board flash memory: The base STM32 chip has about 512kb of memory, but CircuitPython uses most of this for the runtime. An external flash chip will allow larger CP programs or it can be used for logging or to create a USB MSD.
I have an open PR to boost the user program flash memory a bit for the current board.
New flat board with external battery: The original form factor works well in many cases, but sometimes you need something flatter/smaller. I'm working on an alternative form factor which uses an external battery. It should retain the same basic features.
Flexible LED PCBs: Loosely inspired by Adafruit's LED Collar, I've been playing with flexible PCBs from OSHPark to make DIY LED strips that mate directly with the thunderpack board. This has some great wearable applications.
Shorter Board, Same Power: Using a new switch I found on Aliexpress, I can reduce the length of the standard ThunderPack board by 4.5mm (~1/4 inch)
Stay tuned, I'll be posting more soon about these ideas.
It took awhile to get here but the new STM32F411 chips are working really well!
It has been so interesting to see how COVID has affected everything in such real ways. I say this because, most things come and go but don't really have this kind of Hollywood movie effect. So to see something stop so much is truly staggering and I'm in awe. (I'm also in week 2 of quarantine in San Francisco, so I might be a bit loopy).
I find my self comparing how surprised people are about COVID19 to climate change. People didn't expect a worldwide pandemic to actually happen...and here it is. So many people refuse to believe climate change can happen...but it's here and is happening; whether you believe it is or not.
All that to say, I placed PCB orders with DirtyPCBs and OSHPark in min February and it took about a month to get to my door. Longer than expected, but totally reasonable considering the circumstances.
It also meant that my trip to the Open Hardware Summit was grounded and I attended virtually; just like everyone else.
Bare PCBs to play with!!!
My goal with this batch was to get CircuitPython running on the boards. So I ordered 2 chips to try: STM32F412 and STM32F411. The F12s come with as much as 1Mb flash while the F411s top out at 512Kb. I know CircuitPython takes at least 256Kb of flash, so I wanted to test the chips side-by-side. Would 512Kb be enough space to load both the CircuitPython runtime and user programs? (It turns out all STM chips seem to be limited to 48Kb for user program space - source).
The STM32F411 had plenty of room and ran CircuitPython really well. It's also a couple dollars cheaper and is way more common; so it's the clear winner.
Officially on CircuitPython!
I have to say, the CircuitPython engineers are phenomenal. I had a few issues getting the boards working and the devs on their discord server were super responsive and helped me out a lot.
Along the way I was even able to contribute a general fix back to the codebase and add non-volatile memory (EEPROM emulation) support to the library for the STM line of chips.
I'm now excited to say that the team behind CircuitPython have accepted my PR and Thunderpack is an official port in their repository!
Arduino on the way
I have a Github PR open with the stm32duino team to add the new version of the board & chip to their project. Hopefully that'll be added in their next version.
Next - Update Examples
Now that the big things are out of the way, the next step is to update all the existing examples, add CircuitPython examples and get a new round of boards. Unsurprisingly, the WS2812B/Neopixel examples are giving me some grief (The DMA to PWM code always seems to cause trouble). I'm hoping to get that all sorted this week.
The goal of ThunderPack is to be accessible to beginners and experts alike. With that in mind, CircuitPython seemed like an important thing to include. Only one problem...the chip I chose will not work for it.
Why? STM32L072xx and CircuitPython
I liked the STM32L07 because it's small, low-power and has integrated EEPROM. The only problem is that CircuitPython requires ~50KB of flash to work as expected*, and the STM32L072 only has about 128KB.
* you can technically get CircuitPython/MicroPython to fit inside 128KB, but it doesn't include the USB mass storage device firmware loader or the REPL. In my opinion, this removes the two most useful things of CircuitPython -- so why bother.
Upgrade to STM32F4xx with big flash and speed boost!
A great thing about the SMT32 line of chips is how they attempt to maintain pin compatibility between families. Which means we can upgrade ThunderPack to the STM32F4xx chip, which packs a whopping 1MB of flash space and can run up to 100Mhz, without significant changes to the board.
It's pin-compatible, but unfortunately not a drop-in replacement because the chip footprint itself is a little bigger (7x7 vs. 5x5). I had to rearrange a few things but was able to keep the overall form factor and pinout the same. I will also need to update the examples for this chip and the Arduino core.
Feel free to follow along the process in the STM32F4 branch on Github.
As the board is finally in the more production-ready phase, I'm collecting ideas for what people would do with ThunderPack. Share your ideas in the comments!
Open Hardware Summit
I will also be going to the Open Hardware Summit in New York in March and hope to have a handful of these boards with me to give away.
While talking to friends about the projects they wanted to use ThunderPack for, I realized that the 18650 battery size might be a bit big for smaller projects. So I took the design and shrunk it to two smaller battery sizes: 14500 (AA) and 10440 (AAA).
The real downside to the smaller batteries is power. These are the maximum ratings I've found for cells with built-in protection:
Ultimately the 10440 is the least bulky, but also severely lacks juice for projects involving LEDs; however, it could still be useful for other projects.
ThunderPack needs to be accessible to everyone, so the next step is to get CircuitPython running on it. I've done a little work on this already and it's clear I'll need to make some hardware changes to support this. More details soon...
Open Hardware Summit
I'll be flying to New York for the Open Hardware Summit in March and I'm planning to bring a handful of these boards with me. This will be my first time at a hardware conference, so I'm very excited and not sure what to expect.
It's official, ThunderPack has been added to version 1.8 of the STM32 Arduino Cores project! This version hasn't been released yet, but support for ThunderPack will conveniently be there for Arduino when it does.
I also have another PR open to remove the need to install outside software to flash programs to the board from Arduino. This update should also benefit all STM32 boards which support USB flashing via the DFU protocol. This also led to a pretty interesting conversation about the DFU protocol and potential enhancements to the dfu-util program itself.
More Bugs, More Prototypes
In writing the Addressable LED (WS2812B) examples, I found a bug with the board design...
Naturally, an addressable LED strip should be powered by the battery and the "Batt+" pin is connected directly to the battery. This all sounds good, right? Well, imagine this: You turn your board on, the program runs a lighting program to the LED strip, then you turn the board off. At this point the board stop sending new data to the strip, but the power isn't remove because it's directly connected to the battery. So, the strip continues to display the last pattern sent to it until you physically remove it from power. 🤦
The next version of the board (rev 5) will have a pin which provides power after the on/off button.
Of course I'm already thinking about what to do after the board is finalized. Here are the ideas I have running around my head currently:
MicroPython (or CircuitPython) support.
A version of the hardware built around the smaller 14500 battery (AA size). This would be for more compact projects and give up to 1A of power.
We're rounding the corner to a final product! I've been getting feedback from friends, creating documentation and prepping arduino support.
Pin out diagram
The real step to making something real and usable by others is documentation. And in my mind, the first tangible piece of documentation for a custom board is the pinout diagram. From there an intrepid maker can dig up datasheets as necessary to get things running.
I went through a few iterations of this because I wanted it to be easily viewable without scrolling (a vertical oriented board meant vertical scrolling on laptop screens). If the labels look familiar, I borrowed the style from the adafruit pinout diagrams.
There's still room for improvement (I'm not loving the angled labels), so if anyone wants to lend a hand or ideas, please let me know. (also the SVG file is also an inkscape file)
Another important step to making a board usable by others is platform support; notably Arduino. These days I run a little closer to the metal, but there's a lot of value in giving all makers a very accessible starting point.
The stm32duino project already provides arduino support for STM32 boards; however, I still needed to add Thunder Pack board configs to it. Luckily the stm32duino team (notably [fpistm]) have been very responsive and helpful with my pull requests. Along the way, I even found a bug with one of their binaries and am providing additional pull requests to cut down on the number of outside software dependencies necessary for an end-user to get up and running with any of their boards.
If I'm lucky ThunderPack will be supported by stm32duino 1.8.0! 🤞
Hardware Reviews & Feedback
A couple weeks ago I sent the hardware files to some friends who actually work in hardware design & development. Through that, they pointed out that I was missing some decoupling caps, my USB traces could be optimized for data line impedance, and a few other helpful tricks. This was incredibly helpful and also reassuring about the overall design.
The next step is to build a few more boards and hand them off to more friends for real-world testing.
The boards have arrived! I haven't assembled any yet, but everything is feeling a lot more polished.
Now that the boards are close to completion, I've reached out to some friends and asked them to give them a spin and put them through their paces. I'm excited to get their feedback.
If you're interested to be a beta tester, let me know and I'll help you get setup.
Now 100% more dongle & sewable
The new batch has a hole at the end so it can be hung from a carabiner and notches if it will be sewn to something. The dongle hole can be removes from the board with a pair of diagonal cutters, if it's unnecessary.
Debug Changes + More GPIO
When I moved from 4 layers to 2 layers, space got tight and I had to move the JTAG/SWD pins to the bottom of the board, under the switch (assuming you'd have the switch on top and the debug headers on the bottom). At the time I thought this was a clever way to save some space and keep the layout tidy.
While waiting for the new round of boards, I've been working on writing a decent WS2812B addressable LED example and have been using the debugging interface quite a lot. It's become clear that having the debug pins on the bottom means you cannot debug AND be on a breadboard; which is inconvenient.
So last night I rerouted things.
Now, instead of a dedicated JTAG/SWD block, the necessary 3 pins (reset, PA13, PA4) have been added to the GPIO rows. The happy side-effect is now the board has 2 additional GPIO pins to use!
Next Round of Boards...
I'm controlling my twitchy finger from ordering a new batch of boards with the latest routing. First, I want to build a couple boards from this batch, run them through some tests and get the WS2812B example working.
This is one of those projects that I've been casually working on for the past couple years. Every few months I pick it up, iterate on it a bit, and then put it away. Well, the past few months have seen a great deal of progress and I'm really happy with how far it's come.
In fact, I took one of the recent iterations of it to Burning Man and it survived the week in the harsh elements beautifully. Nothing beats some real-world testing.
Here's a brief rundown on what's been changing:
I've upgraded the MOSFETS to supply max 2.3A per PWM channel (there are 4 PWM channels!!! You know, so you can drive really big LEDs or just a long string of them. (however, you're still limited by the battery voltage)
The lithium battery charger IC has been changed to more than double the charging current from 500mA to 1.1A.
So Many Example Programs
II've been going crazy writing examples for the board across 4 different popular HAL libraries:
STM32Cube (Official STM32 HAL lib)
My goal is to have the same examples for each HAL (with some exceptions) so people can compare 1:1 how the libraries differ. It could even be a useful tool for people looking to switch from one library to another (maybe someone familiar with Arduino wants to get closer to the bare metal).
PCB: 2-Layer -> 4-Layer -> 2-Layer
Even though the overall circuit design isn't too complicated, it can be challenging to effectively route everything on such a narrow board. After reading Hackaday's article on 4-layer PCBs, I decided to give 4 layers a try. It truly made routing the PCB so much easier!
The only problem, though, is the cost. It's still twice as expensive as a 2 layer board, and even more with some PCB houses. For a prototype run, it averages out to $8+/board just for the PCB. Because I want this board to be economical and accessible to anyone, I've decided to switch back to the 2-layer design (although, I could be convinced to keep 4-layers).
The latest 2-layer redesign feels fine, however, I'm still a long way from from being a PCB designing expert. So if anyone is interested in taking a look at the latest iteration, I'd love feedback:
I was never really happy with calling the project "Lit Fist". It seemed to pigeonhole it as purely an LED controller. Even though that was the original goal of this project, it has been expanded to be much more than that. Now I see it as a general purpose battery-powered, ARM board with 4 high current outputs and 10 GPIOs. With that in mind, the name has been changed to "Thunder Pack". It still makes for a pretty awesome personal LED controller for wearable projects.
This morning I submitted an order for a fresh run of prototype boards with the new 2-layer design. Now comes the part that I hate...waiting for the PCBs (it's like waiting for Christmas as a kid). When they arrive and if they work as expected, we'll be at a place to call this project feature complete! Until then, I'll keep myself busy writing documentation and coming up with more examples. Stay tuned.