Raspberry Pi 4 で小さなSSD1306 OLEDディスプレーに文字を表示させてみた

2020.05.16

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

最近リモートワーク中のおうちの室内のCO2濃度が気になり、計測したい&遊んでみたい、という気持ちでRaspberry Piに入門しました。モノクロのディスプレーに惹かれて、ついでに0.96インチの小さなOLEDディスプレーモジュールも購入しました。

今回はこのディスプレーに文字を表示することをゴールとします。また手軽に動かせるということでCircuitPythonを利用することとします。

環境

  • 128×64 OLED display module (SSD1306)
  • Raspberry Pi 4 Model B
  • Raspbian 10

やってみる

Raspberry Piとディスプレーを接続

今回はメス-メスのデュポンワイヤーで↓のように接続します。

[ディスプレー] -> [GPIO]

  • GND -> Ground (14)
  • VDD -> 3V3 power (1)
  • SCK -> GPIO 3 (5)
  • SDA -> GPIO 2 (3)

GPIO - Raspberry Pi Documentation

Raspberry PiでI2Cを有効にする

Raspberry Piに入りraspi-configを起動

sudo raspi-config

5 Interfacing Options を選択

P5 I2C を選択

Would you like the ARM I2C interface to be enabled を Yes と選択

再起動して有効化

sudo reboot

再起動後設定が反映され、デバイスが検出される事を確認

sudo i2cdetect -y 1

i2cdetect(8) - Linux man page

CircuitPython ドライバの導入

CircuitPythonって何だ?

CircuitPython is a beginner friendly, open source version of Python for tiny, inexpensive computers called microcontrollers.

GitHub - adafruit/circuitpython: CircuitPython - a Python implementation for teaching coding with microcontrollers より

CircuitPython adds the Circuit part to the Python part. Letting you program in Python and talk to Circuitry like sensors, motors, and LEDs!

Overview | CircuitPython on Linux and Raspberry Pi | Adafruit Learning System より

初心者に優しくチープな環境でも動くPythonで、センサー/モーター/LED なんかを操作できる。と覚えときます。

インストール

GitHub - adafruit/Adafruit_CircuitPython_SSD1306: Adafruit CircuitPython framebuf driver for SSD1306 or SSD1305 OLED displays. Not for use with displayio. See README.

pip3 install adafruit-circuitpython-ssd1306

表示させる

READMEページのUsage Examplesは表示を初期化するだけのコードのようです。git cloneするなりし、 examples の中の ssd1306_pillow_demo.py の初期設定しているブロックのHEIGHTだけ、ディスプレーのサイズに合わせて64に変更します。

"""
This demo will fill the screen with white, draw a black box on top
and then print Hello World! in the center of the display
This example is for use on (Linux) computers that are using CPython with
Adafruit Blinka to support CircuitPython libraries. CircuitPython does
not support PIL/pillow (python imaging library)!
"""

import board
import digitalio
from PIL import Image, ImageDraw, ImageFont
import adafruit_ssd1306

# Define the Reset Pin
oled_reset = digitalio.DigitalInOut(board.D4)

# Change these
# to the right size for your display!
WIDTH = 128
#HEIGHT = 32  # Change to 64 if needed
HEIGHT = 64  # Change to 64 if needed
BORDER = 5

# Use for I2C.
i2c = board.I2C()
oled = adafruit_ssd1306.SSD1306_I2C(WIDTH, HEIGHT, i2c, addr=0x3C, reset=oled_reset)

# Use for SPI
# spi = board.SPI()
# oled_cs = digitalio.DigitalInOut(board.D5)
# oled_dc = digitalio.DigitalInOut(board.D6)
# oled = adafruit_ssd1306.SSD1306_SPI(WIDTH, HEIGHT, spi, oled_dc, oled_reset, oled_cs)

# Clear display.
oled.fill(0)
oled.show()

# Create blank image for drawing.
# Make sure to create image with mode '1' for 1-bit color.
image = Image.new("1", (oled.width, oled.height))

# Get drawing object to draw on image.
draw = ImageDraw.Draw(image)

# Draw a white background
draw.rectangle((0, 0, oled.width, oled.height), outline=255, fill=255)

# Draw a smaller inner rectangle
draw.rectangle(
    (BORDER, BORDER, oled.width - BORDER - 1, oled.height - BORDER - 1),
    outline=0,
    fill=0,
)

# Load default font.
font = ImageFont.load_default()

# Draw Some Text
text = "Hello!"
(font_width, font_height) = font.getsize(text)
draw.text(
    (oled.width // 2 - font_width // 2, oled.height // 2 - font_height // 2),
    text,
    font=font,
    fill=255,
)

# Display image
oled.image(image)
oled.show()

そして実行

python3 ssd1306_pillow_demo.py

おお、美しい。。

最後に

Pythonの高レベルなAPIを利用することで、簡単にディスプレーに表示することができました。敷居が低く早く動かせるのはかなり価値があるし、何より楽しいですね!