Pyboard/MicroPython display on SSD1315 I2C OLED using SSD1306 driver
This video show how Pyboard PYBv1.1 (flashed with MicroPython v1.19.1) display on 0.96 inch 128x64 SSD1315 I2C OLED using micropython-ssd1306 driver.
The post "Raspberry Pi Pico/MicroPython exercise using SSD1306 I2C OLED" show how to manual install ssd1306 driver to MicroPython device. This video
show another approach in Thonny to install micropython-ssd1306 driver. This is a fork of
the driver for SSD1306 displays which is hosted in the Micropython
package. The purpose of this fork is to make the
driver available on PyPi
and thus installable via the upip package manager. But it haven't implemented
rotate() function.
Exercise code
mpyPYB_i2c_scanner.py
Show I2C info and scan I2C devices
import sys
import os
import machine
print("====================================")
print(sys.implementation[0], os.uname()[3],
"\nrun on", os.uname()[4])
print("====================================")
print()
def i2c_scan(i2c_toscan):
print('=== I2C Scanner ===')
print(i2c_toscan)
devices = i2c_toscan.scan()
if len(devices) == 0:
print("No I2C device found!")
else:
print('I2C devices found:',len(devices))
for device in devices:
print(device, ":", hex(device))
# How many hardware I2C supported
# and show the I2C info
print("number of I2C supported:")
print("========================")
i=1
while True:
try:
i2c=machine.I2C(i)
i2c_scan(i2c)
except ValueError as e:
#print(e)
break
i += 1
print()
mpyPYB_ssd1306.pyA simple test code for ssd1306
import sys
import os
import machine
import time
import ssd1306
print("====================================")
print(sys.implementation[0], os.uname()[3],
"\nrun on", os.uname()[4])
print("====================================")
oled_i2c = machine.I2C(2)
print("Default I2C(2):", oled_i2c)
DISP_WIDTH=128
DISP_HEIGHT=64
oled = ssd1306.SSD1306_I2C(DISP_WIDTH, DISP_HEIGHT, oled_i2c)
print("Default SSD1306 I2C address:",
oled.addr, "/", hex(oled.addr))
oled.fill(1)
oled.show()
time.sleep(2)
oled.fill(0)
oled.show()
time.sleep(2)
oled.rect(0, 0, DISP_WIDTH, DISP_HEIGHT, 1)
oled.text('Hello, World!', 5, 5, 1)
oled.show()
mpyPYB_ssd1315_hello_fb.py, port from the post "Raspberry Pi Pico/MicroPython exercise using SSD1306 I2C OLED".
"""
MicroPython/Pyboard exercise
display on 0.96" 128x64 SSD1315 I2C OLED.
"""
import sys
import os
import time
import ssd1306
import framebuf
print("====================================")
print(sys.implementation[0], os.uname()[3],
"\nrun on", os.uname()[4])
print("====================================")
oled_i2c = machine.I2C(2)
print("Default I2C(2):", oled_i2c)
DISP_WIDTH=128
DISP_HEIGHT=64
# Raspberry Pi logo as 32x32 bytearray
fb_width=32
buffer = bytearray(b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|?\x00\x01\x86@\x80\x01\x01\x80\x80\x01\x11\x88\x80\x01\x05\xa0\x80\x00\x83\xc1\x00\x00C\xe3\x00\x00~\xfc\x00\x00L'\x00\x00\x9c\x11\x00\x00\xbf\xfd\x00\x00\xe1\x87\x00\x01\xc1\x83\x80\x02A\x82@\x02A\x82@\x02\xc1\xc2@\x02\xf6>\xc0\x01\xfc=\x80\x01\x18\x18\x80\x01\x88\x10\x80\x00\x8c!\x00\x00\x87\xf1\x00\x00\x7f\xf6\x00\x008\x1c\x00\x00\x0c \x00\x00\x03\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
# Load the raspberry pi logo into the framebuffer (the image is 32x32)
fb = framebuf.FrameBuffer(buffer, 32, 32, framebuf.MONO_HLSB)
def demo():
oled.fill(0)
oled.rect(0, 0, DISP_WIDTH, DISP_HEIGHT, 1)
oled.text('Hello coXXect', 5, 5, 1)
oled.text('SSD1315 OLED', 5, 15, 1)
oled.text('comp.to SSD1306', 5, 25, 1)
oled.show()
time.sleep(2)
oled.blit(fb, DISP_WIDTH-fb_width, 32)
oled.show()
time.sleep(1)
for i in range(DISP_WIDTH-fb_width, 0-1, -1):
oled.blit(fb, i, 32)
oled.show()
time.sleep(0.05)
oled = ssd1306.SSD1306_I2C(DISP_WIDTH, DISP_HEIGHT, oled_i2c)
print("Default SSD1306 I2C address:",
oled.addr, "/", hex(oled.addr))
#oled.rotate(False)
oled.invert(0)
oled.fill(1)
oled.show()
time.sleep(1)
oled.fill(0)
oled.show()
time.sleep(1)
demo()
#oled.rotate(True)
oled.invert(1)
demo()
time.sleep(1)
oled.invert(0)
time.sleep(1)
#oled.rotate(False)
oled.invert(0)
oled.fill(0)
step_width = fb_width+2
for i in range(0, DISP_WIDTH, step_width):
oled.blit(fb, i, 32)
oled.show()
time.sleep(0.5)
print("~ bye ~")
The following code basically ported from the post "Pico/MicroPython display on two OLED as one FrameBuffer".
mpyPYB_dualdisplay_one_framebuf.py, display on two OLEDs as one FrameBuffer.
"""
MicroPython/Pyboard exercise
Two display as one FrameBuffer
Two 0.96" 128x64 SSD1315(SSD1306) I2C OLED
oledl - I2C(1): scl=B6
sda=87
oledr - I2C(2): scl=B10
sda=B11
"""
import sys
import os
import time
import ssd1306
import framebuf
SSD1315_WIDTH=128
SSD1315_HEIGHT=64
print("====================================")
print(sys.implementation[0], os.uname()[3],
"\nrun on", os.uname()[4])
print("====================================")
oledl_I2C = machine.I2C(1)
print("Default I2C(1) for OLED on left:\t", oledl_I2C)
oledr_I2C = machine.I2C(2)
print("Default I2C(2) for OLED on right:\t", oledr_I2C)
"""
fb structure:
|<---------- fb_width=256 ---------->|
-------------- +==================+==================+
^ | 128x64 | 128x64 |
fb_height=64 | | |
v--------------+==================+==================+
^ ^
fb1_hoffset=0 fb2_hoffset=128
"""
# Raspberry Pi logo as 32x32 bytearray
fb_width=128+128
fb_height=64
fb1_hoffset=0
fb2_hoffset=128
buffer = bytearray(fb_width*fb_height)
fb = framebuf.FrameBuffer(buffer, fb_width, fb_height, framebuf.MONO_HLSB)
# Raspberry Pi logo as 32x32 bytearray
pi_fb_width=32
pi_fb_height=32
pi_buffer = bytearray(b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|?\x00\x01\x86@\x80\x01\x01\x80\x80\x01\x11\x88\x80\x01\x05\xa0\x80\x00\x83\xc1\x00\x00C\xe3\x00\x00~\xfc\x00\x00L'\x00\x00\x9c\x11\x00\x00\xbf\xfd\x00\x00\xe1\x87\x00\x01\xc1\x83\x80\x02A\x82@\x02A\x82@\x02\xc1\xc2@\x02\xf6>\xc0\x01\xfc=\x80\x01\x18\x18\x80\x01\x88\x10\x80\x00\x8c!\x00\x00\x87\xf1\x00\x00\x7f\xf6\x00\x008\x1c\x00\x00\x0c \x00\x00\x03\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
# Load the raspberry pi logo into the framebuffer (the image is 32x32)
pi_fb = framebuf.FrameBuffer(pi_buffer, 32, 32, framebuf.MONO_HLSB)
def update_display():
oledL.blit(fb, fb1_hoffset, 0)
oledR.blit(fb, -fb2_hoffset, 0)
oledL.show()
oledR.show()
oledL = ssd1306.SSD1306_I2C(SSD1315_WIDTH, SSD1315_HEIGHT, oledl_I2C)
print("OLED on Left I2C address:",
oledL.addr, "/", hex(oledL.addr))
oledR = ssd1306.SSD1306_I2C(SSD1315_WIDTH, SSD1315_HEIGHT, oledr_I2C)
print("OLED on Right I2C address:",
oledR.addr, "/", hex(oledR.addr))
fb.fill(1)
update_display()
time.sleep(0.5)
fb.fill(0)
update_display()
time.sleep(0.5)
fb.rect(0, 0, fb_width, fb_height, 1)
update_display()
time.sleep(0.5)
update_display()
time.sleep(1)
fb.fill(0)
time.sleep(0.5)
blitx = 0
blity = 0
xdir = 1
xlim = fb_width-pi_fb_width
ydir = 1
ylim = fb_height-pi_fb_height
while True:
fb.blit(pi_fb, blitx, blity)
update_display()
#prepare next round
blitx = blitx+xdir
if blitx == -1:
blitx=1
xdir=1
if blitx == xlim:
blitx=xlim-1
xdir=-1
blity = blity+ydir
if blity == -1:
blity=1
ydir=1
if blity == ylim:
blity=ylim-1
ydir=-1
print("~ bye ~")
mpyPYB_dualdisplay_one_framebuf_scroll.py, scroll text across two OLEDs.
"""
MicroPython/Pyboard exercise
Two display as one FrameBuffer
Scroll text across two displays
Two 0.96" 128x64 SSD1315(SSD1306) I2C OLED
oledl - I2C(1): scl=B6
sda=87
oledr - I2C(2): scl=B10
sda=B11
"""
import sys
import os
import time
import ssd1306
import framebuf
SSD1315_WIDTH=128
SSD1315_HEIGHT=64
print("====================================")
print(sys.implementation[0], os.uname()[3],
"\nrun on", os.uname()[4])
print("====================================")
oledl_I2C = machine.I2C(1)
print("Default I2C(1) for OLED on left:\t", oledl_I2C)
oledr_I2C = machine.I2C(2)
print("Default I2C(2) for OLED on right:\t", oledr_I2C)
"""
fb structure:
|<---------- fb_width=256 ---------->|
-------------- +==================+==================+
^ | 128x64 | 128x64 |
fb_height=64 | | |
v--------------+==================+==================+
^ ^
fb1_hoffset=0 fb2_hoffset=128
"""
# Raspberry Pi logo as 32x32 bytearray
fb_width=128+128
fb_height=64
fb1_hoffset=0
fb2_hoffset=128
buffer = bytearray(fb_width*fb_height)
fb = framebuf.FrameBuffer(buffer, fb_width, fb_height, framebuf.MONO_HLSB)
# Raspberry Pi logo as 32x32 bytearray
pi_fb_width=32
pi_fb_height=32
pi_buffer = bytearray(b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|?\x00\x01\x86@\x80\x01\x01\x80\x80\x01\x11\x88\x80\x01\x05\xa0\x80\x00\x83\xc1\x00\x00C\xe3\x00\x00~\xfc\x00\x00L'\x00\x00\x9c\x11\x00\x00\xbf\xfd\x00\x00\xe1\x87\x00\x01\xc1\x83\x80\x02A\x82@\x02A\x82@\x02\xc1\xc2@\x02\xf6>\xc0\x01\xfc=\x80\x01\x18\x18\x80\x01\x88\x10\x80\x00\x8c!\x00\x00\x87\xf1\x00\x00\x7f\xf6\x00\x008\x1c\x00\x00\x0c \x00\x00\x03\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
# Load the raspberry pi logo into the framebuffer (the image is 32x32)
pi_fb = framebuf.FrameBuffer(pi_buffer, 32, 32, framebuf.MONO_HLSB)
def update_display():
oledL.blit(fb, fb1_hoffset, 0)
oledR.blit(fb, -fb2_hoffset, 0)
oledL.show()
oledR.show()
oledL = ssd1306.SSD1306_I2C(SSD1315_WIDTH, SSD1315_HEIGHT, oledl_I2C)
print("OLED on Left I2C address:",
oledL.addr, "/", hex(oledL.addr))
oledR = ssd1306.SSD1306_I2C(SSD1315_WIDTH, SSD1315_HEIGHT, oledr_I2C)
print("OLED on Right I2C address:",
oledR.addr, "/", hex(oledR.addr))
fb.fill(1)
update_display()
time.sleep(0.5)
fb.fill(0)
update_display()
time.sleep(0.5)
fb.text("Hello",50,5)
fb.text("coXXect",50,15)
update_display()
for i in range(80):
fb.scroll(1, 0)
update_display()
time.sleep(0.5)
for i in range(40):
fb.scroll(-1, 1)
update_display()
time.sleep(0.5)
for i in range(40):
fb.scroll(0, -1)
update_display()
time.sleep(0.5)
for i in range(40):
fb.scroll(+1, +1)
update_display()
time.sleep(0.5)
print("~ bye ~")
mpyPYB_dualdisplay_one_framebuf_sq.py, draw squares across OLEDs.
"""
MicroPython/Pyboard exercise
Two display as one FrameBuffer
Draw squares across two displays
Two 0.96" 128x64 SSD1315(SSD1306) I2C OLED
oledl - I2C(1): scl=B6
sda=87
oledr - I2C(2): scl=B10
sda=B11
"""
import sys
import os
import time
import ssd1306
import framebuf
SSD1315_WIDTH=128
SSD1315_HEIGHT=64
print("====================================")
print(sys.implementation[0], os.uname()[3],
"\nrun on", os.uname()[4])
print("====================================")
oledl_I2C = machine.I2C(1)
print("Default I2C(1) for OLED on left:\t", oledl_I2C)
oledr_I2C = machine.I2C(2)
print("Default I2C(2) for OLED on right:\t", oledr_I2C)
"""
fb structure:
|<---------- fb_width=256 ---------->|
-------------- +==================+==================+
^ | 128x64 | 128x64 |
fb_height=64 | | |
v--------------+==================+==================+
^ ^
fb1_hoffset=0 fb2_hoffset=128
"""
# Raspberry Pi logo as 32x32 bytearray
fb_width=128+128
fb_height=64
fb1_hoffset=0
fb2_hoffset=128
buffer = bytearray(fb_width*fb_height)
fb = framebuf.FrameBuffer(buffer, fb_width, fb_height, framebuf.MONO_HLSB)
# Raspberry Pi logo as 32x32 bytearray
pi_fb_width=32
pi_fb_height=32
pi_buffer = bytearray(b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|?\x00\x01\x86@\x80\x01\x01\x80\x80\x01\x11\x88\x80\x01\x05\xa0\x80\x00\x83\xc1\x00\x00C\xe3\x00\x00~\xfc\x00\x00L'\x00\x00\x9c\x11\x00\x00\xbf\xfd\x00\x00\xe1\x87\x00\x01\xc1\x83\x80\x02A\x82@\x02A\x82@\x02\xc1\xc2@\x02\xf6>\xc0\x01\xfc=\x80\x01\x18\x18\x80\x01\x88\x10\x80\x00\x8c!\x00\x00\x87\xf1\x00\x00\x7f\xf6\x00\x008\x1c\x00\x00\x0c \x00\x00\x03\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
# Load the raspberry pi logo into the framebuffer (the image is 32x32)
pi_fb = framebuf.FrameBuffer(pi_buffer, 32, 32, framebuf.MONO_HLSB)
def update_display():
oledL.blit(fb, fb1_hoffset, 0)
oledR.blit(fb, -fb2_hoffset, 0)
oledL.show()
oledR.show()
oledL = ssd1306.SSD1306_I2C(SSD1315_WIDTH, SSD1315_HEIGHT, oledl_I2C)
print("OLED on Left I2C address:",
oledL.addr, "/", hex(oledL.addr))
oledR = ssd1306.SSD1306_I2C(SSD1315_WIDTH, SSD1315_HEIGHT, oledr_I2C)
print("OLED on Right I2C address:",
oledR.addr, "/", hex(oledR.addr))
fb.fill(1)
update_display()
time.sleep(0.5)
fb.fill(0)
update_display()
time.sleep(0.5)
# draw squares
pt0=[0, 0]
pt1=[fb_width-1, 0]
pt2=[fb_width-1, fb_height-1]
pt3=[0, fb_height-1]
num_of_step = 12
step_x = fb_width//num_of_step
step_y = fb_height//num_of_step
def draw_sq():
fb.line(pt0[0], pt0[1], pt1[0], pt1[1], 1)
fb.line(pt1[0], pt1[1], pt2[0], pt2[1], 1)
fb.line(pt2[0], pt2[1], pt3[0], pt3[1], 1)
fb.line(pt3[0], pt3[1], pt0[0], pt0[1], 1)
n=0
while n<num_of_step:
draw_sq()
update_display()
pt0[0]+=step_x
pt1[1]+=step_y
pt2[0]-=step_x
pt3[1]-=step_y
time.sleep(0.5)
n+=1
print("~ bye ~")
Comments
Post a Comment