Pico/MicroPython display on two OLED as one FrameBuffer

Exercises run on Raspberry Pi Pico/MicroPython v1.19.1, display on two OLED (1.3 inch 128x64 SH1106 I2C OLED and 0.91 inch 128x32 SSD1306 I2C OLED) as one FrameBuffer.

To install the driver os the OLEDs, refer to:
- Raspberry Pi Pico/MicroPython exercise using SH1106 I2C OLED
- Raspberry Pi Pico/MicroPython exercise using SSD1306 I2C OLED


mpyPico_dualdisplay_one_framebuf.py
floating icon across displays
"""
MicroPython/Raspberry Pi Pico exercise
Two display as one FrameBuffer

1.3 inch 128x64 SH1106 I2C OLED
I2C(0): scl=9
        sda=8
        
0.91 inch 128x32 SSD1306 I2C OLED
I2C(1): scl=7
        sda=6
"""
import sys
import os
import time
import sh1106
import ssd1306
import framebuf

SH1106_WIDTH=128
SH1106_HEIGHT=64
SSD1306_WIDTH=128
SSD1306_HEIGHT=32

print("====================================")
print(sys.implementation[0], os.uname()[3],
      "\nrun on", os.uname()[4])
print("====================================")

oled_ssd1306_I2c = machine.I2C(1)
print("Default I2C(1) for SSD1306:\t", oled_ssd1306_I2c)
oled_sh1106_I2c = machine.I2C(0)
print("Default I2C(0) for SH1106:\t", oled_sh1106_I2c)

"""
fb structure:
                |<- fb_width=128 ->|
    
 -------------- +==================+-<fb1_voffset=0
 ^              | 128x64           |
 fb_height=96   |                  |
                +------------------+-<fb2_voffset=64
 v              | 128x32           |
 -------------- +==================+----------
    

"""
# Raspberry Pi logo as 32x32 bytearray
fb_width=128
fb_height=96   # 64+32

fb1_voffset=0
fb2_voffset=64
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():
    oled_sh1106.blit(fb, 0, fb1_voffset)
    oled_ssd1306.blit(fb, 0, -fb2_voffset)
    oled_sh1106.show()
    oled_ssd1306.show()

oled_ssd1306 = ssd1306.SSD1306_I2C(SSD1306_WIDTH, SSD1306_HEIGHT, oled_ssd1306_I2c)
print("Default SSD1306 I2C address:",
      oled_ssd1306.addr, "/", hex(oled_ssd1306.addr))

oled_sh1106 = sh1106.SH1106_I2C(SH1106_WIDTH, SH1106_HEIGHT, oled_sh1106_I2c)
print("Default SH1106 I2C address:",
      oled_sh1106.addr, "/", hex(oled_sh1106.addr))
oled_sh1106.rotate(True)    
oled_ssd1306.rotate(True)

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 = fb2_voffset
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 ~")



mpyPico_dualdisplay_one_framebuf_scroll.py
scroll text across displays
"""
MicroPython/Raspberry Pi Pico exercise

1.3 inch 128x64 SH1106 I2C OLED
I2C(0): scl=9
        sda=8
        
0.91 inch 128x32 SSD1306 I2C OLED
I2C(1): scl=7
        sda=6
"""
import sys
import os
import time
import sh1106
import ssd1306
import framebuf

SH1106_WIDTH=128
SH1106_HEIGHT=64
SSD1306_WIDTH=128
SSD1306_HEIGHT=32

print("====================================")
print(sys.implementation[0], os.uname()[3],
      "\nrun on", os.uname()[4])
print("====================================")

oled_ssd1306_I2c = machine.I2C(1)
print("Default I2C(1) for SSD1306:\t", oled_ssd1306_I2c)
oled_sh1106_I2c = machine.I2C(0)
print("Default I2C(0) for SH1106:\t", oled_sh1106_I2c)

"""
fb structure:
                |<- fb_width=128 ->|
    
 -------------- +==================+-<fb1_voffset=0
 ^              | 128x64           |
 fb_height=96   |                  |
                +------------------+-<fb2_voffset=64
 v              | 128x32           |
 -------------- +==================+----------
    

"""
# Raspberry Pi logo as 32x32 bytearray
fb_width=128
fb_height=96   # 64+32

fb1_voffset=0
fb2_voffset=64
buffer = bytearray(fb_width*fb_height)
fb = framebuf.FrameBuffer(buffer, fb_width, fb_height, framebuf.MONO_HLSB)

