PewPew Mini

The smallest PewPew of all PewPews.

Similar projects worth following

The #PewPew Standalone is pretty much where I wanted it to be in terms of balance between size, simplicity, ease of use, functionality and, last but not least, price. However, if I sacrificed a little bit of convenience and size, maybe I could make something with more functionality and better price?

  • Ugh, Software

    de∫hipu2 days ago 0 comments

    I finally found some time today to actually flash the CircuitPython firmware on this device, and test it. Long story short, I will need another version.

    But let's start from the beginning. Some week ago a second order for the buttons finally arrived (the first one is still "on its way" after 2 months), so I assembled both the #D1 Mini UI Shield and this little device. But testing it requires making a new board definition for CircuitPython, and also burning the bootloader, so  didn't bother with that — only updated the photo on the project.

    Today I finally got to it. I had my J-Link out already, because I was re-flashing the bootloader on some older projects, so I quickly uploaded it to this one as well. That got me the energy to also copy and modify the board definition of that OLED board I was prototyping with earlier. Flashed it, copied the pew.mpy and the games, inserted the battery, switched on, and... InvalidPinError.

    Turns out the pins PA17 and PA18, despite being marked in the SAMD21 datasheet as supporting SPI, can't be used for SPI with CircuitPython. I'm not entirely sure why, to be honest, but I suspect it has something to do with one of the SERCOM peripherals being used for something else. And of course I didn't think about testing it before. Well, technically it's not a show-stopper, I will just need to pick another two pins, and there is a whole bunch of them free in there. In fact, I already amended the PCB design to use PA10/PA11, which I also tested to make sure they work:

    But that means a new PCB order, and desoldering/re-soldering of all the components, and I still don't even know if the coin cell battery is going to be able to power the thing with the display on, and it would be awfully nice to know that before I make yet another prototype (because then I could switch to a LiPO coin cell, and add a charging circuit). So what can be done?

    Bodging the wires doesn't look like a viable option with the QFN chip hiding under the hot-glued display. The pins are just visible at the edge, but I don't think I have such thin wires at hand, and the surface is too small to actually support a good attachment.

    I could attach wires only on the display side, and provide the signals that switch it on from some other microcontroller. But that is a lot of wires and work, and I just remembered about the bitbangio library, which lets you have software SPI on any pins. All I have to do is enable it to be included in the firmware, and add "import bitbangio as busio" to my library file. A bit of fumbling to restore the previous pin definition, and I have a ready firmware to flash. And... nothing. The device keeps restarting on the battery power. Yay.

    A quick swap of the battery to a rechargeable one, and lo and behold:

    So now I know I will need to squeeze that battery charging circuit in there somewhere. But I will leave that for some sleepless night.

  • Got PCBs

    de∫hipu05/16/2019 at 09:04 1 comment

    It took some time, but the PCBs are already here (USB plug for scale):

    I'm not sure I like the new style of mousebites from @oshpark — I can see how they save on drills, and it's probably also much faster, but I can't remove them with a knife anymore — I have to use a rotary tool. Then again, with the rotary tool it looks cleaner, so maybe it's not so bad.

    Also, looking at the number on the sticker, I think I might have missed a couple. Oops.

    I have now almost all the parts, except for the buttons — they are on the slow boat. Unfortunately, I used the buttons as jumpers, to make some of the GND connections and save on vias, so it won't work without them.

  • Looking at Other Displays

    de∫hipu04/27/2019 at 21:32 0 comments

    This week I'm paritcipating in Ludum Dare, trying to write a game from scratch in 48 hours, so not much time for hacking, but an interesting display arrived in the mail, so of course I had to give it a try:

    It's a STN 9664 LCD display, with an ST7585 controller chip, 96×64 resolution and a bonus row of icons along the top edge. The documentation is sparse, as usual, and I didn't yet get it to work yet with a quick attempt at it.

    Read more »

  • PewPew Pew

    de∫hipu04/25/2019 at 15:47 0 comments

    So the Pew library is now ported. It's still not as fast as on the other boards, I might need to rewrite it in C after all, but it's a good first step for testing.

    The heart of the whole porting effort is the function that draws those dithered pixels. It's surprisingly simple:

    _PATTERNS = (
    def show(pix):
        pix_buffer = pix.buffer
        display_buffer = _display.buffer
        index = 24
        for y in range(8):
            pix_index = pix.width * y
            for x in range(8):
                display_buffer[index:index+10] = _PATTERNS[pix_buffer[pix_index]]
                pix_index += 1
                index += 10
            index += 48

    Basically we have pre-recorded images of the pixels, that we copy into the buffer at the right places based on the image to be displayed. I also tested doing this on the fly while sending data to the display, and with a per-line buffer, but that didn't make it faster, and resulted in some tearing effects — sending the whole frame all at once to the display has the advantage of it appearing instantly and whole.

    I might try keeping track of dirty pixels, and only update those, and maybe even updating the display buffer right away when the drawing operations are happening, though that would require changes in Pew's architecture. Most likely I will probably keep the current logic and just move it to C to make it faster. 

  • Blit Blit Blitty Blit

    de∫hipu04/25/2019 at 08:20 3 comments

    With the display working, it's time to have some blitting fun. How about the good old classic bouncing ball?

    We have a background of random dots, and a round ball, with black outline, bouncing around the screen on top of it, passing outside the screen edges. Those details are all important, for example we don't want to only be able to handle rectangular sprites, or to crash when a sprite is partially outside the screen. So how do we do that?

    Read more »

  • The Curse of the OLED Display 3

    de∫hipu04/24/2019 at 17:07 0 comments

    This is not my first encounter with those small OLED display modules. We actually go back a while.

    First I tried to use it for the #Micro:Boy project, and I kept failing to get it working so much, that in the final version I decided to just use one of the ready modules. And of course after I did that and redesigned everything, I came back to the initial project and discovered that the display itself was physically faulty. But the project moved on, and I discovered other reasons why it won't work (not enough memory and code space on the micro:bit for the kind of games I wanted).

    Second attempt was with the #CircuitPython Badge, where one of the prototypes I've build used that display. I used the same display module, but in 4-wire SPI configuration this time. I wasn't able to get it to work, and I've moved on to e-ink displays, and later, after rethinking the whole thing, to LED matrices, because of the specifics of the project (the display needed to be big, not necessarily high-res).

    And here I am again, with the accursed display, in 4-wire SPI mode again. And again, I looked at the application notes in the datasheets both for SSD1306 and for SH1106, I looked at Adafruit's schematics for their breakout, and I am none the wiser. The connections are exactly the same as on that badge, and there is really nothing wrong with them, at least as far as I can see. Sure, all three sources of data use wildly different values for the capacitors — from 1µF, through 2.2µF, up to 4.7µF and 10µF. So which ones are correct? Who knows? Will the display work with my new PCB, if it didn't with the old one? Will I ever be able to get those things to work?

    Facing all those questions and doubts, I decided to take arms against them, and answer them once and for all. I dug out of my drawers the failed badge prototype, and decided to try and get it to work. I started by finding the designs files for it, and re-creating the board definition for CircuitPython, so that I can use the latest version (it includes displayio module, which I will need to get to work with those OLED displays later on). Then I flashed it, and dug up some of my old libraries for MicroPython for this display, and quickly converted it to CircuitPython. A quick test, and of course it doesn't work. Dead.

    Fine, as a next step, I tried all three combinations of capacitor values. No difference. Measured the voltages on those caps — hmm, looks like the charge pump is not even starting...

    I de-soldered the display from the prototype, and from a known good breakout, and swapped them. Tried the breakout module with an Adafruit board I had lying around, using Adafruit's SSD1306 libraries. Ah-ha! The display did start, but it's an SH1106, not SSD1306. But it's not faulty, so it should be at least showing something, like in this breakout. Why doesn't it?

    Next I tried the display from the known-good breakout in the prototype, with the code I had on it. Nope, doesn't work. And I'm sure this one is an SSD1306 and working. So something is wrong with the prototype. The charge pump is not switching on, so perhaps something with communications?

    I checked the continuity for all the control pins — everything looks correct. I re-soldered them, just to be sure. Still nothing. It seems that physically everything is fine...

    Wait a minute, what if I used those Adafruit libraries on this prototype? I copied them over and lo and behold! The display works! It was my crappy code all this time!

    I re-soldered all the displays back to their places, and changed the init sequence to a minimal example from my tutorial — just enabling the charge pump and setting contrast.

    And it works perfectly fine (the pattern on the display is the refresh of the OLED interfering with my potato camera).

    That means not only that the PCBs I ordered are going to work, but also that I can already start testing code on this prototype.

  • PCB Ordered

    de∫hipu04/22/2019 at 11:45 0 comments

    A few more hours finishing the display circuit (oh boy, does the SSD1306 datasheet suck in terms of example application), a bunch of capacitors added, and I think it's ready. Oops, a small DRC fail because I changed the USB connector. No problem, we will move that trace, thank you DRC! And now ordered from OSHPark.

    We will see how that goes. Now I we can bet on what comes first: the buttons, the display, or the PCB?

  • PCB Progress

    de∫hipu04/21/2019 at 22:56 5 comments

    I had some time over the holidays, so I made some progress on the PCB. A new footprint for the buttons and for the screen connector, routed everything except for the screen. Next I will need to add a truckload of capacitors for the screen, and bunch of vias for the display signals. I think I will go with SPI, because it's two resistors less, it's faster, and I have the pins for it anyways. The whole PCB is 32x32mm right now.

  • Buttons and Layout

    de∫hipu04/17/2019 at 22:48 0 comments

    With the display tentatively chosen (we will see how well that one works, and if it doesn't, there are many other possibilities) I have started to look into adding all the rest of components and arranging them. The second biggest part, and one with which the user will have intimate contact, are buttons.

    Of course for the price, going for simple capacitive touch pads, or cheap rubber dome buttons would be the best. But we do want to have at least a modicum of tactile feedback and comfort. So tact switches it is. I looked through what is available from the usual Chinese sellers, and mocked up a couple of layouts:

    You never before noticed how huge those buttons are, did you? Well, turns out the smallest you can get are about the size of a 1206 SMD resistor. I used similar buttons in the nGame before ( but they were horrible — designed as reset buttons for development boards, they require a lot of force to be pushed. This time I decided to try something more similar to the C&K PTS815 switches — they have a bigger cap and hopefully require less force. We will see. They do have 4 pins, though, which is a bit of an annoyance.

    But this would be too easy. I also want compatibility with PewPew Standalone boards in terms of the connector for the extra pins. That is 12 pins with 2.54mm pitch, so a bit difficult to fit, especially since the top edge is going to be taken up by the flex ribbon of the display. So I came up with something like this:

    It's a bit bigger than initially anticipated, with some margins around the display — that should make it a little bit easier to fit everything. And it has the connector, and some free PCB real estate on the opposing margin, which can be useful for actually getting that thing mounted in a case, if it comes to that.

    I'm sure the design will still change — I might decide to not put components under the display, for example — but this is at least some starting point.

  • Display

    de∫hipu04/16/2019 at 21:06 0 comments

    The LED matrices I'm using in all the other PewPew are great for several reasons: they have large pixels and small resolution, perfect for the kind of games I want to teach, where you don't have to worry about graphics. They are made of plastic, so are robust, scratch-resistant and light. And they only have 16 pins for soldering, and can be easily soldered by hand. But can there be anything cheaper?

    How about individual LEDs, like on the MicroBit? They are cheap, right? Well, the components themselves are cheap, but the soldering of 128 pads is not. And forget about doing it by hand. Plus, they don't look very good.

    Hmm, what else has a lot of LEDs in it, but only a few connectors, and can be had for cheap?

    How about those tiny little OLED displays? They only require a few pins to control, they are cheap, low-power, and they have more LEDs on them than we need. Sure, they are also usually monochrome, but because they have much higher resolution than we need, we can use dithering to get our required 44 shades:

    We even have some room left on the sides for some indicators!

    Plus, if we added support for them to displayio, we could even have proper error messages displayed on them when something happens. That's an improvement in functionality.

    (As an added bonus, it will probably be able to run arduboy games...)

View all 10 project logs

Enjoy this project?



John Loeffler wrote 04/30/2019 at 01:52 point

I caded a few displays if you are interested

  Are you sure? yes | no

de∫hipu wrote 04/30/2019 at 06:41 point

Thanks, that may come useful if I ever use a CAD program!

  Are you sure? yes | no

Alessandro wrote 04/24/2019 at 22:13 point

I think this could make for a better gamebuino clone :D

  Are you sure? yes | no

de∫hipu wrote 04/24/2019 at 22:23 point

Gamebuino is more like #µGame, but this should be copatible with the Arduboy, at least after changing the pins. Not that I have any plans on working on that — I prefer to write the games in Python.

  Are you sure? yes | no

Daren Schwenke wrote 04/16/2019 at 20:45 point

Perhaps the number of pews could denote the size.  :)

  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