ESP32-S3/CircuitPython to drive SSD1331 SPI color OLED

This exercise run on ESP32-S3-DevKitC-1/CircuitPython 7.3.2, to drive 0.95 inch 96x64 SSD1331 SPI Color OLED.

adafruit_ssd1331.mpy, adafruit_display_shapes and adafruit_display_text folders are needed, upload to CircuitPython device's /lib folder. If you don't know how to download and install Adafruit Library, read here.



The original ssd1331_simpletest.py not work on ESP32-S3, here cpyS3_ssd1331_simpletest.py is my modified version work on ESP32-S3-DevKitC-1.
"""
Simple Test 0.95" 96x64 SSD1331 SPI Color OLED
run on ESP32-S3-DevKitC-1/CircuitPython
modified from ssd1331_simpletest.py example

Connection:
SSD1331    ESP32-S3-DevKitC-1
-----------------------------
GND        GND
VCC        3V3
SCL        IO12
SDA        IO11
RES        IO4
DC         IO5
CS         IO6

"""
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT

"""
This test will initialize the display using displayio
and draw a solid green background, a smaller purple
rectangle, and some yellow text.
"""

import board
import terminalio
import displayio
from adafruit_display_text import label
from adafruit_ssd1331 import SSD1331
import busio

# Release any resources currently in use for the displays
displayio.release_displays()

# init display
disp_clk = board.IO12
disp_mosi = board.IO11
disp_spi = busio.SPI(clock=disp_clk, MOSI=disp_mosi)

disp_res = board.IO4
disp_dc  = board.IO5
disp_cs  = board.IO6

display_bus = displayio.FourWire(
    disp_spi,
    command=disp_dc,
    chip_select=disp_cs,
    reset=disp_res
)

display = SSD1331(display_bus,
                  width=96, height=64)
#=======================================
# Make the display context
splash = displayio.Group()
display.show(splash)

color_bitmap = displayio.Bitmap(96, 64, 1)
color_palette = displayio.Palette(1)
color_palette[0] = 0x00FF00  # Bright Green

bg_sprite = displayio.TileGrid(color_bitmap,
                               pixel_shader=color_palette,
                               x=0, y=0)
splash.append(bg_sprite)

# Draw a smaller inner rectangle
inner_bitmap = displayio.Bitmap(86, 54, 1)
inner_palette = displayio.Palette(1)
inner_palette[0] = 0xAA0088  # Purple
inner_sprite = displayio.TileGrid(inner_bitmap,
                                  pixel_shader=inner_palette,
                                  x=5, y=5)
splash.append(inner_sprite)

# Draw a label
text = "Hello World!"
text_area = label.Label(terminalio.FONT,
                        text=text,
                        color=0xFFFF00,
                        x=12, y=32)
splash.append(text_area)

while True:
    pass



cpyS3_ssd1331_random.py, exercise to display random pixel.
"""
0.95" 96x64 SSD1331 SPI Color OLED
run on ESP32-S3-DevKitC-1/CircuitPython 7.3.2
display random pixel

Connection:
SSD1331    ESP32-S3-DevKitC-1
-----------------------------
GND        GND
VCC        3V3
SCL        IO12
SDA        IO11
RES        IO4
DC         IO5
CS         IO6
"""

import board
import terminalio
import displayio
from adafruit_display_text import label
import adafruit_ssd1331
import busio
import random
import time

# Release any resources currently in use for the displays
displayio.release_displays()

# init display
disp_width = 96
disp_height = 64

disp_clk = board.IO12
disp_mosi = board.IO11
disp_spi = busio.SPI(clock=disp_clk, MOSI=disp_mosi)

disp_res = board.IO4
disp_dc  = board.IO5
disp_cs  = board.IO6

display_bus = displayio.FourWire(
    disp_spi,
    command=disp_dc,
    chip_select=disp_cs,
    reset=disp_res
)

display = adafruit_ssd1331.SSD1331(display_bus,
                  width=disp_width, height=disp_height)

print(adafruit_ssd1331.__name__,
      adafruit_ssd1331.__version__)
#=======================================
# Make the display context
splash = displayio.Group()
display.show(splash)

color_of_bg = 256
color_bitmap = displayio.Bitmap(disp_width,
                                disp_height,
                                color_of_bg)
color_palette = displayio.Palette(color_of_bg)
#color_palette[0] = 0x00FF00  # Bright Green
# create random color_palette
color_palette[0] = 0x000000   # black
for c in range(1, color_of_bg):    
    color_palette[c]=(random.randrange(255)*0x10000 +
                      random.randrange(255) * 0x100 +
                      random.randrange(255))

    
bg_sprite = displayio.TileGrid(color_bitmap,
                               pixel_shader=color_palette,
                               x=0, y=0)
splash.append(bg_sprite)

