T
The argument related issues are related to an issue with using a native class as a base class. See here:
https://github.com/micropython/micropython/issues/3323
This doesn't work in Pycom's MicroPython release 1.18 (current stable) but the fix from the above linked issue has been incorporated into the development release 1.20 (currently at rc4).
Additionally, the Pycom MicroPython flavor has a different I2C API than the official MicroPython, lacking the I2C methods start(), stop() and write(). There you need to apply the changes outlined in this old thread as well:
https://forum.pycom.io/topic/1366/wipy-ssd1306-only-noise/6
Specifically, you'll need to replace the write_data() method with:
def write_data(self, buf):
self.i2c.writeto(self.addr, bytearray([0x40]) + buf)
(I see that you've already discussed the issue with Pycom's MicroPython flavor using framebuf.MVLSB where as the constant is named framebuf.MONO_VLSB in the official MicroPython).
The SSD1306 driver in Pycom's MicroPython flavor has never worked and is still using non-existant APIs and constants even in the release-candidate tree: https://github.com/pycom/pycom-micropython-sigfox/blob/release-candidate/drivers/display/ssd1306.py
If you get noisy display you might have an SH1106 display. I'm using the below piece of code successfully with random eBay 0.96" and 1.3" I2C OLED displays. It's been a few years since I looked into this but IIRC the SH1106 module's internal memory layout is for 132 pixel strides but the screen only supports 128. So the noise in the form of random black pixels come from the fact that those extra two pixels on the left and on the right side are not accounted for (the display is centered somehow).
from ssd1306 import SSD1306
class SH1106_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)
# Parent does show() but is using the SSD1306 implementation..
self.show()
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.i2c.writeto(self.addr, bytearray([0x40]) + buf)
def poweron(self):
pass
def show(self):
for page in range(8):
self.write_cmd(0xb0 | page)
self.write_cmd(0x02) # Start addr low column
self.write_cmd(0x10) # Start addr high column
mv = memoryview(self.buffer)
self.write_data(mv[128*page: 128 + 128*page])
from sh1106 import SH1106_I2C
i2c = I2C(0, I2C.MASTER, baudrate=400000)
d = SH1106_I2C(128, 64, i2c)
d.text('ping', 1, 2)
d.show()