def update_display():
    oled_sh1106.blit(fb, 0, fb1_voffset)
    oled_ssd1306.blit(fb, 0, -fb2_voffset)
    oled_sh1106.show()
    oled_ssd1306.show()

oled_ssd1306 = ssd1306.SSD1306_I2C(SSD1306_WIDTH, SSD1306_HEIGHT, oled_ssd1306_I2c)
print("Default SSD1306 I2C address:",
      oled_ssd1306.addr, "/", hex(oled_ssd1306.addr))

oled_sh1106 = sh1106.SH1106_I2C(SH1106_WIDTH, SH1106_HEIGHT, oled_sh1106_I2c)
print("Default SH1106 I2C address:",
      oled_sh1106.addr, "/", hex(oled_sh1106.addr))
oled_sh1106.rotate(True)
oled_ssd1306.rotate(True)

fb.text("Hello",3,76)
fb.text("coXXect",3,86)
update_display()
for i in range(60):
    fb.scroll(1, -1)
    update_display()
time.sleep(0.5)

for i in range(60):
    fb.scroll(0, 1)
    update_display()
time.sleep(0.5)

for i in range(60):
    fb.scroll(-1, -1)
    update_display()
time.sleep(0.5)

for i in range(60):
    fb.scroll(0, 1)
    update_display()
time.sleep(0.5)

print("~ bye ~")



mpyPico_dualdisplay_one_framebuf_sq.py
draw squares across displays
"""
MicroPython/Raspberry Pi Pico exercise

1.3 inch 128x64 SH1106 I2C OLED
I2C(0): scl=9
        sda=8
        
0.91 inch 128x32 SSD1306 I2C OLED
I2C(1): scl=7
        sda=6
"""
import sys
import os
import time
import sh1106
import ssd1306
import framebuf

SH1106_WIDTH=128
SH1106_HEIGHT=64
SSD1306_WIDTH=128
SSD1306_HEIGHT=32

print("====================================")
print(sys.implementation[0], os.uname()[3],
      "\nrun on", os.uname()[4])
print("====================================")

oled_ssd1306_I2c = machine.I2C(1)
print("Default I2C(1) for SSD1306:\t", oled_ssd1306_I2c)
oled_sh1106_I2c = machine.I2C(0)
print("Default I2C(0) for SH1106:\t", oled_sh1106_I2c)

"""
fb structure:
                |<- fb_width=128 ->|
    
 -------------- +==================+-<fb1_voffset=0
 ^              | 128x64           |
 fb_height=96   |                  |
                +------------------+-<fb2_voffset=64
 v              | 128x32           |
 -------------- +==================+----------
    

"""
# Raspberry Pi logo as 32x32 bytearray
fb_width=128
fb_height=96   # 64+32

fb1_voffset=0
fb2_voffset=64
buffer = bytearray(fb_width*fb_height)
fb = framebuf.FrameBuffer(buffer, fb_width, fb_height, framebuf.MONO_HLSB)

def update_display():
    oled_sh1106.blit(fb, 0, fb1_voffset)
    oled_ssd1306.blit(fb, 0, -fb2_voffset)
    oled_sh1106.show()
    oled_ssd1306.show()

oled_ssd1306 = ssd1306.SSD1306_I2C(SSD1306_WIDTH, SSD1306_HEIGHT, oled_ssd1306_I2c)
print("Default SSD1306 I2C address:",
      oled_ssd1306.addr, "/", hex(oled_ssd1306.addr))

oled_sh1106 = sh1106.SH1106_I2C(SH1106_WIDTH, SH1106_HEIGHT, oled_sh1106_I2c)
print("Default SH1106 I2C address:",
      oled_sh1106.addr, "/", hex(oled_sh1106.addr))
oled_sh1106.rotate(True)
oled_ssd1306.rotate(True)

pt0=[0, 0]
pt1=[fb_width-1, 0]
pt2=[fb_width-1, fb_height-1]
pt3=[0, fb_height-1]
num_of_step = 10
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 ~")



Related:
~ "Pyboard/MicroPython display on SSD1315 I2C OLED using SSD1306 driver" port it to Pyboard/SSD1315 (or SSD1306), two OLEDs arranged in horizontal.


Comments

Popular posts from this blog

MicroPython/ESP32-C3 + 1.8" 128x160 TFT ST7735 SPI, using boochow/MicroPython-ST7735 library.

CameraWebServe: ESP32-S3 (arduino-esp32) + OV5640 camera module