ラズパイ5で128×64 OLEDディスプレイモジュール(SSD1306搭載)を動かしてみた

当ページのリンクには広告が含まれています。

Raspberry Pi 5で小型ディスプレイを使ってみたいと思い、今回はOLEDディスプレイモジュール(SSD1306搭載)を動かしてみました。

このモジュールは、電子工作で良く使われる小型OLEDディスプレイです。黒背景に文字が見やすく表示されるので、センサー値の表示などに便利です。I2C接続のため必要な配線が少なく、比較的手軽に扱えるのもポイント。

この記事では、SSD1306 OLEDモジュールの配線、I2Cの接続確認、Pythonを使った表示方法まで、Raspberry Pi 5を使って実際に動かしながら順番に解説していきます。

目次

はじめに

今回は、ラズパイ5にOLEDディスプレイモジュール(SSD1306)を接続し、I2C制御でディスプレイに文字を表示できるようにします。


流れとしては、「配線→I2Cの有効化 → デバイスの認識確認(i2cdetect)→ ライブラリのインストール → 画面に文字を表示」という感じです。やることはシンプルですが、I2Cデバイスの基本的な扱い方が分かるので、今後センサーや他のデバイスをつなぐときにも活用できます。

OLEDディスプレイモジュール(SSD1306)とは?

今回使用するディスプレイモジュールは、「OLEDディスプレイ」と「SSD1306」という2つの要素で構成されています。

OLEDは、有機ELを使った小型ディスプレイのことです。バックライトなしで発光するため、黒背景に文字がくっきり表示されるのが特徴で、電子工作ではセンサー値やシステム情報の表示によく使われています。

SSD1306は、そのOLEDディスプレイを制御するためのコントローラチップです。ラズパイやArduinoから送られてきたデータを受け取り、実際に画面へ表示する役割を担当しています。

つまり、

  • OLED = 「表示画面」
  • SSD1306 = 「画面を制御するIC」

という関係になります。

現在は、このSSD1306を搭載した128×64の小型OLEDモジュールが広く流通しており、I2C接続に対応したものは4ピンのピンヘッダで外部接続します。

表示色にはいくつか種類があり、

  • 白単色
  • 青単色
  • 上部が黄色、下部が青色のツートンカラー

といったタイプがよく流通しています。機能的な違いはほとんどないので、見た目の好みで選んで大丈夫です。

今回は「青単色」タイプを使用します。

I2C接続について

今回使用するI2C(アイツーシー)接続は、シリアル通信のため配線が少なくて済みます。
通常、ディスプレイを制御しようとするとたくさんのピンが必要になりますが、I2Cなら以下の4本だけでOKです。

  • 電源(VCC)
  • GND
  • SDA(データ線)
  • SCL(クロック線)

さらに、I2Cは同じバスに複数のデバイスを接続できる仕組みになっているので、将来的にセンサーを追加するのも簡単です。

「とりあえず1つつないでみて、あとから拡張したい」という用途にもぴったりです。

使用する機材

今回の製作で使用するパーツはそれほど多くありません。SSD1306はI2C接続に対応しているため、少ない配線で手軽に接続できるのが特徴です。

今回使用するパーツ一覧

まずは、今回使用するパーツを一覧で確認しておきましょう。

パーツ数量用途
Raspberry Pi 51SSD1306の制御
OLEDモジュール(SSD1306)1テキストや情報の表示
ブレッドボード1配線を簡単に行うために使用
ジャンパ線(オス-メス)4ラズパイ5とブレッドボード間の接続用
プルアップ抵抗(不要※)

※プルアップ抵抗は通常、SSD1306モジュール側に実装済みなので不要です。

各パーツについて

ここでは、今回使用する各パーツについて簡単に紹介します。

ラズパイ5

ラズパイ5は、先日組み立てたPironman 5 miniを使います。詳しい内容は以下の記事を参照してください。

128×64ドットOLEDモジュール(SSD1306)

SSD1306搭載OLEDモジュールは、秋月のものを使います。表示サイズは128×64ドット、表示色は青です。

今回はI2Cタイプを使いますが、SSD1306は見た目が似ていても「SPI接続タイプ」と「I2C接続タイプ」があるので、I2C対応のものを選ぶ点に注意してください。

I2Cスレーブアドレスは「3C」か「3D」のいずれかが設定可能です。今回使用するモジュールはアドレス選択用パッドが基板に用意されており、実装状態に応じてアドレスを選択可能になっているようです。

ブレッドボード

