ssd1351 128*128 RGB565 OLED

Video demonstration

:slight_smile: Finally got my hands on a few SSD1351 modules. Ended up with 2 for ~A$50 from Alibaba instead of A$60 each locally. They’re 128*128 1.5" and only have SPI interface.

First thing I noticed about the driver was the similarity with the SSD130X OLED screens.

Ended up just extending my OLED13XX driver as it was already generic and basically just pass a parameter script to initialize everything.

I was paranoid at first these would be slow because of the extra bit depth but found the Arduino Due with modified DMA is more than adequate.

I revisited my virtual 16BPP graphic library and now have most aspects working very well. All graphics is rendered into a screen buffer of which all or partial areas can be sent to the SSD1351.

The SD card library and OLED library also play nicely together even when both have a different SCK rate.

All the font and images I tested with were created with http://kiweedsoftware.byethost18.com/a_mcumaker.php

Although the device is 16 bit RGB565 I can render memory or streamed bitmaps that are clipped in the following formats :-

16 bit RGB565
8 bit palette with 1 alpha
8 bit palette with no alpha
1 bit (with or without BG color)
4 bit palette with 1 alpha
4 bit palette with 0 alpha

The streaming rate from SD card is fast enough for streaming 128*128 animations without any problems and needed delays to stop it being played too fast.

The file format is one for all… fonts, animations, single bitmaps, regardless are in a single easy to decode format. The format is the same for whether in memory or being streamed.

I took a different approach to rendering just recently and as a result rendering clipped bitmaps is the same speed as non-clipped as the area to be rendered is adjusted just once at the start.

Streaming is also handled differently than my first iteration. I have a buffer of 1.5K, if the streamed bitmap will fit into the buffer it’s loaded then treated as if it’s not streamed as it’s now in memory. If it can’t fit then… the entire scanline must fit or it aborts (limit). In the y-loop section of rendering I check to see if it’s being streamed… if it is then the next scanline is loaded and the source buffer reset back to the start.

Finally got to physically test everything and have been very happy with the results.

Some demonstrations of these devices on youtube do no justice to the potential of these devices. They will run on an 8 bit AVR but don’t expect blazing speed etc.

The other thing I got happening (finally) was getting the OVR7670 camera working with the SSD1351 display. Makes debugging the camera image easier when have some realtime output happening.

Example of code to display some bitmaps etc.

void showbitmap()
{
#if _DEBUG
 Serial.println("showbitmap start!");
#endif

 gDIB.Font.LoadFromFile("gr1.lmb");

 for (int i = 0; i < gDIB.Font.FrameCount(); i++)
 {
 gDIB.drawBitmap(0, 0, i, DIB_BLIT_STORE);
 gOLED.checkSCKDiv();
 gOLED._1351renderScreen(gDIB.getBuffer(), true);
 delay(50);
 }

 delay(1000);

 gDIB.Font.LoadFromFile("gr3.lmb");

 gDIB.clearScreen();

 for (int i = 0; i < gDIB.Font.FrameCount(); i++)
 {
 gDIB.drawBitmap(0, 0, i, DIB_BLIT_STORE);
 gOLED.checkSCKDiv();
 gOLED._1351renderScreen(gDIB.getBuffer(), true);

 delay(50);
 }

Loading from a “blob” in memory is basically the same using

gDIB.Font.LoadFromMemoryBlob(bitmap_troll4bpp);