Here’s a pic of the OpenMV M7 connected to the SPI OLED display. Thanks again!
Ibrahim, can you add this to the examples?
done.
Can we add the I2C code for this module back into the driver as well?
Do you want the example shipped with the IDE?
that would be nice, but i am referencing the ssd1306 driver you added to the libraries.
The code only supports SPI communication. since it is not pulled from the main micropython branch, or was but was heavily modified to remove the I2C portion and modify some of the initialization for the SPI from the main branch, my request to to either change it to the master, or add the I2C support.
https://github.com/micropython/micropython/blob/master/drivers/display/ssd1306.py
you’ll find this code missing from the library added to the openmv github.
class SSD1306_I2C(SSD1306):
def __init__(self, width, height, i2c, addr=0x3c, external_vcc=False):
self.i2c = i2c
self.addr = addr
self.temp = bytearray(2)
super().__init__(width, height, external_vcc)
def write_cmd(self, cmd):
self.temp[0] = 0x80 # Co=1, D/C#=0
self.temp[1] = cmd
self.i2c.writeto(self.addr, self.temp)
def write_data(self, buf):
self.temp[0] = self.addr << 1
self.temp[1] = 0x40 # Co=0, D/C#=1
self.i2c.start()
self.i2c.write(self.temp)
self.i2c.write(buf)
self.i2c.stop()
Thanks!
I’m using this 128x64 OLED display: link
I tried to use the code above with this display and OpenMV. It is not working but it doesn’t give me any error message.
Do you know what modifications should be made in this code in order to connect this display?
Thank you!
That code isn’t written by use. Someone just sent us a PR and we added it. Can you send a PR for the fixes you need?
Now, I am using the same display than you but I have trouble with the connections.
Please could you send me the schematics of the pin connections?
Thank you!
Attached below is the code I am attempting to use. I have an SSD1306 128x32 OLED wired for I2C4, and I’m having some trouble understanding how to print text. I did some research on classes/objects, but I’m still having some trouble understanding what “self” is and how to call functions from inside classes. Do you know how to call the function to print simple text to the OLED? I’m specifically looking at what I need to include in this part of the code to make it work:
SSD1306.__init__(SSD1306,width=128,height=32, external_vcc=3.3)
SSD1306.text("HelloWorld!", 0,0,1)
SSD1306.show()
When this portion of the code is ran, I get an error stating “AttributeError: type object ‘SSD1306’ has no attribute ‘poweron’”
Thanks so much, and sorry if there are any issues with this post; this is my first post on the forums.
import time
import framebuf
from pyb import I2C
i2c = I2C(4, I2C.MASTER) # The i2c bus must always be 2.
mem = i2c.mem_read(256, 0x3C, 0) # The eeprom slave address is 0x50.
# register definitions
SET_CONTRAST = const(0x81)
SET_ENTIRE_ON = const(0xa4)
SET_NORM_INV = const(0xa6)
SET_DISP = const(0xae)
SET_MEM_ADDR = const(0x20)
SET_COL_ADDR = const(0x21)
SET_PAGE_ADDR = const(0x22)
SET_DISP_START_LINE = const(0x40)
SET_SEG_REMAP = const(0xa0)
SET_MUX_RATIO = const(0xa8)
SET_COM_OUT_DIR = const(0xc0)
SET_DISP_OFFSET = const(0xd3)
SET_COM_PIN_CFG = const(0xda)
SET_DISP_CLK_DIV = const(0xd5)
SET_PRECHARGE = const(0xd9)
SET_VCOM_DESEL = const(0xdb)
SET_CHARGE_PUMP = const(0x8d)
class SSD1306:
def __init__(self, width, height, external_vcc):
self.width = width
self.height = height
self.external_vcc = external_vcc
self.pages = self.height // 8
# Note the subclass must initialize self.framebuf to a framebuffer.
# This is necessary because the underlying data buffer is different
# between I2C and SPI implementations (I2C needs an extra byte).
self.poweron()
self.init_display()
def init_display(self):
for cmd in (
SET_DISP | 0x00, # off
# address setting
SET_MEM_ADDR, 0x00, # horizontal
# resolution and layout
SET_DISP_START_LINE | 0x00,
SET_SEG_REMAP | 0x01, # column addr 127 mapped to SEG0
SET_MUX_RATIO, self.height - 1,
SET_COM_OUT_DIR | 0x08, # scan from COM[N] to COM0
SET_DISP_OFFSET, 0x00,
SET_COM_PIN_CFG, 0x02 if self.height == 32 else 0x12,
# timing and driving scheme
SET_DISP_CLK_DIV, 0x80,
SET_PRECHARGE, 0x22 if self.external_vcc else 0xf1,
SET_VCOM_DESEL, 0x30, # 0.83*Vcc
# display
SET_CONTRAST, 0xff, # maximum
SET_ENTIRE_ON, # output follows RAM contents
SET_NORM_INV, # not inverted
# charge pump
SET_CHARGE_PUMP, 0x10 if self.external_vcc else 0x14,
SET_DISP | 0x01): # on
self.write_cmd(cmd)
self.fill(0)
self.show()
def poweroff(self):
self.write_cmd(SET_DISP | 0x00)
def contrast(self, contrast):
self.write_cmd(SET_CONTRAST)
self.write_cmd(contrast)
def invert(self, invert):
self.write_cmd(SET_NORM_INV | (invert & 1))
def show(self):
x0 = 0
x1 = self.width - 1
if self.width == 64:
# displays with width of 64 pixels are shifted by 32
x0 += 32
x1 += 32
self.write_cmd(SET_COL_ADDR)
self.write_cmd(x0)
self.write_cmd(x1)
self.write_cmd(SET_PAGE_ADDR)
self.write_cmd(0)
self.write_cmd(self.pages - 1)
self.write_framebuf()
def fill(self, col):
self.framebuf.fill(col)
def pixel(self, x, y, col):
self.framebuf.pixel(x, y, col)
def scroll(self, dx, dy):
self.framebuf.scroll(dx, dy)
def text(self, string, x, y, col=1):
self.framebuf.text(string, x, y, col)
class SSD1306_I2C(SSD1306):
def __init__(self, width, height, i2c, addr=0x3c, external_vcc=False):
self.i2c = i2c
self.addr = addr
self.temp = bytearray(2)
super().__init__(width, height, external_vcc)
def write_cmd(self, cmd):
self.temp[0] = 0x80 # Co=1, D/C#=0
self.temp[1] = cmd
self.i2c.writeto(self.addr, self.temp)
def write_data(self, buf):
self.temp[0] = self.addr << 1
self.temp[1] = 0x40 # Co=0, D/C#=1
self.i2c.start()
self.i2c.write(self.temp)
self.i2c.write(buf)
self.i2c.stop()
SSD1306.__init__(SSD1306,width=128,height=32, external_vcc=3.3)
SSD1306.text(1,"HelloWorld!", 0,0,1)
SSD1306.show()
Hi, this is not really a piece of hardware we support. We enabled the driver but did not test. Please check the source code for the driver in MicroPython and see what methods are there.