ブレッドボードがあると配線しやすくなります。今回は以下のものを使用しした。上下にある電源ラインは今回使用しませんが、今後の拡張性を考えて電源ライン付きのものを使います。

ジャンパ線

ジャンパ線は、「オス-メス」タイプを4本使います。

色は何でもいいですが、電源についてはVCC→赤、GND→黒のように色を決めておくと分かりやすくなります。

外付けプルアップ抵抗は不要

I2C通信では4.7kΩ〜10kΩ程度のプルアップ抵抗が必要ですが、市販のSSD1306 OLEDモジュールはプルアップ抵抗実装済みのものが多いようです。

今回使用するモジュールの回路図は見当たらないのですが、基板を見ると4.7kΩのチップ抵抗が複数実装されています。おそらくI2C通信のプルアップ抵抗だと思われるので、外付けのプルアップ抵抗は使用しません。

仮に外付けのプルアップ抵抗がなかった場合でも、ラズパイ5のI2C端子には弱い内部プルアップ抵抗が入っているため、今回のようなシンプル回路であれば問題なく動作すると思います。

SSD1306 OLEDモジュールをラズパイ5に接続する

ここからは、SSD1306 OLEDモジュールを実際にラズパイ5へ接続していきます。

今回使用するSSD1306モジュールは、I2C通信に対応したタイプです。I2Cは少ない本数で接続できるのが特徴で、電源を含めて4本だけで接続できます。

回路図

回路図は非常にシンプルですね。ラズパイ5のピンヘッダとSSD1306モジュールの間で線4本が接続されているだけです。

ラズパイ5のピンヘッダは、以下のピンを使用します。

  • VCC → 3.3V(1 pin)
  • SDA → GPIO2(3 Pin)
  • SCL → GPIO3(5 Pin)
  • GND → GND(9 Pin)

SDAはデータ通信用の線で、SCLはクロック(通信のタイミング)用の線です。

結線図

結線図は以下のとおりです。

ブレッドボードにディスプレイを配置し、ジャンパ線4本で結線します。配線自体はシンプルなので難しくないと思います。

Lチカのときにも書きましたが、ラズパイ5のピンヘッダに配線するときは電源を確実に切っておくことに注意しましょう。

一通り配線が終わったら、電源を投入する前に間違いがないか確認します。特に電源(VCC、GND)の接続は、間違いがないかどうか入念にチェックしておきます。

ブレッドボードは見た目以上に差し間違いが起きやすいので、配線後に一度ゆっくり確認するのがおすすめです。

I2Cの有効化と接続確認

配線が終わったら、ラズパイ5側の設定を行っていきます。

I2Cを有効化する

まずは、ラズパイ側でI2C機能を有効化します。初期状態では無効になっていることがあるため、この設定は必ず行っておきます。

コマンドからも設定できますが、デスクトップ画面のスタートメニューから「設定」→ 「Control Centre」を開き、インターフェースの項目からI2Cを有効化することもできます。

i2c-toolsのインストール

次に、I2Cデバイスが認識されているか確認するためのツールをインストールします。

sudo apt update
sudo apt install -y i2c-tools

このツールを使うことで、「ちゃんと配線できているか?」を簡単にチェックできます。トラブルの切り分けにも使えるので、インストールしておきます。

i2cdetectで接続確認する

それでは、接続確認してみます。i2c-toolsに含まれるコマンド「i2cdetect」を実行してださい。

i2cdetect -y 1
  • y → 対話を無視するオプション
  • 1 → バス番号 (ラズパイ5は、Pin 3(SDA)とPin 5(SCL)でI2Cバス1を使用)

すると、I2Cバス上に接続されているデバイスのアドレス一覧が表示されます。うまく接続できていれば、以下のようにi2cアドレスが表示されるはず。

SSD1306のI2Cアドレスは3cが一般的で、モジュールによっては3dの場合もあるようです。

この数字が表示されていれば、ラズパイとSSD1306の通信は問題なくできています。表示されない場合、接続に間違いがないかもう一度確認しましょう。

PythonでOLEDディスプレイに表示させる

ここからは実際にPythonを使って、OLEDディスプレイに文字を表示させてみます。

流れとしてはシンプルで、「ライブラリを入れる → コードを書く → 実行する」の3ステップです。順番に進めていけば問題なく動くので、ひとつずつ確認しながら進めてみてください。

必要なライブラリのインストール

まずは、SSD1306を制御するためのPythonライブラリをインストールします。今回は使いやすい luma.oled を使います。

ラズパイ5(Bookworm OS以降)では、システムPythonにpipでパッケージをインストールするのは非推奨となっているため、予めvenvで仮想環境を構築しておきます。