while True:
    x = random.randrange(disp_width)
    y = random.randrange(disp_height)
    c = random.randrange(color_of_bg)
    color_bitmap[x, y]=c
    time.sleep(0.01)

print("~ bye ~")


cpyS3_ssd1331_label.py, show label over random pixel.
"""
0.95" 96x64 SSD1331 SPI Color OLED
run on ESP32-S3-DevKitC-1/CircuitPython 7.3.2
display random pixel, with toggle label.

Connection:
SSD1331    ESP32-S3-DevKitC-1
-----------------------------
GND        GND
VCC        3V3
SCL        IO12
SDA        IO11
RES        IO4
DC         IO5
CS         IO6
"""

import board
import terminalio
import displayio
from adafruit_display_text import label
import adafruit_ssd1331
import busio
import random
import time
from adafruit_display_shapes.roundrect import RoundRect
import gc

# Release any resources currently in use for the displays
displayio.release_displays()

# init display
disp_width = 96
disp_height = 64

disp_clk = board.IO12
disp_mosi = board.IO11
disp_spi = busio.SPI(clock=disp_clk, MOSI=disp_mosi)

disp_res = board.IO4
disp_dc  = board.IO5
disp_cs  = board.IO6

display_bus = displayio.FourWire(
    disp_spi,
    command=disp_dc,
    chip_select=disp_cs,
    reset=disp_res
)

display = adafruit_ssd1331.SSD1331(display_bus,
                  width=disp_width, height=disp_height)

print(adafruit_ssd1331.__name__,
      adafruit_ssd1331.__version__)
#=======================================
# Make the display context
splash = displayio.Group()
display.show(splash)

color_of_bg = 256
color_bitmap = displayio.Bitmap(disp_width, disp_height, color_of_bg)
color_palette = displayio.Palette(color_of_bg)
#color_palette[0] = 0x00FF00  # Bright Green
# create random color_palette
color_palette[0] = 0x000000   # black
for c in range(1, color_of_bg):    
    color_palette[c]=(random.randrange(255)*0x10000 +
                      random.randrange(255) * 0x100 +
                      random.randrange(255))

    
bg_sprite = displayio.TileGrid(color_bitmap,
                               pixel_shader=color_palette,
                               x=0, y=0)

#================================================
#prepare Label of title
title = ("ESP32-S3", "CircuitPython", "SSD1331 OLED")
group_title = displayio.Group(scale=1)

label_title = label.Label(terminalio.FONT,
                        text=title[0]+"\n"+
                          title[1]+"\n"+
                          title[2],
                        color=0xFFFFFF)
label_title.anchor_point = (0.0, 0.0)
label_title.anchored_position = (0, 0)
label_title_width = label_title.bounding_box[2]
label_title_height = label_title.bounding_box[3]
shape_title = RoundRect(x=-2, y=-2,
                        width=label_title_width+4,
                        height=label_title_height+4,
                        r=5,
                        fill=0x000000,
                        outline=0xFFFFFF, stroke=1)
group_title.x = (disp_width-label_title_width)//2
group_title.y = (disp_height-label_title_height)//2
group_title.append(shape_title)
group_title.append(label_title)
#================================================
splash.append(bg_sprite)
splash.append(group_title)

"""
In beginning, I suppose to update label_title
and shape_title at runtime.
But I found that I cannot update shape_title
at runtime.
So I remove both label_title and shape_title,
update label_title and create another shape_title,
then append back.
Such that I have to call gc.collect() repeatly,
otherwise mem_free will decrease when it run.
"""
def toggle_title():
    global title_index
    global label_title
    global shape_title
    global group_title
    
    group_title.remove(shape_title)
    group_title.remove(label_title)
    
    title_index=title_index+1
    if title_index==len(title):
        title_index=0
    #print(title[title_index])
    label_title.text = title[title_index]

    lt_width = label_title.bounding_box[2]
    lt_height = label_title.bounding_box[3]
    shape_title = RoundRect(x=-5, y=-5,
                            width=lt_width+10,
                            height=lt_height+10,
                            r=10,
                            fill=0x000000,
                            outline=0xFFFFFF,
                            stroke=1)
    group_title.x = (disp_width-lt_width)//2
    group_title.y = (disp_height-lt_height)//2
    group_title.append(shape_title)
    group_title.append(label_title)
    
title_index=len(title)-1
next_dur = 3.0
next_time = time.monotonic() + next_dur
while True:
    x = random.randrange(disp_width)
    y = random.randrange(disp_height)
    c = random.randrange(color_of_bg)
    color_bitmap[x, y]=c
    
    #toggle label in 3 seconds
    now = time.monotonic()
    if now >= next_time:
        next_time = now+next_dur
        toggle_title()
        print(gc.mem_free())
        gc.collect()
        print(gc.mem_free())
        print("-----------")
    
    time.sleep(0.01)

print("~ bye ~")


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