Two years ago I wrote font_to_py.py: a utility for converting fonts to Python source. This enables fonts to be stored as frozen bytecode and used with minimal RAM allocation. To demonstrate it I wrote a very basic Writer class intended as a proof of concept. A number of people are using this as it stands so I have improved it, taking on board various requests and suggestions, to make it a practical solution.
A MicroPython module adds functionality to the official SSD1306 driver, enabling the rendering of Python fontfiles. It supports fields and labels with inverse and normal text:
Mixed text and graphics:
Right or centre justified text:
Scrolling text with multiple fonts:
Row wrapping options are clip or scroll. Column wrapping options are clip, character wrap and simple word wrap. Text display honours tab and newline characters. Inverse (background on foreground) text may be displayed and an inverted (upside down) display option is provided.
It supports multiple displays on the same host. It is designed to support any display device whose driver is subclassed from Framebuf. Currently only the SSD1306 OLED driver meets that requirement.
SSD1306 OLED display: enhanced driver
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
SSD1306 OLED display: enhanced driver
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.
Re: SSD1306 OLED display: enhanced driver
Added subclassed version of my Nokia 5110 / PCD8544 driver:
https://github.com/mcauser/micropython- ... 8544_fb.py
It uses the MONO_VLSB format, as there is currently no compatible Framebuf format for the vertical addressing supported by the display.
More details on the display addressing: https://github.com/mcauser/micropython- ... addressing
https://github.com/mcauser/micropython- ... 8544_fb.py
It uses the MONO_VLSB format, as there is currently no compatible Framebuf format for the vertical addressing supported by the display.
More details on the display addressing: https://github.com/mcauser/micropython- ... addressing
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: SSD1306 OLED display: enhanced driver
Just ordered a Nokia display so I'll give it a try.
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.
Re: SSD1306 OLED display: enhanced driver
Hi, I have have previously used the ssd1306 and just tried using the writer with the 1.3" sh1106 and of course it fails:Currently only the SSD1306 OLED driver meets that requirement.
Code: Select all
ValueError: Device must be derived from FrameBuffer.
Code: Select all
import sh1106
>>> sh=sh1106.SH1106_I2C(128,64,gpio.i2c)
>>> dir(sh)
['__class__', '__dict__', '__init__', '__module__', '__qualname__', 'addr', 'blit', 'buffer', 'fill', 'fill_rect', 'framebuf', 'hline', 'invert', 'line', 'pixel', 'rect', 'reset', 'scroll', 'sleep', 'text', 'vline', 'res', 'init_display', 'poweroff', 'poweron', 'contrast', 'show', 'width', 'height', 'external_vcc', 'pages', 'write_cmd', 'write_data', 'i2c', 'temp', 'rotate', 'hw_write_data', 'sw_write_data']
>>> fm = Writer(ssd, f10, verbose=False)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "writer.py", line 70, in __init__
File "writer.py", line 45, in _get_id
ValueError: Device must be derived from FrameBuffer.
Re: SSD1306 OLED display: enhanced driver
I attempted to convert an existing sh1106 library to a similar format as ssd1306, but it fails at the init() probably as I don't understand how to use super():
Code: Select all
import framebuf
'''
import gpio, sh1106_i2c as sh
ssd = sh.SH1106(gpio.i2c)
'''
class SH1106(framebuf.FrameBuffer):
_byte = bytearray(1)
_word = bytearray(2)
def __init__(self, i2c, address=0x3c, width=128, height=64):
self._address = address
self.width = width
self.height = height
self._i2c = i2c
buffer = bytearray(1024)
self._buffer = memoryview(buffer)
super().__init__(self._buffer, self._i2c, self._address,self.width,self.height)
self.init_display()
def init_display(self):
self._command = bytearray(b'\xb0\x02\x10')
if self.width > 128: self._command[1] = 0x00
self._i2c.writeto_mem(self._address, 0x00, b'\xae\xd5\x80\xa8\x3f\xd3'
b'\x00\x40\x80\x14\x20\x00\xc0\xa0\xda\x12'
b'\x81\xcf\xd9\xf1\xdb\x40\xa4\xa6\xaf')
def active(self, val):
self._i2c.writeto_mem(self._address, 0x00, b'\xaf' if val else b'\xae')
def inverse(self, val):
self._i2c.writeto_mem(self._address, 0x00, b'\xa7' if val else b'\xa6')
def vscroll(self, dy):
self._byte[0] = 0x40 | dy & 0x3f
self._i2c.writeto_mem(self._address, 0x00, self._byte)
def flip(self, val):
self._i2c.writeto_mem(self._address, 0x00, b'\xc0' if val else b'\xc8')
def mirror(self, val):
self._i2c.writeto_mem(self._address, 0x00, b'\xa0' if val else b'\xa1')
def contrast(self, val):
self._word[0] = 0x81
self._word[1] = val & 0xff
self._i2c.writeto_mem(self._address, 0x00, self._word)
def update(self):
index = 0
for page in range(self.height // 8):
self._command[0] = 0xb0 | page
self._i2c.writeto_mem(self._address, 0x00, self._command)
self._i2c.writeto_mem(self._address, 0x40,self._buffer[index:index + self.width])
index += self.width
Code: Select all
>>> import gpio, sh1106_i2c as sh
>>> ssd = sh.SH1106(gpio.i2c)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "sh1106_i2c.py", line 21, in __init__
TypeError: can't convert I2C to int
Re: SSD1306 OLED display: enhanced driver
did you check the order of arguments in the super.__init__() call. That may be the problem. It calls the framebuffer class' init(), which does not requires i2c and address. Should look like
super().__init__(width, height, external_vcc)
super().__init__(width, height, external_vcc)
Re: SSD1306 OLED display: enhanced driver
Thanks Robert, that was it.
I have updated the driver which can be found here: https://github.com/pacmac/micropython-s ... 106_i2c.py
I have updated the driver which can be found here: https://github.com/pacmac/micropython-s ... 106_i2c.py