Using an SSD1306 as 7-segment display

Questions and discussion about running MicroPython on a micro:bit board.
Target audience: MicroPython users with a micro:bit.
Post Reply
fizban
Posts: 24
Joined: Mon Oct 24, 2016 2:32 pm

Using an SSD1306 as 7-segment display

Post by fizban » Mon Mar 06, 2017 12:33 pm

I have created a library for the micro:bit to use the SSD1306 OLED display as a 7-segment display: https://github.com/fizban99/microbit_ssd1306_7seg

As my other library, it currently only supports I2C, but this one supports the full 128x64 resolution of the display since it does not require a display buffer. Number generation is also very fast, since only the required segments are redrawn and the design of the segments is optimized for this display.

User avatar
mcauser
Posts: 507
Joined: Mon Jun 15, 2015 8:03 am

Re: Using an SSD1306 as 7-segment display

Post by mcauser » Mon Mar 13, 2017 1:55 am

I made a library for 7-segment displays using the TM1637 LED driver, used by the SeeedStudio Grove 4 digit display:
http://forum.micropython.org/viewtopic. ... 81&p=16525
Not as cool as an OLED though!

Nokia 5110 LCD (PCD8544) next? The Nokia display uses a lot less power. (0.4mA vs 5-13mA for the OLED)
http://www.bigmessowires.com/2011/06/07 ... smackdown/

fizban
Posts: 24
Joined: Mon Oct 24, 2016 2:32 pm

Re: Using an SSD1306 as 7-segment display

Post by fizban » Mon Mar 13, 2017 8:01 am

The Nokia 5110 is in my to do list. Once I receive it from China in about one month (2.5 euro presoldered)... I believe its resolution might be perfect for a screen buffer that the micro:bit can handle without major memory problems.

I just received an OLED SSD1306 SPI and I am modifying the library to work with it. I actually prefer the SPI version over the I2C version for the micro:bit: it is much faster, it is cheaper (2.8 euro vs 3.5 euro of the I2C version), it does not require any soldering since the SPI pins are available on the breakout board and you can use 6 contiguous pins easily putting together 6 dupont cables.

User avatar
mcauser
Posts: 507
Joined: Mon Jun 15, 2015 8:03 am

Re: Using an SSD1306 as 7-segment display

Post by mcauser » Mon Mar 13, 2017 3:47 pm

I made you a Nokia 5110 version. Here is it running on my ESP8266:
https://github.com/mcauser/MicroPython- ... -7-segment

The first version I made used bytearrays for each digit, but this proved to be much larger than just drawing individual lines to make up each segment.

Code: Select all

# digits 0-7, column major, 16x25 each digit
buf0 = bytearray(b'\xFE\xFD\xFB\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\xFB\xFD\xFE\xC7\xEF\xC7\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC7\xEF\xC7\xFF\x7F\xBF\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xBF\x7F\xFF\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00')
buf1 = bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xF8\xFC\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC7\xEF\xC7\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3F\x7F\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
buf2 = bytearray(b'\x00\x01\x03\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\xFB\xFD\xFE\xC0\xE0\xD0\x38\x38\x38\x38\x38\x38\x38\x38\x38\x38\x17\x0F\x07\xFF\x7F\xBF\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\x80\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00')
buf3 = bytearray(b'\x00\x01\x03\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\xFB\xFD\xFE\x00\x00\x10\x38\x38\x38\x38\x38\x38\x38\x38\x38\x38\xD7\xEF\xC7\x00\x00\x80\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xBF\x7F\xFF\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00')
buf4 = bytearray(b'\xFE\xFC\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xF8\xFC\xFE\x07\x0F\x17\x38\x38\x38\x38\x38\x38\x38\x38\x38\x38\xD7\xEF\xC7\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3F\x7F\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
buf5 = bytearray(b'\xFE\xFD\xFB\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x03\x01\x00\x07\x0F\x17\x38\x38\x38\x38\x38\x38\x38\x38\x38\x38\xD0\xE0\xC0\x00\x00\x80\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xBF\x7F\xFF\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00')
buf6 = bytearray(b'\xFE\xFD\xFB\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x03\x01\x00\xC7\xEF\xD7\x38\x38\x38\x38\x38\x38\x38\x38\x38\x38\xD0\xE0\xC0\xFF\x7F\xBF\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xBF\x7F\xFF\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00')
buf7 = bytearray(b'\x00\x01\x03\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\xFB\xFD\xFE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC7\xEF\xC7\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3F\x7F\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')

fbuf0 = framebuf.FrameBuffer(buf0, 16, 25, framebuf.MVLSB)
fbuf1 = framebuf.FrameBuffer(buf1, 16, 25, framebuf.MVLSB)
...
fbuf7 = framebuf.FrameBuffer(buf7, 16, 25, framebuf.MVLSB)
Digits 8 and 9 can be made by blitting other digits. (8=6+1, 9=5+1)

Code: Select all

fbuf.blit(fbuf6, 65, 12)
fbuf.blit(fbuf1, 65, 12, 0)
It was 75% smaller by just drawing 3 lines per segment, and offsetting for each segment location.

Code: Select all

fbuf.hline(x, y, w, c)
fbuf.vline(x, y, h, c)

fizban
Posts: 24
Joined: Mon Oct 24, 2016 2:32 pm

Re: Using an SSD1306 as 7-segment display

Post by fizban » Mon Mar 13, 2017 4:56 pm

Thanks. There are some interesting ideas that I might borrow. Still, due to the memory limitations of the micro:bit I wanted to avoid the usage of a screen buffer. Even 504 contiguos bytes can be tricky (84*48/8). Besides, I wanted it to be fast, so only the segments that change from the previous update will get rewritten, instead of doing a full screen refresh each time. That makes the segments look a little bit weird, since they cannot overlap the same page.

For general drawing capabilities and games you do need a screen buffer and 504 bytes is just about right for simple games, but when you just need to display information coming from a sensor, for example, better save those precious bytes for the main program.

Post Reply