Raspberry Pi Pico 2/MicroPython display on SPI SSD1306 OLED
Last post show
how to install MicroPython ssd1306 driver on Raspberry Pi Pico 2 in Thonny,
and display on 0.96 inch 128x64 SSD1315 I2C OLED (SSD1306
compatible). Here is how to using the ssd1306 driver, display on
0.96 inch 128x64 SSD1306 SPI OLED.
Connection:
SPI SSD1306 OLED Raspberry Pi Pico 2
========================================
- D/C GP13
- RST GP12
- SDA GP11 (mosi)
- SCL GP10 (sck)
- VCC 3V3
- GND GND
GP9 (dummy cs) - No connection
GP8 (miso) - No connection
Notice that my SPI SSD1306 OLED is 6 pins version, no cs on board. But it's
required in ssd1306 driver, so I have to assign dummy GP9 for it. Also GP8 is
the SPI MISO, not use in this case.Exercise Code:
mpyPico2_SSD1306_spi_hello.py, a simple exercise to say Hello.
"""
MicroPython/Raspberry Pi Pico 2 exercise
display on 0.96" 128x64 SSD1306/SSD1306 SPI OLED.
(It should work on both Pico/Pico 2)
Install ssd1306 @ micropython-lib SSD1306 OLED driver (ver: 0.1.0)
in Thonny > Tools > Manager packages...
OLED is connected to SPI(1)
SCK - GP10
MOSI - GP11
MISO - GP8 (Not use)
"""
import sys
import os
import time
import ssd1306
DISP_WIDTH=128
DISP_HEIGHT=64
# notice that:
# parameter cs have to be provided to ssd1306.SSD1306_SPI(),
# so I assign a GP8 as dummt cs, no need connect it.
dc = machine.Pin(13)
res = machine.Pin(12)
cs = machine.Pin(9) #dummy (any un-used pin), no connection
print("====================================")
print(sys.implementation[0], os.uname()[3],
"\nrun on", os.uname()[4])
print("====================================")
package_info = ssd1306.__name__
try:
package_info = package_info + " ver:" + ssd1306.__version__
except AttributeError as exc:
print("AttributeError!", exc)
print("ssd1306 package: ", package_info)
print("====================================")
oled_spi = machine.SPI(1)
print("Using SPI:", oled_spi)
print()
try:
oled_ssd1306 = ssd1306.SSD1306_SPI(DISP_WIDTH, DISP_HEIGHT, oled_spi, dc, res, cs)
oled_ssd1306.fill(1)
oled_ssd1306.show()
time.sleep(1)
oled_ssd1306.fill(0)
oled_ssd1306.show()
time.sleep(1)
#oled_ssd1306.rect(0, 0, DISP_WIDTH, DISP_HEIGHT, 1)
oled_ssd1306.rect(1, 1, DISP_WIDTH-2, 25, 1)
oled_ssd1306.text('Hello, World!', 5, 5, 1)
oled_ssd1306.text(oled_ssd1306.__qualname__, 5, 15, 1)
oled_ssd1306.show()
"""
scroll() shift the contents of the FrameBuffer by the given vector.
This may leave a footprint of the previous colors in the FrameBuffer.
https://docs.micropython.org/en/latest/library/framebuf.html#framebuf.FrameBuffer.scroll
"""
while True:
for y in range(9):
oled_ssd1306.scroll(0, y)
oled_ssd1306.show()
time.sleep(0.2)
for y in range(9):
oled_ssd1306.scroll(0, -y)
oled_ssd1306.show()
time.sleep(0.2)
except OSError as exc:
print("OSError!", exc)
if exc.errno == errno.ENODEV:
print("No such device")
print("~ bye ~")
mpyPico2_SSD1306_spi_hello_fb.py, display a bitmap in framebuffer to move around.
"""
MicroPython/Raspberry Pi Pico exercise
display on 0.96" 128x64 SSD1306/SSD1306 SPI OLED, using FrameBuffer.
(It should work on both Pico/Pico 2)
Install ssd1306 @ micropython-lib SSD1306 OLED driver (ver: 0.1.0)
in Thonny > Tools > Manager packages...
OLED is connected to SPI(1)
SCK - GP10
MOSI - GP11
MISO - GP8 (Not use)
"""
import sys
import os
import time
import ssd1306
import framebuf
DISP_WIDTH=128
DISP_HEIGHT=64
dc = machine.Pin(13)
res = machine.Pin(12)
cs = machine.Pin(9) #dummy (any un-used pin), no connection
print("====================================")
print(sys.implementation[0], os.uname()[3],
"\nrun on", os.uname()[4])
print("====================================")
package_info = ssd1306.__name__
try:
package_info = package_info + " ver:" + ssd1306.__version__
except AttributeError as exc:
print("AttributeError!", exc)
print("ssd1306 package: ", package_info)
print("====================================")
oled_spi = machine.SPI(1)
print("Using SPI:", oled_spi)
print()
# 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)
"""
If you install another lib micropython-ssd1306 @ PyPI ssd1306 module for MicroPython (ver 0.3),
it's lack of rotate() function.
This function (rotate_screen()) is special handle it for information only, just skip rotate if:
AttributeError! 'SSD1306_I2C' object has no attribute 'rotate'
"""
def rotate_screen(rot=False):
try:
oled_ssd1306.rotate(rot)
except AttributeError as exc:
print("AttributeError!", exc)
def demo():
oled_ssd1306.fill(0)
oled_ssd1306.rect(0, 0, DISP_WIDTH, DISP_HEIGHT, 1)
oled_ssd1306.text('Hello', 5, 5, 1)
oled_ssd1306.text('coXXect', 5, 15, 1)
oled_ssd1306.show()
time.sleep(2)
oled_ssd1306.blit(fb, DISP_WIDTH-fb_width, 0)
oled_ssd1306.show()
time.sleep(1)
for i in range(DISP_WIDTH-fb_width, 0-1, -1):
oled_ssd1306.blit(fb, i, 0)
oled_ssd1306.show()
time.sleep(0.1)
try:
oled_ssd1306 = ssd1306.SSD1306_SPI(DISP_WIDTH, DISP_HEIGHT, oled_spi, dc, res, cs)
rotate_screen(False) #oled_ssd1306.rotate(False)
oled_ssd1306.invert(0)
oled_ssd1306.fill(1)
oled_ssd1306.show()
time.sleep(1)
oled_ssd1306.fill(0)
oled_ssd1306.show()
time.sleep(1)
demo()
rotate_screen(True) #oled_ssd1306.rotate(True)
oled_ssd1306.invert(1)
demo()
time.sleep(1)
oled_ssd1306.invert(0)
time.sleep(1)
rotate_screen() #oled_ssd1306.rotate(False)
oled_ssd1306.invert(0)
oled_ssd1306.fill(0)
step_width = fb_width+2
for i in range(0, DISP_WIDTH, step_width):
oled_ssd1306.blit(fb, i, 0)
oled_ssd1306.show()
time.sleep(0.5)
except OSError as exc:
print("OSError!", exc) # may be no connected to I2C OLED
print("~ bye ~")
mpyPico2_SSD1306_spi_myEquPolygon.py, exercise to display Equilateral Polygon.
"""
MicroPython/Raspberry Pi Pico 2 exercise
display on 0.96" 128x64 SSD1306/SSD1306 SPI OLED.
(It should work on both Pico/Pico 2)
To draw a Equilateral Polygon
Install ssd1306 @ micropython-lib SSD1306 OLED driver (ver: 0.1.0)
in Thonny > Tools > Manager packages...
OLED is connected to SPI(1)
SCK - GP10
MOSI - GP11
MISO - GP8 (Not use)
"""
import sys
import os
import time
import ssd1306
from array import array
import math
DISP_WIDTH=128
DISP_HEIGHT=64
# notice that:
# parameter cs have to be provided to ssd1306.SSD1306_SPI(),
# so I assign a GP8 as dummt cs, no need connect it.
dc = machine.Pin(13)
res = machine.Pin(12)
cs = machine.Pin(9) #dummy (any un-used pin), no connection
print("====================================")
print(sys.implementation[0], os.uname()[3],
"\nrun on", os.uname()[4])
print("====================================")
package_info = ssd1306.__name__
try:
package_info = package_info + " ver:" + ssd1306.__version__
except AttributeError as exc:
print("AttributeError!", exc)
print("ssd1306 package: ", package_info)
print("====================================")
oled_spi = machine.SPI(1)
print("Using SPI:", oled_spi)
print()
# === myEquPolygonClass class ===
class myEquPolygonClass:
def __init__(self, num_of_ends, r):
self.num_of_ends = num_of_ends
self.r = r
self.coords_list = []
for end in range(num_of_ends):
angle_in_radians = math.radians(360 * end/num_of_ends)
print("degree of end", end, angle_in_radians)
print(angle_in_radians, ":", math.sin(angle_in_radians), math.cos(angle_in_radians))
self.coords_list.append(int(r * math.sin(angle_in_radians)))
self.coords_list.append(int(r * math.cos(angle_in_radians)))
def show(self, screen, offset_x=0, offset_y=0, fill=0):
coords_array = array('h', self.coords_list)
screen.poly(offset_x, offset_y,
coords_array,
1, # color
fill) # optional fill: True - fill, False - not fill
screen.show()
# === End of myFixedPolygonClass ===
try:
oled_ssd1306 = ssd1306.SSD1306_SPI(DISP_WIDTH, DISP_HEIGHT, oled_spi, dc, res, cs)
oled_ssd1306.fill(1)
oled_ssd1306.show()
time.sleep(1)
oled_ssd1306.fill(0)
oled_ssd1306.show()
time.sleep(1)
center_x = int(oled_ssd1306.width/2)
center_y = int(oled_ssd1306.height/2)
myEquPolygon = myEquPolygonClass(6, 30)
fill = False
while True:
oled_ssd1306.fill(0)
oled_ssd1306.text('num_of_ends ' + str(myEquPolygon.num_of_ends), 5, 5, 1)
myEquPolygon.show(oled_ssd1306, center_x, center_y, fill)
fill = not fill
time.sleep(1)
except OSError as exc:
print("OSError!", exc)
if exc.errno == errno.ENODEV:
print("No such device")
print("~ bye ~")
mpyPico2_SSD1306_spi_myEquPolygon2.py and mpyPico2_SSD1306_spi_myEquPolygon3.py do the same thing, to change the polygon at runtime, different in how to recreate/update myEquPolygonClass object.
mpyPico2_SSD1306_spi_myEquPolygon2.py
"""
MicroPython/Raspberry Pi Pico 2 exercise
display on 0.96" 128x64 SSD1306/SSD1306 SPI OLED.
(It should work on both Pico/Pico 2)
To draw a Equilateral Polygon, change num_of_ends at runtime.
In this version, myEquPolygonClass object have to be re-created everytimes wanted to change parameters (num_of_ends, r).
To improve it, refer to mpyPico2_SSD1306_spi_myEquPolygon3.py.
Install ssd1306 @ micropython-lib SSD1306 OLED driver (ver: 0.1.0)
in Thonny > Tools > Manager packages...
OLED is connected to SPI(1)
SCK - GP10
MOSI - GP11
MISO - GP8 (Not use)
"""
import sys
import os
import time
import ssd1306
from array import array
import math
DISP_WIDTH=128
DISP_HEIGHT=64
# notice that:
# parameter cs have to be provided to ssd1306.SSD1306_SPI(),
# so I assign a GP8 as dummt cs, no need connect it.
dc = machine.Pin(13)
res = machine.Pin(12)
cs = machine.Pin(9) #dummy (any un-used pin), no connection
print("====================================")
print(sys.implementation[0], os.uname()[3],
"\nrun on", os.uname()[4])
print("====================================")
package_info = ssd1306.__name__
try:
package_info = package_info + " ver:" + ssd1306.__version__
except AttributeError as exc:
print("AttributeError!", exc)
print("ssd1306 package: ", package_info)
print("====================================")
oled_spi = machine.SPI(1)
print("Using SPI:", oled_spi)
print()
# === myEquPolygonClass class ===
class myEquPolygonClass:
def __init__(self, num_of_ends, r):
self.num_of_ends = num_of_ends
self.r = r
self.coords_list = []
for end in range(num_of_ends):
angle_in_radians = math.radians(360 * end/num_of_ends)
print("degree of end", end, angle_in_radians)
print(angle_in_radians, ":", math.sin(angle_in_radians), math.cos(angle_in_radians))
self.coords_list.append(int(r * math.sin(angle_in_radians)))
self.coords_list.append(int(r * math.cos(angle_in_radians)))
def show(self, screen, offset_x=0, offset_y=0, fill=0):
coords_array = array('h', self.coords_list)
screen.poly(offset_x, offset_y,
coords_array,
1, # color
fill) # optional fill: True - fill, False - not fill
screen.show()
# === End of myFixedPolygonClass ===
try:
oled_ssd1306 = ssd1306.SSD1306_SPI(DISP_WIDTH, DISP_HEIGHT, oled_spi, dc, res, cs)
oled_ssd1306.fill(1)
oled_ssd1306.show()
time.sleep(1)
oled_ssd1306.fill(0)
oled_ssd1306.show()
time.sleep(1)
center_x = int(oled_ssd1306.width/2)
center_y = int(oled_ssd1306.height/2)
fill = False
my_num_of_ends = 0
while True:
myEquPolygon = myEquPolygonClass(my_num_of_ends, 30)
oled_ssd1306.fill(0)
oled_ssd1306.text('num_of_ends ' + str(myEquPolygon.num_of_ends), 5, 5, 1)
myEquPolygon.show(oled_ssd1306, center_x, center_y, fill)
fill = not fill
time.sleep(1)
if fill == False:
if my_num_of_ends == 10:
my_num_of_ends = 0
else:
my_num_of_ends = my_num_of_ends + 1
except OSError as exc:
print("OSError!", exc)
if exc.errno == errno.ENODEV:
print("No such device")
print("~ bye ~")
mpyPico2_SSD1306_spi_myEquPolygon3.py
"""
MicroPython/Raspberry Pi Pico 2 exercise
display on 0.96" 128x64 SSD1306/SSD1306 SPI OLED.
(It should work on both Pico/Pico 2)
To draw a Equilateral Polygon, change num_of_ends at runtime.
Implement update_coords_list() in myEquPolygonClass class,
such that no need to re-create myEquPolygonClass object everytime wanted to change parameters.
Install ssd1306 @ micropython-lib SSD1306 OLED driver (ver: 0.1.0)
in Thonny > Tools > Manager packages...
OLED is connected to SPI(1)
SCK - GP10
MOSI - GP11
MISO - GP8 (Not use)
"""
import sys
import os
import time
import ssd1306
from array import array
import math
DISP_WIDTH=128
DISP_HEIGHT=64
# notice that:
# parameter cs have to be provided to ssd1306.SSD1306_SPI(),
# so I assign a GP8 as dummt cs, no need connect it.
dc = machine.Pin(13)
res = machine.Pin(12)
cs = machine.Pin(9) #dummy (any un-used pin), no connection
print("====================================")
print(sys.implementation[0], os.uname()[3],
"\nrun on", os.uname()[4])
print("====================================")
package_info = ssd1306.__name__
try:
package_info = package_info + " ver:" + ssd1306.__version__
except AttributeError as exc:
print("AttributeError!", exc)
print("ssd1306 package: ", package_info)
print("====================================")
oled_spi = machine.SPI(1)
print("Using SPI:", oled_spi)
print()
# === myEquPolygonClass class ===
class myEquPolygonClass:
def __init__(self, num_of_ends, r):
self.num_of_ends = num_of_ends
self.r = r
self.coords_list = []
self.reCal_coords_list()
def update_coords_list(self, num_of_ends, r):
self.num_of_ends = num_of_ends
self.r = r
self.coords_list.clear()
self.reCal_coords_list()
def reCal_coords_list(self):
for end in range(self.num_of_ends):
angle_in_radians = math.radians(360 * end/self.num_of_ends)
print("degree of end", end, angle_in_radians)
print(angle_in_radians, ":", math.sin(angle_in_radians), math.cos(angle_in_radians))
self.coords_list.append(int(self.r * math.sin(angle_in_radians)))
self.coords_list.append(int(self.r * math.cos(angle_in_radians)))
def show(self, screen, offset_x=0, offset_y=0, fill=0):
coords_array = array('h', self.coords_list)
screen.poly(offset_x, offset_y,
coords_array,
1, # color
fill) # optional fill: True - fill, False - not fill
screen.show()
# === End of myFixedPolygonClass ===
try:
oled_ssd1306 = ssd1306.SSD1306_SPI(DISP_WIDTH, DISP_HEIGHT, oled_spi, dc, res, cs)
oled_ssd1306.fill(1)
oled_ssd1306.show()
time.sleep(1)
oled_ssd1306.fill(0)
oled_ssd1306.show()
time.sleep(1)
center_x = int(oled_ssd1306.width/2)
center_y = int(oled_ssd1306.height/2)
fill = False
my_num_of_ends = 0
myEquPolygon = myEquPolygonClass(my_num_of_ends, 30)
while True:
myEquPolygon.update_coords_list(my_num_of_ends, 30)
oled_ssd1306.fill(0)
oled_ssd1306.text('num_of_ends ' + str(myEquPolygon.num_of_ends), 5, 5, 1)
myEquPolygon.show(oled_ssd1306, center_x, center_y, fill)
fill = not fill
time.sleep(1)
if fill == False:
if my_num_of_ends == 10:
my_num_of_ends = 0
else:
my_num_of_ends = my_num_of_ends + 1
except OSError as exc:
print("OSError!", exc)
if exc.errno == errno.ENODEV:
print("No such device")
print("~ bye ~")
next:~ Raspberry Pi Pico 2 (RP2350)/MicroPython display on two OLED, SSD1306 I2C and SPI.
Comments
Post a Comment