はじめに
Raspberry Pi Pico Wのサンプルプログラム集(その1)を作成しました。
プログラムの実行には、Raspberry Pi Pico WにMicroPythonがインストールされていることが必要です。MicroPythonのインストール方法など基本的な使い方については、以下の記事などをご参照ください。
なお、Wi-Fiに接続するプログラムには、プログラム中のssidとpasswordの部分(以下参照)にお使いのWiFiルータの情報を入力する必要があります。
connect_to_wifi('ssid', 'password')
Raspberry pi Picoのピン配置等は以下のサイトをご参照ください。
サンプルプログラム集
1. オンボードLEDの点滅(Lチカ)
オンボード上のLEDを点滅させるプログラムです。電子回路の作成は不要です。
from machine import Pin
import time
led = Pin("LED", Pin.OUT)
while True:
led.on()
time.sleep(1)
led.off()
time.sleep(1)
2. 温度計測(オンボード温度計、結果はシェル表示)
オンボード上の温度計で温度を計測するプログラムです。電子回路の作成は不要です。
import machine
import time
# 温度センサが接続されている、4番ピンの ADC(アナログデジタルコンバータ) を取得
sensor_temp = machine.ADC(4)
conversion_factor = 3.3 / (65535)
while True:
# センサから取得した値(read_u16():0~65535) を電圧0〜3.3Vに変換
reading = sensor_temp.read_u16() * conversion_factor
# 電圧が基準値からどれくらいずれているかを計算して温度を測定
# センサは27℃を基準にしているため、温度センサの数値を27℃から引いて計算
temperature = 27 - (reading - 0.706)/0.001721
print("{:.1f}".format(temperature))
time.sleep(2)
3. WiFi接続
WiFiの接続テストをするプログラムです。電子回路の作成は不要です。
import time # 時刻関連の関数(sleep, time, localtimeなど)を使うための標準モジュール
import network # Wi-Fi 接続などネットワーク機能を使うためのモジュール
# Wi-Fi に接続する関数
# 引数:SSIDとパスワード(ssid, password)
def connect_to_wifi(ssid, password):
wlan = network.WLAN(network.STA_IF) # ルーターに接続でWiFiインターフェースを作成
wlan.active(True) # インターフェースを有効にする
wlan.connect(ssid, password) # SSIDとパスワードでWiFiに接続開始
max_wait = 10 # 最大10秒待機
while max_wait > 0:
if wlan.status() < 0 or wlan.status() >= 3:
break # 接続完了(3)またはエラー(-1など)ならループを抜ける
print('Wi-Fi接続待機中...')
time.sleep(1)
max_wait -= 1
# 接続状態の確認
if wlan.status() != 3:
raise RuntimeError('Wi-Fi接続に失敗しました') # 接続できなかった場合はエラーを出す
else:
print('Wi-Fi接続成功')
ip = wlan.ifconfig()[0] # 自分のIPアドレスを取得
print(f'IPアドレス: {ip}')
# Wi-Fiに接続(ssid と password にはWiFiルータのIDとパスワードを入力)
connect_to_wifi('ssid', 'password')
実行結果(Thonny)
>>> %Run -c $EDITOR_CONTENT
MPY: soft reboot
Connected
ip = 192.168.11.47
>>>
4. 温湿度計測(DHT11、結果はシェル表示)
DHT11センサーモジュール(プルアップ抵抗付)で温湿度を計測するプログラムです。
DHT11について
プログラム
import dht
import machine import Pin
import time
# Initialize DHT11 sensor on GPIO 28
d = dht.DHT11(Pin(28))
# Continuously read and print temperature and humidity
while True:
d.measure()
print("Temperature:" ,d.temperature()) # Print temperature
print("Humidity:" ,d.humidity()) # Print humidity
time.sleep_ms(1000) # Read every second
実行結果(ThonnyのShell画面)
>>> %Run -c $EDITOR_CONTENT
MPY: soft reboot
Temperature: 27
Humidity: 45
Temperature: 27
Humidity: 45
Temperature: 27
Humidity: 44
5. OLEDへのテキスト(半角)表示
有機ELディスプレイ(OLED)をRaspberry Pi Pico WにI2C接続して、文字を表示させるプログラムです。
使用したOLEDについて
I2C接続について
電子回路
次のような電子回路を作成します。OLEDをI2CC接続にするため、OLEDのSDAを0番ピン、SCLを1番ピンに接続します。
SSD1306ライブラリのインストール
プログラム
from machine import Pin, I2C
from ssd1306 import SSD1306_I2C
# Initialize
i2c = I2C(0, scl=Pin(1), sda=Pin(0))
oled = SSD1306_I2C(128, 64, i2c)
# clear display
oled.fill(0)
# Display text on the OLED screen
oled.text("SSD1306 OLED", 0, 10)
oled.text("Pico W", 40, 35)
# The following line sends what to show to the display
oled.show()
6. NTPからの時刻の取得(結果はシェル表示)
NTP(Network Time Protocol)から時刻を取得するプログラムです。電子回路の作成は不要です。
NTPについて
import time # 時刻関連の関数(sleep, time, localtimeなど)を使うための標準モジュール
import network # Wi-Fi 接続などネットワーク機能を使うためのモジュール
import ntptime # NTP(Network Time Protocol)を使ってRTC(内蔵時計)をインターネット経由で同期するためのモジュール
# Wi-Fi に接続する関数
# 引数:SSIDとパスワード(ssid, password)
def connect_to_wifi(ssid, password):
wlan = network.WLAN(network.STA_IF) # ルーターに接続でWiFiインターフェースを作成
wlan.active(True) # インターフェースを有効にする
wlan.connect(ssid, password) # SSIDとパスワードでWiFiに接続開始
max_wait = 10 # 最大10秒待機
while max_wait > 0:
if wlan.status() < 0 or wlan.status() >= 3:
break # 接続完了(3)またはエラー(-1など)ならループを抜ける
print('Wi-Fi接続待機中...')
time.sleep(1)
max_wait -= 1
# 接続状態の確認
if wlan.status() != 3:
raise RuntimeError('Wi-Fi接続に失敗しました') # 接続できなかった場合はエラーを出す
else:
print('Wi-Fi接続成功')
ip = wlan.ifconfig()[0] # 自分のIPアドレスを取得
print(f'IPアドレス: {ip}')
# Wi-Fiに接続(ssid と password にはWiFiルータのIDとパスワードを入力)
connect_to_wifi('ssid', 'password')
# --- NTP ---
ntptime.host = "time.cloudflare.com"
for _ in range(3):
try:
ntptime.settime()
print("NTP時刻同期に成功")
break
except Exception as e:
print("NTP時刻同期に失敗:", e)
time.sleep(2)
else:
print("NTP時刻同期を継続")
# --- JST(UTC+9) ---
now = time.localtime(time.time() + 9 * 60 * 60)
print(f"{now[0]}/{now[1]:02d}/{now[2]:02d} {now[3]:02d}:{now[4]:02d}:{now[5]:02d}")
7. 温湿度計測(DHT11、結果はOLED表示、NTP時刻も表示)
「温湿度計測(DHT11、結果はシェル表示)」「OLEDへのテキスト表示」「NTPからの時刻の取得」を組み合わせて、温湿度を計測してOLEDに表示するガジェットを作成します。
プログラム
import time # 時刻関連の関数(sleep, time, localtimeなど)を使うための標準モジュール
import network # Wi-Fi 接続などネットワーク機能を使うためのモジュール
import ntptime # NTP(Network Time Protocol)を使ってRTC(内蔵時計)をインターネット経由で同期するためのモジュール
from machine import Pin, I2C
import dht
from ssd1306 import SSD1306_I2C
# Wi-Fi に接続する関数
# 引数:SSIDとパスワード(ssid, password)
def connect_to_wifi(ssid, password):
wlan = network.WLAN(network.STA_IF) # ルーターに接続でWiFiインターフェースを作成
wlan.active(True) # インターフェースを有効にする
wlan.connect(ssid, password) # SSIDとパスワードでWiFiに接続開始
max_wait = 10 # 最大10秒待機
while max_wait > 0:
if wlan.status() < 0 or wlan.status() >= 3:
break # 接続完了(3)またはエラー(-1など)ならループを抜ける
print('Wi-Fi接続待機中...')
time.sleep(1)
max_wait -= 1
# 接続状態の確認
if wlan.status() != 3:
raise RuntimeError('Wi-Fi接続に失敗しました') # 接続できなかった場合はエラーを出す
else:
print('Wi-Fi接続成功')
ip = wlan.ifconfig()[0] # 自分のIPアドレスを取得
print(f'IPアドレス: {ip}')
# I2C、DHT11、OLEDの初期設定
i2c = I2C(0, scl=Pin(1), sda=Pin(0))
d = dht.DHT11(Pin(28))
oled = SSD1306_I2C(128, 64, i2c)
# Wi-Fiに接続(ssid と password にはWiFiルータのIDとパスワードを入力)
connect_to_wifi('ssid', 'password')
# --- NTP ---
ntptime.host = "time.cloudflare.com"
for _ in range(3):
try:
ntptime.settime()
print("NTP時刻同期に成功")
break
except Exception as e:
print("NTP時刻同期に失敗:", e)
time.sleep(2)
else:
print("NTP時刻同期を継続")
# --- JST(UTC+9) ---
now = time.localtime(time.time() + 9 * 60 * 60)
print(f"{now[0]}/{now[1]:02d}/{now[2]:02d} {now[3]:02d}:{now[4]:02d}:{now[5]:02d}")
# 繰り返し実施
while True:
oled.fill(0)
try:
d.measure()
temp = d.temperature()
humi = d.humidity()
except Exception as e:
temp = humi = None
now = time.localtime(time.time() + 9 * 60 * 60)
hh, mm, ss = now[3], now[4], now[5]
if temp is not None and humi is not None:
oled.text("Temp.: {}".format(temp), 0, 10)
oled.text("Humid.: {}".format(humi), 0, 30)
else:
oled.text("DHT 読み込みエラー", 0, 10)
oled.text("Time: {:02d}:{:02d}:{:02d}".format(hh, mm, ss), 0, 50)
oled.show()
time.sleep(1)
8. 温湿度気圧計測(BME280、結果はOLED表示)
上記7 で使用したDHT11の代わりに温度・湿度・気圧センサー(BME280)を使用して、温湿度を計測してOLEDに表示するガジェットを作成します。BME280とOLEDはI2C接続します。
以下のサイトを参考にして、BME280のライブラリをインストールします。
- BME280はI2C接続とし、プルアップ抵抗も設定するため、BME280のJ1、J2、J3はすべてハンダ付けします。
- 以下のような電子回路を作成します。配線については、VDCはPicoの3.3V、GNDはPicoのGND、SDIはPicoの0ピン、SCKはPicoの1ピンにそれぞれ接続します。なお、SDOはPicoのGNDに接続しました。これにより、BME280のI2Cアドレスを0x76と設定します。
I2C動作確認用プログラム
以下のプログラムは、I2C接続された機器(ここではOLEDとBME280)のアドレスを表示するものです。まず、このプログラムを実行します。
from machine import Pin, I2C
i2c = I2C(0, sda=Pin(0), scl=Pin(1), freq=100_000) # まずは100kHzで安定動作を確認
print("scan:", [hex(a) for a in i2c.scan()])
実行結果
OLEDとBME280のアドレスが表示されます。
MPY: soft reboot
scan: ['0x3c', '0x76']
温度・湿度・気圧測定のプログラム
アドレスが表示されたら、次のプログラムを実行します。
from machine import Pin, I2C
from time import sleep
from bme280 import BME280
from ssd1306 import SSD1306_I2C
# I2C接続の定義
i2c = I2C(0, sda=Pin(0), scl=Pin(1), freq=400000)
# 必要なら addr パラメータを調整 (BME280: 0x76/0x77, SSD1306: 0x3C/0x3D)
bme = BME280(i2c=i2c) # 0x77 の場合: BME280(i2c=i2c, address=0x77)
oled = SSD1306_I2C(128, 64, i2c) # 0x3D の場合: SSD1306_I2C(128,64,i2c, addr=0x3D)
while True:
t, p, h = bme.values # 例: ('24.3C','1012.8hPa','45.1%')
oled.fill(0)
oled.text("BME280", 0, 0)
oled.text("T: " + t, 0, 16)
oled.text("P: " + p, 0, 32)
oled.text("H: " + h, 0, 48)
oled.show()
sleep(1)
9. OLEDの日本語表示
OLEDに日本語を表示させるため、Raspberry Pi Pico Micro Python用の美咲フォントをインストールします。
- 以下のサイトにアクセスします。
- 右上の「Code」をクリックしてから「Download ZIP」を選択します。
- ダウンロードしたzipファイルを展開します。
- Thonnyを起動し、「表示」「ファイル」でファイルタブを表示させます。
- ファイルタブ内の「misakifont」を右クリックして、「/にアップロード」をクリックします。
電子回路
OLEDをPICOにI2C接続したものを作成します。上記で作成した回路がある場合、そのまま使えます。
プログラム
「湿」という字が美咲フォントに無いため「□」になっていることが分かります(収録文字は美咲フォントのgithubを参照)。
import machine
import ssd1306
from misakifont import MisakiFont
import time
fcolor = 1
#フォントサイズの倍数
fsize = 1
def show_bitmap(oled, fd, x, y, color, size):
for row in range(0, 7):
for col in range(0, 7):
if (0x80 >> col) & fd[row]:
oled.fill_rect(int(x + col * size), int(y + row * size), size, size, color)
oled.show()
sda = machine.Pin(0)
scl = machine.Pin(1)
i2c = machine.I2C(0, sda=sda, scl=scl, freq=400000)
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
oled.fill(0)
mf = MisakiFont()
str = "温度℃、気圧pa、湿度%"
x = 0
y = 0
for c in str:
d = mf.font(ord(c))
show_bitmap(oled, d, x, y, fcolor, fsize)
x += 8 * fsize
if x >= 128:
x = 0
y += 8 * fsize
if y >= 64:
y = 0
time.sleep(0.02)
動作環境
- micropython v1.26.0
参考文献