A PewPew shield for the TinyPICO

Similar projects worth following
This add-on turns your TinyPICO ESP32 development board into a tiny MicroPython-powered game console compatible with the PewPew family by @de∫hipu. Program 8×8 pixel games using an extremely simple API!


  • First Assembly

    Christian Walther09/14/2019 at 20:38 3 comments

    I assembled the first PicoPew today, and it worked on the first try! That made me happy. The only thing that didn’t work right was that I had the X and O buttons swapped, which was a simple fix in the software since the GPIO assignment is arbitrary.

    Soldering the 0.5 mm pitch eTQFP chip with a soldering iron and solder wire worked acceptably once I found the desoldering wick to remove excess solder stuck between the pins, even without additional flux (I thought there was a flux pen at the FabLab but there wasn’t). Still, for the next try I am going to buy solder paste and use the hot air rework station or ask colleagues to borrow a reflow hotplate or oven.

    Soldering the buttons worked much better than I had feared, it was no problem at all to get them down without shorting the very close solder pads in the center of the d-pad.

    The matrix with the bent pins worked acceptably too, but the outer holes are really close to the ones for the pin header and I accidentally filled two with solder while soldering the latter. Also, with the header covering about half of the holes, first inserting the matrix and then soldering it without leaving too large molten marks on the plastic was a challenge. I wonder if there is any way I can make this easier to assemble. I can probably move the holes 0.1–0.2 mm further out, that might help, even though it requires more bending.

    What gave me most trouble was actually the female pin headers. Their pins just wouldn’t take on solder properly, even after scraping them with a knife and with sandpaper. They seem to make good enough mechanical and electrical contact now, but I’m a little suspicious. It occurs to me now I could have tried the stackable ones that came with the TinyPICO, maybe they would work better.

    With the standard-height headers, the whole thing gets really thick, and there is space for more than two of the LiPo batteries inside. I should look for shorter headers, like the ones Adafruit sells for the Feather boards.

    I still need to add the battery, and then I’ll play with it for a while to see if it’s comfortable to hold or anything else needs improvement. I suspect it will be less comfortable to hold than the PewPew Lite FeatherWing, which has a somewhat well-defined box shape because the Feather board has the same dimensions as the shield in front, whereas on the PicoPew there are many edges and protrusions on the back.

    Other observations for revision 2:
    • The holes for the pin header and battery could be a bit larger, the header pins just barely fit, and when you accidentally fill a hole with solder, it’s very hard to get it open again with the suction pump and desoldering wick.
    • The holes for the vias can be smaller, it looks like my specified diameter was rounded up to a larger drill bit, and there is now very little annular ring remaining. They are also larger than I have seen on other OSH Park boards.

  • PCB Layout

    Christian Walther09/10/2019 at 20:20 0 comments

    With the prototype circuit working, it was time for the interesting part: PCB design! I planned to use EAGLE for that, I had used it before and had gotten somewhat familiar with its quirky user interface. I had version 7.5 installed, which was from before the acquisition by Autodesk, and didn’t bother checking if they had managed to ruin it yet in newer versions. Someday I should, but then I also resolved that for some future project I’m going to try KiCad and see if it’s any more or less capable and compatible with my brain.

    The main challenge in the basic layout was posed by the fact that the spacing between the outer rows of pins of the LED matrix was pretty much the same as that of the TinyPICO, meaning that I couldn’t put them exactly on top of each other. I didn’t want to offset them sideways either however because that would make the board larger, and I was really trying to get it no wider than the LED matrix, 20 mm. A promising idea came in the form of @de∫hipu’s #Matrix Sanitizer, where he had rotated the two layers of pins by 90° relative to each other, which made them interlock perfectly, although with very little space left for pads. These were both on a 2.54 mm grid though, and my matrices had a 7.5 mm by 2.4 mm grid, which didn’t fit between the TinyPICO’s 2.54 mm pins at all. However, since I had found that the matrices could be crammed into a 2.54 mm grid with some force to bend the wires, what about bending just the outer 6 pins into the 2.54 mm grid and leaving all the others on the 2.4 by 7.5 mm one? That worked beautifully on the screen, and it even let me run a trace between the pads on the inside of the TinyPICO pins, which wouldn’t have been possible with all matrix pins on the 2.54 mm grid, but turned out absolutely necessary. How well it works mechanically with the actual matrix remains to be seen when the PCBs arrive.

    I proceeded with placing the ISSI chip and wiring it up to the matrix, which turned out harder than expected: The pin row of the matrix closest to the chip caused a bottleneck, acting like a fence through whose gaps a lot of traces needed to go. When using 8 mil traces, I could run two of them between each pair of matrix pins on both sides, except for the outermost ones, where only one would fit because a TinyPICO pin was in the way. That gave me space for 24 traces – just barely enough for 16 matrix pins, 2 I²C lines, 2 buttons, and 2 power lines if I made those 20 mil wide. Whew!

    After several iterations of nudging the ISSI chip around to get it farther away from the corner of the board so I could round off more of it, and the corresponding twiddling of traces between the matrix pads, I had a rough layout that satisfied both the design rule check and my desire to squeeze things neatly together for the tiniest board outline possible. It consisted of the usual 45°-angled traces, placed by hand somewhat irregularly because of the different grids involved. That I was not happy with, I want my traces curved, not angular, aligned to the environment, not to an arbitrary grid, neatly curving around obstacles and regularly spaced where several run in parallel.

    So, a final round of prettification started. EAGLE’s tools however turned out severely inadequate for that. Maybe not surprising, because this is work that no engineer working on a commercial product would do – but I have the luxury of being a hobbyist, here to spend more time on it because I’m having fun, not less because it costs money. What to do? As always, make your own tools.

    EAGLE can be extended with so-called ULPs (user language programs), and learning how to do that was an interesting experience. They are written in a C-like language that is easy to pick up using the documentation, but the system is very awkward because these programs cannot modify the internal data structures of the document, to bend or add traces as I wanted. The document tree is read-only, and the only thing the program can do to modify...

    Read more »

  • Power Consumption

    Christian Walther09/08/2019 at 21:30 8 comments

    One of the nice features of the IS31FL3733 LED driver is that it has separate power supply pins for various parts, which allows running the I²C communication at a different voltage than the LEDs. I could therefore leave the communication at 3.3 V as required by the microcontroller, but connect the LED drivers directly to the battery at up to 4.2 V, which means the LED current would not have to go through the voltage regulator of the TinyPICO and part of the power be dissipated as heat there. Would that allow me to save power, a desirable thing when planning to use a battery as small as a 100 mAh LiPo? I took some measurements to find out.

    In the final series of measurements, I powered the TinyPICO through its BAT pin from my bench power supply at different voltages – simulating a battery at different charge levels – and measured the total current there, with all LEDs fully on, but with different global brightness values, and with the power pins of the LED driver connected to either the BAT pin or the 3V3 pin on the TinyPICO. As a brightness reference, I used a PewPew Lite and adjusted the global brightness on the prototype until their brightnesses visually matched.

    The results were not what I initially expected, but in hindsight completely explainable: It made no difference at all to the total current consumption at the same brightness whether the LED driver was connected at 3.3 V through the voltage regulator or directly to the battery. The current was constant independently of the supply voltage (once the voltage was high enough to actually reach that current, which except at the highest brightness setting generally happened earlier than the ESP32 would even run), varying from 50 mA at the lowest brightness to 350 mA at the highest. The brightness would not vary with the supply voltage, the match with the reference PewPew was always at the same setting. In other words, the additional power available with the higher voltage did not make it into light as I had hoped, but was dissipated somewhere in the driver chip or in the LEDs themselves.

    Thinking about it afterwards, I realized that this was exactly the way it needed to be. The average current through an LED needs to be held constant not just over various numbers of LEDs being on, but also over various supply voltages, because on a power supply with a nonnegligible internal resistance, the voltage will automatically vary with the number of LEDs being on, and we do not want the brightness to vary then. Also, since the brightness of an LED is approximately proportional to the current, its power efficiency decreases with increasing voltage, and it is not beneficial to run it at a higher voltage but lower PWM duty cycle.

    Another effect of connecting the LED power to the BAT pin is that when the system is running without a battery, powered from USB or the 5V pin, the LEDs are powered through the battery charger. It turned out that the charger was very confused by that load that didn’t act like a battery and would sometimes deliver little current and sometimes a lot, resulting in a randomly shifting display brightness.

    In conclusion, since there was no power consumption advantage to connecting the LED power directly to the battery, but a disadvantage in the case of running without a battery, I decided to connect it to 3.3 V along with the logic power. This would also make the circuit simpler, and the voltage regulator of the TinyPICO, rated at 700 mA, should take it easily.

  • Adding Buttons

    Christian Walther09/07/2019 at 16:18 0 comments

    Meanwhile, my TinyPICOs had arrived, and the picture shows one driving the prototype. With the wires going to the breadboard on the left, connected to one unused row output on the green PCB and two column outputs at the matrix, I was testing whether I could use the open/short detection feature of the ISSI chip to read buttons. It worked in principle, I could detect from the software whether the wires were connected, but unfortunately a scan resulted in a visible flash of the display, either dark when set to the minimum current as recommended, or bright at a higher current. I therefore concluded that this was not a practical solution.

    As alternative solutions for connecting the buttons, I considered using some IO expander chip or a second microcontroller such as an ATtiny. With the latter, I would also be able to offload the latching feature of the PewPew key reading API from the main microcontroller (it remembers which keys have ever been down since the last check, no matter how briefly). Either would be connected to the same pair of I²C pins as the display driver and thereby leave lots of other GPIOs available for other uses, such as maybe a 12-pin PewPew Standalone connector. The disadvantage, on the other hand, would be the space needed on the board for at least one additional component, which might compromise my goal of making the device as tiny as possible.

    In the end, I decided to just use ESP32 GPIOs for the buttons – the TinyPICO had enough of them, and I was unlikely to need them for anything else. If I left DAC1 and GPIO4 open, it would still be possible to connect an official TinyPICO audio shield, for people who want their games to make noise. (I usually don’t and am happy with the lack of sound in the PewPew standard.)

    I had bought some tiny buttons from Mouser, with a rectangular package, a relatively large cap that is still comfortable to push with bare fingers, and a nice clicky feel. The same size was used in the PewPew Lite for D1 Mini. I experimented with several arrangements and settled on one where the directional buttons are arranged in a cross, visually emphasizing their meaning. It uses a little more space than the most compact arrangement possible, but assuming that I would arrange the buttons to the left and right of the display, as in the FeatherWing, my preferred arrangement, I would have that space. Whether to choose that arrangement or the Gameboy-like arrangement below the display as in the D1 Mini shield would be decided later based on what was easier to achieve in the PCB layout.

    Radomir later also graciously gave me two of the impressively small D1 Mini shield PCBs. After populating them (including working around some design flaws where he had pushed Fritzing to its limits), I could test that arrangement and found that the buttons were a bit too close to the display, and the two groups a bit too close to each other, for me to comfortably use with two thumbs.

    For my prototype, I soldered six buttons in my chosen arrangement onto a corner of an upside-down perfboard (luckily they fit well onto its 2.54 mm grid) and attached wires that would go into the breadboard with the TinyPICO.

    With this, all the hardware for a fully functional PewPew was in place, and of course I couldn’t wait to also get the software ready. I started from the MicroPython pew library for PewPew Lite and replaced the display and key functions by ones suitable for my hardware. I used pin interrupts to read the buttons and at first only looked at which pin triggered the interrupt to recognize which key was pressed. This however resulted in some occasional crosstalk between keys: sometimes, pressing one key would register as a simultaneous press of that key and one of its neighbors. I do not know whether these spurious interrupts were caused by inductive coupling between the parallel wires or by something inside the microcontroller. The problem disappeared when I, inside the interrupt handler, actively read...

    Read more »

  • From Idea to First Prototype

    Christian Walther09/04/2019 at 20:10 0 comments

    Impressed by the engineering that went into them, the first-class MicroPython support, and the sheer tininess, I had ordered some TinyPICO ESP32 development boards from Unexpected Maker’s CrowdSupply campaign. But what to actually do with them, other than sinking them into the drawer of cool but eternally unused microcontroller boards? In the weeks before EuroPython 2019, with my head full of PewPew as I was going to help @de∫hipu run PewPew workshops there, the answer was obvious: Make a PewPew shield for them! I had never designed a PCB more complex than a bristlebot kit, so this might be a nice exercise, not totally uncharted terrain but not without challenges either.

    The easiest way of doing this would be to copy the circuit of the PewPew Lite FeatherWing. The problem with that is that the Holtek HT16K33 LED matrix driver used there only exists in a relatively large SOP-28 package. It fits between the pins of the Feather, but not between those of the TinyPICO (and not those of the LED matrix either), making it impossible to build an appropriately tiny device with it.

    Looking for alternatives, I turned to @de∫hipu’s excellent article and was intrigued by the ISSI IS31FL3733 that he had also used in his PewPew Pro. It comes in an eTQFP-48 package that is reasonably small but hopefully still within my soldering skills. Beyond the capabilities required for a PewPew, it would offer 256 shades of brightness for each individual LED, multiplied by 256 levels of global brightness. It however lacks the key scanning feature of the Holtek chip, but I wondered whether its capability of detecting shorted LEDs could be misused for that. So I ordered some of these chips from Mouser.

    For the LED matrix, I was thinking of using the same 20 mm red/green one as in the PewPew Lite, which I much prefer to the monochrome displays of PewPew Standalone devices, because the colors are easier to distinguish. 4 shades of the same color have advantages too, such as allowing antialiasing, but with the ISSI driver I would get the best of both worlds. I briefly went looking for even smaller bi-color matrices, or RGB ones of the same size, but could not find any. When the KYX-788AHG ordered from AliExpress arrived, the first thing I noticed was that, just like on the ones I had gotten from Radomir on PewPews, their pin spacing was not actually 2.5 mm as specified, but around 2.4 mm instead, making them hard to squeeze into 2.5 mm (or even 2.54 mm) holes. The larger spacing of 7.5 mm was accurate though.

    To test my understanding of how to use the ISSI LED driver, I mounted one of them on an adapter board and wired it up to a matrix and to an ESP8266 Feather HUZZAH board running MicroPython. Figuring out how to control the LEDs that way was not hard with the help of the data sheet and the MicroPython REPL, but I ran into two problems:

    1. One of the LEDs would always stay off, the green one in the upper right corner. The LED itself was fine, it could not be the wiring because that would affect whole rows or columns, and an off-by-one error in my code could be ruled out because the way I assigned rows and columns, the respective bits were located in the middle of the buffers, not at the edge. I finally concluded that I had probably fried some memory cell with my clumsy soldering, but I was unable to figure out whether it was in the LED On/Off bitmap or in the PWM buffer, because the registers are write-only.
    2. Whenever I turned on too many LEDs at once at a certain brightness, the chip would just reset, turning the display black and requiring me to redo the whole initialization sequence. The numbers were somewhat random and varied with whether I supplied power from the 3.3 V or 5 V output of the microcontroller board or from a bench power supply, and there was also no clear pattern to how much current I could draw before the reset – but in all cases I was never able to turn on all LEDs at full...
    Read more »

View all 5 project logs

Enjoy this project?



davedarko wrote 09/05/2019 at 09:47 point

  Are you sure? yes | no

Christian Walther wrote 09/05/2019 at 11:30 point

Hmm, nope, spelling it like that in the description and log doesn’t seem to turn it into a link either. Help?

  Are you sure? yes | no

davedarko wrote 09/05/2019 at 12:43 point

there should pop up a helper with his profile picture, that's how I got it to work

  Are you sure? yes | no

de∫hipu wrote 09/06/2019 at 10:48 point

Description is dumb, I use the Details instead, it's a bit smarter.

  Are you sure? yes | no

Christian Walther wrote 09/06/2019 at 11:41 point

Interesting, now it works in the Details and Logs editor. Maybe I wasn’t waiting long enough for the popup. In the Description it really doesn’t seem to be supported. Thanks for the hint!

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates