PicoじゃないラズパイでCircuitPythonのコードを動かす

「ラズパイでCircuitPython」と言うと前回記事でまとめたRP2040搭載のRaspberry Pi Picoを連想しがちだが、Linux(Raspberry Pi OS)が動作する従来からのラズパイにBlinkaというライブラリをインストールすると、CPython(PCなどで動作する普通のPython)からCircuitPython互換のAPIを使えるようになり、CircuitPythonのプログラムがLinux上で動くようになる。

一連のインストール動作はAdafruit社によるPDF文書Webドキュメントにまとめられている。これらを参考に、ラズパイLinux上でCircuitPythonのプログラムを動かしてみた。

スポンサーリンク

事前準備

システムのアップデートとPython3環境のインストールをやっておこう。

sudo apt update
sudo apt upgrade
sudo apt install python3-pip
sudo pip3 install --upgrade setuptools

Blinkaのインストール

以下の手順でraspi-blinka.pyをダウンロードして管理者権限で実行すればOK。

sudo pip3 install --upgrade adafruit-python-shell
wget https://raw.githubusercontent.com/adafruit/Raspberry-Pi-Installer-Scripts/master/raspi-blinka.py
sudo python3 raspi-blinka.py

すると以下のようなメッセージ(「システムデフォルトのPythonがバージョン2だけどバージョン3にしていいか?」と聞かれている)が表示されるので、yを選択する。

This script configures your
Raspberry Pi and installs Blinka

RASPBERRY_PI_ZERO_W detected.

Blinka WARNING Default System python version is 2.7.16. It will be updated to Version 3.
Continue? [y/n] y

次に”Updating System Packages”とのメッセージが表示され、暫く待っているとパッケージのインストールやハードウエアの有効化などが自動で行われる。

最後に以下のようなメッセージが表示され(「リブートして良いか?」と聞かれてる)、yと答えればシステムの再起動がかかりBlinkaのインストールが完了する。

Settings take effect on next boot.

REBOOT NOW? [Y/n] 

再起動後に以下を実行し、/dev/i2c-1 /dev/spidev0.0 /dev/spidev0.1の3つが表示されればインストールは成功だ。

ls /dev/i2c* /dev/spi*

I2Cデバイスの接続とポートの確認

ラズパイでI2Cデバイスを使いたい場合のGPIOポートは以下のような割当となっている。

SCLSDA
GPIO3GPIO2

GPIOのピンアサインが分からなくなった時は、コマンドラインからpinoutコマンドを実行するとテキストコンソールにアスキーアートでボードのレイアウトとピンアサインを表示してくれるので便利だ。

さて、今回はMicroPythonでも愛用しているSSD1306小型OLEDディスプレイをCircuitPythonで動かしてみる。写真のようにRaspberry Pi Zero WにI2Cインタフェースで接続した。

SSD1306の接続

この状態で以下を実行する。

sudo i2cdetect -y 1

すると以下のような出力が得られ、I2Cの0x3C番地にディスプレイが検出されていると分かる。

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- 3c -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                         

PythonコードでBlinkaの簡易テスト

Blinkaが正しくインストールされていれば、既にPythonコードからI2Cポートが使えるようになっている筈だ。

以下のコードをi2cscan.pyというファイル名で保存する。

import board
import busio
i2c = busio.I2C(board.SCL, board.SDA)
port = i2c.scan()
print(hex(port[0]))

そしてi2cscan.pyをコマンドラインから実行して、”0x3c”の文字列がコンソールに表示されたら成功だ。

$ python i2cscan.py
0x3c

CircuitPythonプログラムでSSD1306ディスプレイを動かす

SSD1306をCircuitPythonで動かすためのサンプルプログラムはSSD1306ドライバのGitHubページに幾つか用意されている。

Adafruit_CircuitPython_SSD1306/examples at main · adafruit/Adafruit_CircuitPython_SSD1306
Adafruit CircuitPython framebuf driver for SSD1306 or SSD1305 OLED displays. Not for use with displayio. See README. - a...

これらを参考に、2つほどテキスト表示のプログラムを作った。

まずはドライバをインストール

SSD1306のCircuitPythonドライバはPyPIに登録されており、pipで一発インストール可能だ。

pip3 install adafruit-circuitpython-ssd1306

依存パッケージが自動でインストールされ、手元のラズパイ環境ではadafruit-circuitpython-ssd1306の他にadafruit-circuitpython-busdevice, adafruit-circuitpython-framebuf, adafruit-circuitpython-typing, typing-extensionsがインストールされた。

簡単なテキスト表示プログラム

以下のプログラムをssd1306test.pyというファイル名で保存する。

from board import SCL, SDA
import busio

import adafruit_ssd1306
i2c = busio.I2C(SCL, SDA)

display = adafruit_ssd1306.SSD1306_I2C(128, 64, i2c)
display.fill(0)
display.show()

display.text("hello world", 0, 0, 1)
display.show()

このプログラムを実行するためには、Adafruit_CircuitPython_framebufクラスが参照するデフォルトのフォントファイル(font5x8.bin)をダウンロードしてプログラムと同じディレクトリ階層に置いておく必要がある。

以下をラズパイのコマンドラインから実行。

$ python3 ssd1306test.py

すると写真のような表示となった。

SSD1306テストプログラム実行

TrueTypeフォントでテキスト描画するプログラム

下はRaspberry Pi OSにインストールされているTrueTypeフォントを使ったディスプレイ表示のプログラム。15行目でDejaVuSans.ttfの16ポイントを指定している。

from board import SCL, SDA
import busio
from PIL import Image, ImageDraw, ImageFont

import adafruit_ssd1306
i2c = busio.I2C(SCL, SDA)

display = adafruit_ssd1306.SSD1306_I2C(128, 64, i2c)
display.fill(0)
display.show()

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

font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 16)

draw.text((0, 0), "Hello world!", font=font, fill=255)

display.image(image)
display.show()

これを実行すると、以下のように大きなフォントで表示された。

SSD1306でttfフォント

まとめ

PicoじゃないラズパイRaspberry Zero W上のLinux環境でCircuitPythonプログラムの実行を試してみた。ドライバがPyPIに登録されているため、pipで簡単にインストール出来てしまうのは本当に楽。ヘッドレス運用のラズパイにWiFi経由でsshログインして使えるため、コマンドライン好きな自分としては最強の電子工作プログラミング環境かも。

CircuitPythonはAdafruit社がドライバのメンテをしっかりやっているので、対応ハードウエアも多い。用途が見いだせずに死蔵していたRaspberry Zero Wだったが、これからは電子工作への出番が増えそうだ。

コメント

  1. 吉田 純造 より:

    とてもわかりやすいです
    ありがとうございました