はじめに

これまでRaspberry Pi Picoを使う時にはmicropythonを使っていましたが,W5500(Ethernetモジュール)を使うにあたり,circuitpythonを使うこととなりました.本当はmicropythonでもW5500は使えるはずなのですが,ファームウェアの書き換えを1日くらい格闘したのですがどうもうまくいかず,circuitpythonに乗り換えることとなりました.そもそもcircuitpythonとmicropythonという二つの開発環境があることすら知らなかったため,両者の違いを調べるところから始めて何とかW5500を動かせるところまで来たのでここに書き残します.

micropythonとcircuitpython

両社はともにPythonではありますが,開発する過程がだいぶ異なるようですし.相乗りで動作させることができないようです.micropythonはファームウェア(C++で書かれているプログラム)をビルドし,uf2ファイルを作成してそれをpicoに入れて使います.今回のようにW5500を使うとしたら,パソコンでファームウェアのソースプログラムをダウンロードもしくはgitからクローンし,W5500を含めてビルドする必要があります.picoのネイティブコードが生成されてファームウェアに書き込まれるため,おそらくですが後ほど説明するcircuitpythonより高速になっているのではないでしょうか.ただその一方でファームウェアをビルドし直すのにはそれなりに敷居が高く(実際私もうまくビルドできなかった),よりプロフェッショナル向けなのだと思います.一方でcircuitpythonの場合,基本的にファームウェアの変更をせずに動作させられるようです.パソコンとpicoをUSBケーブルで接続すると,picoが外部ドライブとして認識されます.そしてそのドライブに必要なライブラリを入れてあげれば動作するという作りになっています.

circuitpythonの開発手順

 picoでcircuitpythonによる開発をする手順を下に示します.

  1. circuitpythonのファームウェアをダウンロード
  2. ファームウェアをpicoへインストール
  3. 必要に応じてライブラリを追加
  4. テキストエディタやIDEでプログラミング
  5. pythonのプログラミングと動作確認

ファームウェアのダウンロード

circuitpythonはpicoのみ対応しているわけではなく他のボードでも動作するようになっています.このため,pico用のふぁいーむウェアをダウンロードしなければなりません.こちらのサイトに最新のファームウェアがあります.ダウンロードすると拡張子がuf2のファイルが得られます.なお,この文書を執筆時の最新バージョンは10.0.3でした.

picoへのインストール

ダウンロードしたuf2ファイルをpicoへインストールします.picoに備わるBOOTSELボタンを押したままパソコンとpicoをUSBケーブルで接続します.そうするとpicoがUSB接続された外部ドライブとしてパソコンからは認識されます.その外部ドライブへ先ほどダウンロードしたuf2ファイルをコピーすればインストール完了です.うまくインストールされると外部ドライブ(picoですが)のマウントがいったん解かれ,代わりにCIRCUITPYという名前で外部ドライブとしてマウントされるはずです.そのドライブにはcode.pyをはじめいくつかのファイルが入っています.このcode.pyからプログラムが動作するようになっています.

ライブラリの追加

code.pyと同じ階層にlibフォルダがあります.circuitpythonではこのフォルダにライブラリをコピーすれば自動的に認識してくれる仕様となっています.

ここに収められるファイルは拡張子mpyが多いです.mpyとはpythonプログラムをあらかじめネイティブコンパイラされたもののようです.このmpyにはmicropython用とcircuitpython用で異なります.つまり,micropython用のmpyファイルはcircuitpythonでは使えないということです.そして,私はその罠にはまりました.このあと紹介するW5500用ライブラリをmicropython用のmpyを入れて30分くらいハマっていました.エラー文をしっかり読めば分かったはずなのですが….

W5500のcircuitpython用ライブラリはこちらのgitから手に入れました.このサイトにはlibフォルダがあり,その中から「adafruit_bus_device」フォルダ,「adafruit_wiznet5k」フォルダ,「adafruit_requests」ファイルをダウンロードし,外部ドライブとして認識されているpicoのlibフォルダへコピーします.下の図はコピー後の様子を表しています.

2025 11 15 092058

