3rd Colour Pixel on Arduboy!

First demo, using modified version of @Dreamer3’s code.

Second demo, using modified version of @unclesporky’s code.

Despite using a 1-bit screen, we have developed a way of including a third colour into the mix. So please enjoy the very first demo of grey pixels being displayed alongside black and white pixels on the Arduboy (Apologies for video quality).

Huge credit to @Dreamer3, @unclesporky for their contributions.

https://github.com/Wozza365/GreyPixel (Latest)

Join The Discussion! Arduboy IRC & Slack Chat

Check back here for regular updates!


I tried playing with this same concept on my microview (another arduino powered oled device). I don’t think it’s going to be viable the same way it was on older micro systems like pokemon mini or pocket station.

It’s going to need a lot more work with trying to control sync with the screen.

I’ve also made a greyscale test program. It does…some kinda funky things to get to that point.

Bytes are rearranged vertically when you send them to the screen. That means a standard left-to-right, top-to-bottom bitmap needs to be converted. I don’t have a conversion program on my computer yet, but I wrote one that runs right on the Arduboy, at the cost of many unnecessary CPU cycles. (With the help of @ekem, who wrote a function that did the exact opposite conversion.) To be able to flip between two monochrome images faster, I allocated 2 screen buffers in RAM, and convert bitmaps in progmem to them at the start of the program. Then I just flip between the two screens as fast as possible.

You don’t need to know any of that really. Just run this!

It displays this image of characters from Final Fantasy 1 nearly perfectly with no flicker, including the two grey levels…

…however, there is a “black shadow” passing over the screen regularly. This is because it doesn’t sync up perfectly with the screen refresh rate. If we had some way to time it alongside the screen such as a vsync interrupt, it’d be perfect.

You have to leave the USB cable plugged in for it to look good too, since the USB code takes up some cycles that, as luck would have it, almost syncs the draws up. If you unplug it and turn on the Arduboy manually, it will look flickery.

Just more experimentation, stuff for people to look at.

It’s a work in progress and there are issues. To make it work better we need to be able to sync it with the screen refresh rate. Currently however we are unable to do so.


Is there a reason as to why you flush the display before you overwrite it again?

It made screen tearing far worse in my testing.

Honestly it was just a happy accident. I wasn’t doing that and the greyscale was really flickery, so I added it just to see if it might affect how it looked. I know it adds delay for no real benefit, but it was just enough delay in this case to be an example of what greyscale could look like if we’re able to sync up properly.

Updated with a modified version of @unclesporky’s code!

Source will be uploaded soon!

The comments of my program sort of describe what’s happening, but I should mention it here too.

There are two monochrome images. When we flip between them rapidly, if one image has a white pixel where the other doesn’t, it will look grey.

In order to display two levels of grey, you need to show one of the two images twice, and the other only once. The picture that is shown for two frames in a row gets its bits more emphasized.

So what your eye sees is white-black-black, which is overall more dark, so it’s a dark grey. Or you will see black-white-white, which is overall more white, so it’s a light grey.

My program has two modes - either it shows two shades of grey as described above, or you can just flip directly back and forth between the two images and see only one level of grey. You can change modes by pressing left and right on the d-pad. You should be able to notice the difference.

I should add that I don’t think the hardware is fast enough to show us 50 Shades of Grey. :stuck_out_tongue:

dude really nice work guys!

I won’t be getting an Arduboy for a while and I know the displays work differently… but on the Gamebuino, we found out that the banding stripes will go away if you use a checkered pattern for gray. On the Gamebuino it also looks good with very low FPS (15+, instead of the 40+ we normally need for whole screens flipping like you guys are doing).

Basically, we flip between these two patterns (B = black, _ = white):



Alternating vertical stripes also works very well (and its the way it was coded in the Gamebuino library):



Although for some reason, with the Gamebuino display, alternating horizontal stripes doesn’t work well.

1 Like

I think things are a little different on the Arduboy due to its OLED display. The pixels have a really fast response time, there’s basically 0 ghosting at all. On previous devices like the Gamby and Gamebuino, IIRC they typically had cheap LCD displays with ghosting, which made it easier to generate something that looked grey.

Not that I don’t appreciate the advice. That’d be a good method if you were just showing one shade of grey.

This method might work with the other one that is already working to produce maybe a 4th color?

Dithering between grey and black or grey and white was the plan, to produce a 4th color. It would produce a max of 5 but Dreamer mentioned it should be kept to 2 bits.

Updated with header photo :slight_smile:

and source :slight_smile:

I was actually toying with this last night on my microview. The first option might work to give a perceived variance to the color. (The second one less so due to pixel orientation, looks like flickering lines). It also looks less glitchy then pure on/off (until we get sync sorted).

Generally correct that oled has little/low ghosting due to it’s fast pixel response time but it does have some issues with blurring/sharpness with motion which is why you hear about “low persistence” in VR headsets even when using OLED displays.