ssd1306 using I2C on the esp8266

All ESP8266 boards running MicroPython.
Official boards are the Adafruit Huzzah and Feather boards.
Target audience: MicroPython users with an ESP8266 board.
slzatz
Posts: 79
Joined: Mon Feb 09, 2015 1:09 am

ssd1306 using I2C on the esp8266

Post by slzatz » Sat Mar 26, 2016 3:16 pm

With I2C enabled in the repository, does anyone have working code for driving the ssd1306. There are a couple examples of driving the ssd1306 via the previous SPI and I2C implementations (for example https://github.com/khenderick/micropython-drivers) but I am having trouble modifying them to work with the I2C implementation for the esp8266 port. This commit https://github.com/micropython/micropyt ... b1eff3d42f
had a note about I2C working with the SSD1306 I2C display. Happy to work with code that is still under development and contribute to it.

slzatz
Posts: 79
Joined: Mon Feb 09, 2015 1:09 am

Re: ssd1306 using I2C on the esp8266

Post by slzatz » Sat Mar 26, 2016 7:03 pm

With some minor modifications of Kenneth Henderick's ssd1306 driver, the following works for me using the Adafruit FeatherWing OLED and the Adafruit Feather Huzzah board. Doesn't support fonts at the moment (but plan to add that).

https://gist.github.com/slzatz/7c009736a50bf12c6df7

And allows you to do something like:

Code: Select all

from ssd1306 import SSD1306 as ssd
d = ssd(height=32, external_vcc=False)
d.poweron()
d.init_display()
for x in range(30):
    d.set_pixel(x,x,1)
    
d.display()
and a line will appear on the OLED ...

slzatz
Posts: 79
Joined: Mon Feb 09, 2015 1:09 am

Re: ssd1306 using I2C on the esp8266

Post by slzatz » Sun Mar 27, 2016 1:30 am

Trying to add fonts has run into memory issues. I've removed everything extraneous from ssd1306.py but that module needs to import a font modue and I am getting

Code: Select all

MemoryError: parser could not allocate enough memory
and depending I am also getting just

Code: Select all

Memory Error:
with no additional text. The font file that I am trying to import within ssd1306.py looks like https://github.com/nvbn/micropython-dri ... 06/font.py. I have used gc.collect() and that has freed up a little memory but not enough to get this to work. Any suggestions would be appreciated and since I believe one of the kickstarter videos had text printed to a ssd1306 OLED, it must be possible.

User avatar
deshipu
Posts: 1237
Joined: Thu May 28, 2015 5:54 pm

Re: ssd1306 using I2C on the esp8266

Post by deshipu » Sun Mar 27, 2016 9:51 am

Hmm, on Arduino you would force data like this to live in the program memory, on the flash, by using PROGMEM. I vaguely remember there was some discussion about doing something similar in Micropython, but I can't find it now on the forum.

slzatz
Posts: 79
Joined: Mon Feb 09, 2015 1:09 am

Re: ssd1306 using I2C on the esp8266

Post by slzatz » Sun Mar 27, 2016 11:36 am

Thanks for the suggestion. Currently accessing ssd1306.py and font.py as frozen modules but will look to see if there is some way to leave the font data in flash and access it directly without bringing the whole file into RAM (if that makes any sense).

User avatar
deshipu
Posts: 1237
Joined: Thu May 28, 2015 5:54 pm

Re: ssd1306 using I2C on the esp8266

Post by deshipu » Sun Mar 27, 2016 1:55 pm

Found it https://github.com/micropython/micropython/issues/573

But I remembered wrong and it's not actually what would help you here.

slzatz
Posts: 79
Joined: Mon Feb 09, 2015 1:09 am

Re: ssd1306 using I2C on the esp8266

Post by slzatz » Sun Mar 27, 2016 5:52 pm

So at least the temporary answer is to limit the character set. If I limit the font file to ASCII 32 to 90, which at least gets me all capital letters, then it works fine. The original font file started at ASCII 0, which in retrospect didn't make sense and so easy to eliminate the first 32 characters and my guess is that if I can live without a few punctuation characters it may be possible to get all lowercase characters as well. Not sure I fully understand micropython memory management but the output of micropython.mem_info(1) is that after cutting down the font file there is still 6000 free out of 16064 although I think the issue is that in the process of parsing the file some additional memory is at least temporarily needed.

The following was updated and the module that enables text is ssd1306a.py if anyone is interested.

https://gist.github.com/slzatz/7c009736a50bf12c6df7

User avatar
pythoncoder
Posts: 2016
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: ssd1306 using I2C on the esp8266

Post by pythoncoder » Wed Mar 30, 2016 5:30 am

My e-paper driver has two alternative solutions to the problem of font files. Neither is ideal. The first is to store a binary font file on the SD card (or other disk media) and use random file access to bring individual characters into RAM as needed. This conserves RAM but is probably too slow for any display technology faster than e-paper. The second is to use persistent byte code: a utility converts the fonts in a project to a Python source file which is incorporated into a firmware build. This is fast and uses very little RAM but requires the user to build the firmware.

Storing the Python as a frozen module wouldn't help because the bytes objects containing the font data within would be pulled into RAM at load/compile time.

Persistent byte code is currently under development on the Pyboard - I don't know its status on the esp8266.
Peter Hinch

Online
User avatar
dhylands
Posts: 2517
Joined: Mon Jan 06, 2014 6:08 pm
Location: Shuswap, BC, Canada
Contact:

Re: ssd1306 using I2C on the esp8266

Post by dhylands » Wed Mar 30, 2016 5:32 am

pythoncoder wrote:Storing the Python as a frozen module wouldn't help because the bytes objects containing the font data within would be pulled into RAM at load/compile time.
Even with a memoryview?

User avatar
pythoncoder
Posts: 2016
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: ssd1306 using I2C on the esp8266

Post by pythoncoder » Wed Mar 30, 2016 5:43 am

That's a good question. Say I have a Python source module which declares a large bytes object. When I import the module, presumably the text defining the object gets converted to a contiguous array of binary data. This must exist somewhere: I had assumed that the only place it can exist is in RAM.

My understanding is that freezing Python code is a way of conserving space on the Flash disk rather than conserving RAM.
Peter Hinch

Post Reply