python3 -m venv .venv

以前、gpiozero関連のエラーを避けるため、仮想環境の構築時に「–system-site-packages」オプションを付ける対策をとったことがあります。

今回はこのオプションを付けずに仮想環境を構築しましたが、サンプルコードを問題なく実行できました。I2Cのみで、gpio周りのライブラリを使っていないからではと思います。GPIOも使うなら、上のオプションを付けて仮想環境を構築してください。

仮想環境に入ったら、ターミナルで以下を実行してライブラリを追加します。

pip install luma.oled pillow
  • luma.oled → ディスプレイ制御用

    SSD1306用のPythonライブラリはいくつかあります。
    以前よく使われていたAdafruit製の「Adafruit_SSD1306」は、既に開発終了し非推奨となっています。Adafruitの新ライブラリもありますが、本記事では、よりシンプルで扱いやすい「luma.oled」を使用します。
  • Pillow → 画像や文字を描画するためのライブラリ

    SSD1306は「画像として描画してから表示する」仕組みのため、Pillowもセットで必要になります。

表示テストコード

それでは、実際に表示してみます。表示テスト用コードは以下のとおりです。

from luma.core.interface.serial import i2c
from luma.oled.device import ssd1306
from PIL import Image, ImageDraw
import time

# I2C接続(アドレスは0x3Cが一般的)
serial = i2c(port=1, address=0x3C)
device = ssd1306(serial)

# 画面サイズ取得
width = device.width
height = device.height

# 画像バッファ作成(モノクロ)
image = Image.new("1", (width, height))
draw = ImageDraw.Draw(image)

# テキスト描画
draw.text((0, 0), "Hello SSD1306!", fill=255, font_size=15)

# 表示
device.display(image)
sleep(10)

実行すると、ディスプレイに「Hello SSD1306!」と10秒間表示されました!


何も表示されない場合は、前の手順(i2cdetect)をもう一度確認してみてください。

コードの中身を少し見てみましょう。

(1) I2C接続の設定

serial = i2c(port=1, address=0x3C)
device = ssd1306(serial)

ここでは「I2Cのどのアドレスのデバイスに接続するか」を指定しています。
0x3C のところは、「i2cdetect」で表示されたアドレスを入れます。環境によっては 0x3D の場合もあるので、そのときは変更してください。

(2) 画像バッファを作る

image = Image.new("1", (width, height))
draw = ImageDraw.Draw(image)

SSD1306は直接文字を書き込むのではなく、一度メモリ上に画像を作ってから表示する仕組みになっています。そのため、SSD1306の表示サイズに合わせた画像バッファを作成します。

Image.new()の'1'1ビットピクセルの意味で、各ピクセルが白(1)または黒(0)の2値で表現されます。SSD1306は「白黒(1bit)」表示なので、画像バッファも「1ビット白黒画像(モノクロ画像)」で作ります。

(3) 文字を描画する

draw.text((0, 0), "Hello SSD1306!", fill=255, font_size=15)

(2)で作成した画像バッファに文字を入れています。
座標 (0, 0) は左上を意味します。デフォルトのフォントが小さいため、font_sizeで大きさを指定しています。

fill=255 は本来ならピクセル値の指定ですが、SSD1306は基本的に1bit(白黒)表示のため、fill=1fill=128 に変更しても見た目の明るさは変わりません。

実際には「0なら消灯、それ以外なら点灯」という動作になります。

(4) ディスプレイに表示

device.display(image)
sleep(10)

最後に、作った画像をディスプレイに転送し、次のsleepで10秒間表示させます。

luma.oledは、プログラムの終了と共に画面をクリアする仕様になっているようです。公式サイトを見ると、「Python usage」 – 「Note」に以下のような記載があります。

When a program ends, the display is automatically cleared. This means that a fast program that ends quickly may never display a visible image.

今回のような短いプログラムでは、目に見えないくらい一瞬で表示が消えてしまいます。そのため、最後のsleepを入れて画面の表示時間を延ばしています。

まとめ

今回は、Raspberry Pi 5のI2C機能を使って、SSD1306搭載の128×64 OLEDディスプレイモジュールを動かしてみました。

このモジュールは小型ながら視認性が高く、センサー値やシステム情報の表示にぴったりなディスプレイです。必要な配線が少なくて扱いやすく価格も安いので、ラズパイ5で電子工作を始める最初のディスプレイとして非常におすすめです。ぜひいろいろな表示に挑戦してみてください。


目次