CircuitPython を使った Raspberry Pi Pico の開発
フラッシュメモリをリセットする
Raspberry Pi Documentation - Raspberry Pi Pico and Pico W
上記からflash_nuke.uf2
をダウンロードする。
BOOTSEL ボタンを押した状態で Raspberry Pi Pico を USB 接続した状態で表示されるストレージにflash_nuke.uf2
をコピーする。
CircuitPython をインストールする
Raspberry Pi Pico用の CircuitPython は以下。
Pico Download
Raspberry Pi Pico W用の CircuitPython は以下。
Pico W Download
書き込みを間違えると import エラーが出るなど正しく動作しない。
上記からadafruit-circuitpython-raspberry_pi_pico-en_US-x.x.x.uf2
をダウンロードする。
BOOTSEL ボタンを押した状態で Raspberry Pi Pico を USB 接続した状態で表示されるストレージにadafruit-circuitpython-raspberry_pi_pico-en_US-x.x.x.uf2
をコピーする。
Hello, World
| import time
while True:
print("Hello World!")
time.sleep(1)
|
シリアルポートに出力される。出てこない場合はAcronis True Image for Crucial
をアンインストールする。
LED を点滅させる
Raspberry Pi Pico W では内蔵の LED 点滅ができなかったので諦める。
code.py
をmain.py
にリネームして以下で保存する。
main.py |
---|
1
2
3
4
5
6
7
8
9
10
11
12 | import digitalio
import time
import board
led = digitalio.DigitalInOut(board.GP0)
led.direction = digitalio.Direction.OUTPUT
while True:
led.value = True
time.sleep(1)
led.value = False
time.sleep(1)
|
トグルスイッチを使う
main.py |
---|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 | import time
import analogio
import board
import digitalio
# 代入はこの順番で行わないとトグルスイッチから正しい値が取得できない
toggle = digitalio.DigitalInOut(board.GP0)
toggle.direction = digitalio.Direction.INPUT
toggle.pull = digitalio.Pull.UP
def main() -> None:
delta_t = 1 / 60
toggle_before = toggle.value
while True:
print(toggle.value)
if toggle_before and not toggle.value:
print("Pressed")
toggle_before = toggle.value
time.sleep(delta_t)
if __name__ == "__main__":
main()
|
| True
True
True
False
Pressed
False
False
False
...
|
CircuitPython のライブラリ
Libraries
Wi-Fi に接続する(Raspberry Pi Pico W)
Overview | Quick-Start the Pico W WiFi with CircuitPython | Adafruit Learning System
settings.toml
に以下を記載する。
settings.toml |
---|
| CIRCUITPY_WIFI_SSID="xxxxxxxx"
CIRCUITPY_WIFI_PASSWORD="xxxxxxxx"
|
main.py
に以下を記載する。
main.py |
---|
1
2
3
4
5
6
7
8
9
10
11
12 | import os
import socketpool
import wifi
print("Connecting to Wi-Fi")
wifi.radio.connect(os.getenv("CIRCUITPY_WIFI_SSID"), os.getenv("CIRCUITPY_WIFI_PASSWORD"))
print("Connected to Wi-Fi")
pool = socketpool.SocketPool(wifi.radio)
print("MAC address:", ":".join([hex(i)[2:] for i in wifi.radio.mac_address]))
print("IP address:", wifi.radio.ipv4_address)
|
固定 IP
settings.toml |
---|
| WIFI_SSID="xxxxxxxx"
WIFI_PASSWORD="xxxxxxxx"
IPV4_ADDRESS="xxx.xxx.xxx.xxx"
SUBNET_MASK="255.255.255.0"
DEFAULT_GATEWAY="xxx.xxx.xxx.xxx"
|
main.py |
---|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 | import ipaddress
import os
import time
import socketpool
import wifi
try:
# Wi-Fi
print("Connecting to Wi-Fi")
wifi.radio.set_ipv4_address(
ipv4=ipaddress.IPv4Address(os.getenv("IPV4_ADDRESS")),
netmask=ipaddress.IPv4Address(os.getenv("SUBNET_MASK")),
gateway=ipaddress.IPv4Address(os.getenv("DEFAULT_GATEWAY"))
)
wifi.radio.connect(os.getenv("WIFI_SSID"), os.getenv("WIFI_PASSWORD"))
print("Connected to Wi-Fi")
pool = socketpool.SocketPool(wifi.radio)
print("MAC address:", ":".join([hex(i)[2:] for i in wifi.radio.mac_address]))
print("IP address:", wifi.radio.ipv4_address)
except Exception as e:
print(e)
print("Restarting...")
time.sleep(3)
microcontroller.reset()
|
MQTT 接続する(Raspberry Pi Pico W)
Adafruit MiniMQTT というライブラリを使う。
GitHub - adafruit/Adafruit_CircuitPython_MiniMQTT: MQTT Client Library for CircuitPython
adafruit_minimqtt
ディレクトリをlib
ディレクトリ内にコピーする。
settings.toml |
---|
| WIFI_SSID="xxxxxxxx"
WIFI_PASSWORD="xxxxxxxx"
MQTT_BROKER="xxx.xxx.xxx.xxx"
MQTT_PORT=1883
MQTT_CLIENT_ID="RPiPicoW"
|
main.py |
---|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 | import os
import time
import adafruit_minimqtt.adafruit_minimqtt as MQTT
import socketpool
import wifi
print("Connecting to Wi-Fi")
wifi.radio.connect(os.getenv("WIFI_SSID"), os.getenv("WIFI_PASSWORD"))
print("Connected to Wi-Fi")
pool = socketpool.SocketPool(wifi.radio)
print("MAC address:", ":".join([hex(i)[2:] for i in wifi.radio.mac_address]))
print("IP address:", wifi.radio.ipv4_address)
def connected(client, userdata, flags, rc):
print("MQTT connected")
def disconnected(client, userdata, rc):
print("MQTT disconnected")
def message(client, topic, message):
print("MQTT message on topic {0}: {1}".format(topic, message))
mqtt_client = MQTT.MQTT(
broker=os.getenv("MQTT_BROKER"),
port=int(os.getenv("MQTT_PORT")),
socket_pool=pool,
client_id=os.getenv("MQTT_CLIENT_ID")
)
# Setup the callback methods above
mqtt_client.on_connect = connected
mqtt_client.on_disconnect = disconnected
mqtt_client.on_message = message
# Connect the client to the MQTT broker.
print("MQTT connecting")
mqtt_client.connect()
while True:
mqtt_client.loop()
mqtt_client.publish("json", "{\"key\": \"value\"}")
print("loop")
time.sleep(1)
|
USB シリアル通信する
CircuitPython であれば以下のコードでシリアル出力できる。
Tera Term でスピードを 115200 にすること。
| import time
while True:
print("test")
time.sleep(1)
|
Raspberry Pi に Raspberry Pi Pico を USB で接続したとき、以下コマンドでシリアル出力を確認できる。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 | $ dmesg | grep tty
# (略)
[44202.665254] cdc_acm 1-1.3:1.0: ttyACM0: USB ACM device
[44268.886714] cdc_acm 1-1.3:1.0: ttyACM0: USB ACM device
$ cat /dev/ttyACM0
test
test
test
test
test
test
test
test
test
test
test
|
時刻を取得する
Libraries
adafruit_ntp — Adafruit NTP Library 1.0 documentation
adafruit_ntp.mpy
をlib
ディレクトリ内にコピーする。
よくOSError
が出るのでmicrocontroller.reset()
を使うこと。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 | import os
import microcontroller
import socketpool
import wifi
import adafruit_ntp
try:
# Wi-Fi
print("Connecting to Wi-Fi")
wifi.radio.connect(os.getenv("CIRCUITPY_WIFI_SSID"), os.getenv("CIRCUITPY_WIFI_PASSWORD"))
print("Connected to Wi-Fi")
pool = socketpool.SocketPool(wifi.radio)
print("MAC address:", ":".join([hex(i)[2:] for i in wifi.radio.mac_address]))
print("IP address:", wifi.radio.ipv4_address)
# NTPサーバー
ntp = adafruit_ntp.NTP(pool, tz_offset=9)
print("Hello World!", ntp.datetime)
except Exception as e:
print(e)
print("Restarting...")
time.sleep(3)
microcontroller.reset()
|
| Hello World! struct_time(tm_year=2024, tm_mon=10, tm_mday=4, tm_hour=9, tm_min=52, tm_sec=7, tm_wday=4, tm_yday=278, tm_isdst=-1)
|
ディープスリープを使う
Overview | Deep Sleep with CircuitPython | Adafruit Learning System
時間を取得する
time.time()
は整数の秒なので使いにくい。time.monotonic_ns()
でナノ秒単位で取得できる。
| start = time.monotonic_ns()
while True:
now = time.monotonic_ns()
if now - start >= 1 * 1000 * 1000 * 1000:
break
time.sleep(1/60)
|
キーボードを作成する
以下からadafruit-circuitpython-hid-x.x-mpy-x.x.x.zip
をダウンロードして、zip 内のadafruit_hid
をlib
にコピーする。
GitHub - adafruit/Adafruit_CircuitPython_HID: USB Human Interface Device drivers.
main.py |
---|
1
2
3
4
5
6
7
8
9
10
11
12
13 | import time
import usb_hid
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
from adafruit_hid.keycode import Keycode
keyboard = Keyboard(usb_hid.devices)
layout = KeyboardLayoutUS(keyboard)
keyboard.press(Keycode.UP_ARROW)
time.sleep(0.1)
keyboard.release(Keycode.UP_ARROW)
|
keyboard.press()
とkeyboard.release()
はセットで扱うことに注意。
HTTP サーバーを作成する
以下からライブラリをダウンロードし、lib
ディレクトリ内にadafruit_httpserver
ディレクトリをコピーする。
Libraries
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | └─lib
└─adafruit_httpserver
authentication.mpy
exceptions.mpy
headers.mpy
interfaces.mpy
methods.mpy
mime_types.mpy
request.mpy
response.mpy
route.mpy
server.mpy
status.mpy
__init__.mpy
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 | import os
import socketpool
import wifi
import adafruit_httpserver
print("Connecting to Wi-Fi")
wifi.radio.connect(os.getenv("CIRCUITPY_WIFI_SSID"), os.getenv("CIRCUITPY_WIFI_PASSWORD"))
print("Connected to Wi-Fi")
pool = socketpool.SocketPool(wifi.radio)
print("MAC address:", ":".join([hex(i)[2:] for i in wifi.radio.mac_address]))
print("IP address:", wifi.radio.ipv4_address)
print("Hello World!")
server = adafruit_httpserver.Server(pool, debug=True)
@server.route("/hi", "GET")
def base(request: adafruit_httpserver.Request) -> adafruit_httpserver.Response:
return adafruit_httpserver.JSONResponse(request, {"message": "Hi!"}, status=adafruit_httpserver.status.OK_200)
server.serve_forever("0.0.0.0", 80)
|
server.start("0.0.0.0", 80)
を実行したあと while ループの中でserver.poll()
を呼ぶ方法もある。