稼働中

Raspberry Pi Pico(d_34)SSD1306 OLED ディスプレイドライバー

SSD1306 OLED (I2C)

SSD1306 OLED(有機LED) ディスプレイには、インタフェースがSPIとI2C のもの、サイズが128×64, 128×32, 72×40, 64×48、カラーが白、黄色、青、黄色+青があるそうです。
Raspberry Pi PicoのmicropythonでSSD1306 OLEDを簡単に使えるモジュールがあります。
入手先は「https://github.com/stlehmann/micropython-ssd1306/blob/master/ssd1306.py」です。
「ssd1306.py」は、I2C、SPI通信に対応しているようです。
この記事では、OLED SSD1306 128×64をI2C通信で接続して操作します。
※開発環境はThonnyです。ThonnyでMicroPythonをRaspberry Pi Pico with RP2040にインストールして使っています。

外観

SSD1306 OLED 128×64 (黄色+青) ディスプレイの外観写真です。(以後はSSD1306と記載します)
「https://micropython-docs-ja.readthedocs.io/ja/latest/esp8266/tutorial/ssd1306.html」にあるMicroPython のロゴとテキストを表示させています。
OLED SSD1306 外観

接続例

OLED SSD1306は3.3Vから動作するのでRaspberry Pi Picoと直接接続できます。I2C接続するだけです。
I2C通信にはI2C0のSDA(GP16)SCL(GP17)を使いました。
OLED SSD1306 接続例
接続出来たらI2Cデバイスのスレーブアドレスを調べてみます。
ThonnyのShellで確認しました。
SSD1306のスレーブアドレスは以下のように60(0x3c)でした。


>>> from machine import I2C, Pin
>>> i2c = I2C(0, scl=Pin(17), sda=Pin(16), freq=400_000)
>>> i2c.scan()
[60]
>>> 

SSD1306の説明

「https://micropython-docs-ja.readthedocs.io/ja/latest/esp8266/tutorial/ssd1306.html」から「ssd1306.py」を入手します。
クリップボードにコピーしてThonnyに貼り付けます。
ssd1306.py 入手先
ツールバーのNewを選択してスクリプトを貼り付けます。
ssd1306.py コピペ
ファイルの保存場所をRaspberryPi Picoを選択して「ssd1306.py」名で保存します。
※一旦、This computerに保存してから、別途RaspberryPi Picoに保存してもいいです。
ssd1306.py 保存場所
「ssd1306.py」名を入力してOKをクリックします。これでインポートできるようになります。
ssd1306.py 保存確認
「ssd1306.py」の中身を見ていくと、
ssd1306.py -1
framebufをインポートしているので、<class ‘FrameBuffer’>が使えるようです。
これでSSD1306の印字操作ができます。

framebuf.FrameBufferのメソッド
fill、fill_rect、pixel、hline、vline、rect、line、blit、scroll、textが使えるようです。
このうち、いくつかについて下方のスクリプトで試します。

続けて見ていくと、poweroff、poweron、contrast、invert、showのメソッドがあります。
ssd1306.py -2
さらに見ていくと、class SSD1306_I2CとSSD1306_SPIがありI2CとSPI通信が使えるようです。
この記事ではclass SSD1306_I2Cを使います。

初期化は
SSD1306_I2C(width, height, i2c, addr=0x3C, external_vcc=False)
となっています。

i2cは先に設定した
i2c = I2C(0, scl=Pin(17), sda=Pin(16), freq=400_000)
です。

addr=0x3Cとあります。先に調べたSSD1306のスレーブアドレスと合っています。
またディスプレイサイズは 128×64 なので
SSD1306_I2C(128, 64, i2c)
で初期化します。
ssd1306.py -3
ThonnyのShellでインポートできるか確認してみます。


>>> from machine import I2C, Pin
>>> i2c = I2C(0, scl=Pin(17), sda=Pin(16), freq=400_000)
>>> i2c.scan()
[60]
>>> from ssd1306 import SSD1306_I2C
>>> oled=SSD1306_I2C(128, 64, i2c)
>>> oled.fill(1)            # 全128x64セット
>>> oled.show()             # 表示            下の画像
>>> 
>>> oled.poweroff()         # 画面OFF
>>> oled.poweron()          # 画面ON
>>> 
>>> oled.fill(0)            # 全128x64リセット
>>> oled.show()             # 表示
>>> 

以下は実行結果(全pixel 128×64セット後の表示状態)です。
SSD1306 全画面点灯

スクリプト

SSD1306のスクリプトは以下のようにしました。
順次、以下を描画しています。
rect(x, y, w, h, c)で短形を描画
line(x1, y1, x2, y2, c)で線を描画
pixel(x, y)で点のcolorデータを取得
pixel(x, y, c)で点を描画
fill_rect(x, y, w, h, c)で塗りつぶした短形を描画
text(s, x, y, c)で指定した文字列を描画
※w:width, h:hight, c:color s:文字列

※Raspberry Pi Pico単独で動作させるには’main.py’としてRaspberry Pi Picoにuploadして使います。


pico_ssd1306_test_01b.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from machine import I2C, Pin
from ssd1306 import SSD1306_I2C
import time
import urandom
# i2c set
i2c = I2C(0, scl=Pin(17), sda=Pin(16), freq=400_000)
# SSD1306 128x64 0~127 0~63
oled=SSD1306_I2C(128, 64, i2c) #width,hight,external_vcc

def d_cls():
    oled.fill(0)
    oled.show()
    time.sleep(1)

# rect, line ---------------------
d_cls()
oled.rect(0, 0, 127, 63,1)
oled.show()
time.sleep(1)
for i in range(8,128,8):
    x=int(i)
    y=int(i/2)
    #print(x,y)
    oled.rect(0,0,x,y,1)
    oled.show()
    time.sleep(0.1)
time.sleep(1)

oled.line(0, 0, 127, 63,1)
oled.show()
time.sleep(2)

# pixcel ---------------------
#pixelのcolourデータを取得
print('pixel(127,63)=', oled.pixel(127,63))
d_cls()
for i in range(32):
    x=urandom.randrange(127)
    y=urandom.randrange(63)
    #print(x,y)
    oled.pixel(x,y,1)
    oled.show()
    time.sleep(0.1)
time.sleep(2)

# fill_rect ---------------------
d_cls()
for i in range(16):    
    x=urandom.getrandbits(7)
    y=urandom.getrandbits(6)
    w=x+1
    h=y+1
    #print(x,y)
    #oled.pixel(x,y,1)
    oled.fill_rect(x,y,8,8,1)
    oled.show()
    time.sleep(0.1)
time.sleep(2)

# text ---------------------
d_cls()
oled.text('MicroPython', 10, 5, 1)
oled.text('SSD1306', 20, 20, 1)
oled.text('OLED 128x64', 20, 35, 1)

# contrast---------------------
for i in range(5):
    #print('contrast')
    oled.contrast(0)
    oled.show()
    time.sleep(0.5)
    oled.contrast(255)
    oled.show()
    time.sleep(0.5)
time.sleep(1)

d_cls()
oled.poweroff()

実行結果

結果は以下のようになりました。
pixel(127,63)の値はThonnyのshellに表示されます。


>>> %Run -c $EDITOR_CONTENT
pixel(127,63)= 1
>>> 

動画

まとめ

Raspberry Pi PicoでOLED SSD1306の動作を確認しました。