IDEによるプログラミング

テキストエディタでもcode.pyを編集すれば動作してくれますが,IDEがあったほうが使い勝手はよくなります.一般的にMu editorが使われているようですので,こちらをインストールしました.こちらのサイトからダウンロードしてインストールしました.

Mu editorではさまざまなマイコンボードおよびmicropython,circuitpythonに対応しているようです.ボードやファームウェアの違いをモードと呼ぶようです.下の図はMu editorを立ち上げてモードを選択している様子を表しています.左上にあるモードボタンを押すとモードの選択画面が現れます.今回はCircuitPythonを選択しています.ここではまたわたくしはハマってしまったのですが,モードの中にはRP2040(要するにRaspberry Pi pico)があったため,わたくしは誤ってこれを選択して動作させようとしてしまいました.よく読めばわかるのですが,こちらはpico+micropythonで開発するモードとなっています.したがって,今回の場合には不適切でした.

2025 11 15 092719

もう一つハマったポイントとしては,circuitpythonの実行方法があります.circuitpythonではプログラムを保存すると勝手に動作する仕様となっています.このため,CircuitPythonモードではMu editorに実行ボタンがありません.

プログラミングと動作確認

今回使用したW5500はスイッチサイエンスで販売しているこちらです.このボードとpicoを以下に示すように接続しました.

 端子名 GPIO番号
 MOSI (TX) GP19
 MISO (RX) GP16
 SCK GP18
CS GPIO17
RESET GPIO20

 

上記の接続状況を勘案し,こちらにあるサンプルプログラムをもとに修正したものを下に示します.

import board
import busio
import digitalio
import time
from adafruit_wiznet5k.adafruit_wiznet5k import WIZNET5K

SPI0_SCK = board.GP18
SPI0_TX = board.GP19
SPI0_RX = board.GP16
SPI0_CSn = board.GP17
W5500_RSTn = board.GP20

print("Wiznet5k Ping Test (no DHCP)")

# Setup your network configuration below
# random MAC, later should change this value on your vendor ID
MY_MAC = (0x00, 0x01, 0x02, 0x03, 0x04, 0x05)
IP_ADDRESS = (192, 168, 1, 100)
SUBNET_MASK = (255, 255, 0, 0)
GATEWAY_ADDRESS = (192, 168, 0, 1)
DNS_SERVER = (8, 8, 8, 8)

led = digitalio.DigitalInOut(board.LED)
led.direction = digitalio.Direction.OUTPUT

ethernetRst = digitalio.DigitalInOut(W5500_RSTn)
ethernetRst.direction = digitalio.Direction.OUTPUT

# For Adafruit Ethernet FeatherWing
cs = digitalio.DigitalInOut(SPI0_CSn)
# For Particle Ethernet FeatherWing
# cs = digitalio.DigitalInOut(board.D5)
spi_bus = busio.SPI(SPI0_SCK, MOSI=SPI0_TX, MISO=SPI0_RX)

# Reset W5500 first
ethernetRst.value = False
time.sleep(1)
ethernetRst.value = True

# Initialize ethernet interface with DHCP
# eth = WIZNET5K(spi_bus, cs)
# Initialize ethernet interface without DHCP
eth = WIZNET5K(spi_bus, cs, is_dhcp=False, mac=MY_MAC)

# Set network configuration
eth.ifconfig = (IP_ADDRESS, SUBNET_MASK, GATEWAY_ADDRESS, DNS_SERVER)

print("Chip Version:", eth.chip)
print("MAC Address:", [hex(i) for i in eth.mac_address])
print("My IP address is:", eth.pretty_ip(eth.ip_address))

while True:
    led.value = not led.value
    time.sleep(1)

print("Done!")

あとは有線LANに接続したパソコンからpingを打つと返答があることを確認できました.今回,パソコンの有線LANアドレスは.192.168.1.101にしました.

2025 11 15 094818

おわりに

何とか有線LANでネットワークに接続できました.このあとはmicropythonで今まで書いていたプログラムをすべてcircuitpythonに移植すればよいはずです.結構面倒だけど.