DIY LAB VOL.1
Raspberry Pi Pico Wで作る熱中症警戒アラート表示器
こんにちは。ニンジンです🥕
今回は「物作り系」の新シリーズとして、Raspberry Pi Pico Wと温湿度センサーDHT11、0.96インチOLEDディスプレイを使って、熱中症警戒アラート表示器を自作してみました。気温・湿度から簡易的な暑さ指数を計算し、「ほぼ安全・注意・警戒・厳重警戒・危険」の5段階を、OLED上の顔アイコンで直感的に表示します。
夏休みの自由研究のテーマとしても、Raspberry Pi Picoで「センサーの値を取得する→計算する→表示する」という電子工作の基本の流れを一通り体験できる題材になっています。実際に指でセンサーに触れて警戒レベルが切り替わる様子を動画にまとめたので、まずはご覧ください。
この記事で分かること
- DHT11センサーで温度・湿度を取得する方法
- 0.96インチOLED(SSD1306)にMicroPythonで文字・図形を表示する方法
- 気温・湿度から簡易的な暑さ指数(WBGT)を計算し、5段階で警戒レベルを判定する方法
- framebufのpixel・line・fill_rectを組み合わせて顔アイコンを描く方法
- 作ったプログラムをPico本体に保存し、PCなしで単体動作させる方法
- 実際に制作中つまずいたポイント(COMポートエラー、日本語アカウント名でのライブラリインストール失敗、ブレイクアウトボードの半挿入など)
DIY LAB VOL.1
ハードウェアの配線:Pico WとDHT11・OLED(I2C)の結線図
配線は下図の通りです。DHT11とOLEDで3.3V・GNDのラインを共用しているので、ブレッドボードの電源レール(赤帯・青帯)にまとめて配っています。
DHT11の配線
| DHT11 | 役割 | Pico Wピン |
|---|---|---|
| VCC | 電源 | 36番(3V3(OUT)) |
| GND | グランド | 38番(GND) |
| DATA | データ | 21番(GP16) |
0.96インチOLED(I2C接続)の配線
| OLED | 役割 | Pico Wピン |
|---|---|---|
| VCC | 電源 | 36番(3V3(OUT))※DHT11と共用 |
| GND | グランド | 38番(GND)※DHT11と共用 |
| SDA | I2Cデータ | 1番(GP0) |
| SCL | I2Cクロック | 2番(GP1) |
DIY LAB VOL.1
開発環境の構築:ThonnyとMicroPythonの書き込み
Pico WにMicroPythonを書き込み、開発ソフト「Thonny」をセットアップする手順は、以前の記事で詳しく解説しています。今回もこの手順に沿ってセットアップしました。
Thonnyのインストール〜MicroPython書き込み手順はこちら
記事を読むDIY LAB VOL.1
DHT11とOLED(SSD1306)の単体動作確認
配線ができたら、DHT11とOLEDがそれぞれ単体で正しく動くか確認します。
micropython-ssd1306ライブラリの導入
MicroPython標準にはSSD1306用のドライバが含まれていないため、Thonnyの「ツール」→「パッケージの管理」から追加します。
OLEDの表示テスト
from machine import Pin, I2C
import ssd1306
# I2C接続確認(配線ミス時はここで空リストが出ます)
i2c = I2C(0, scl=Pin(1), sda=Pin(0), freq=400000)
print("I2Cデバイス検出:", i2c.scan()) # 通常 [60] (0x3C) が出れば正常
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
oled.fill(0)
oled.text("Hello, Pico W!", 0, 0)
oled.text("OLED Test OK", 0, 20)
oled.show()DHT11のシリアル出力テスト
from machine import Pin
import dht
import time
sensor = dht.DHT11(Pin(16))
while True:
try:
sensor.measure()
temp = sensor.temperature()
hum = sensor.humidity()
print("温度: {}C 湿度: {}%".format(temp, hum))
except OSError as e:
print("センサー読み取りエラー:", e)
time.sleep(2)
OSError: [Errno 110] ETIMEDOUTで失敗したことがありました。この2つは使用するピンが全く別なので、個別の配線ミスというより電源(3.3V/GND)まわりの共通トラブルを疑うのがポイントです。今回の原因は、FreenoveブレイクアウトボードとPico本体の挿し込みが甘い「半挿入」でした。見た目では気づきにくいので、複数のデバイスが同時にタイムアウトする場合は、まず全体の挿し込みを奥まで確認し直してみてください。DIY LAB VOL.1
気温・湿度から熱中症警戒レベルを計算する(簡易WBGT推定式)
DHT11は気温と湿度しか計測できず、正式な暑さ指数(WBGT)の算出に必要な黒球温度(輻射熱)は測れません。そのため今回は、気温・湿度から屋内向けに簡易推定する計算式を使っています。環境省が発表する正式な熱中症警戒アラートとは異なる簡易的な目安である点にご注意ください。
まずTetensの式で水蒸気圧を求め、それを使って屋内簡易WBGT推定式を計算します。
def estimate_wbgt(temp, humidity):
# Tetensの式で水蒸気圧(hPa)を算出
e = (humidity / 100) * 6.1078 * 10 ** (7.5 * temp / (temp + 237.3))
# 屋内(日射なし)簡易WBGT推定式
return 0.567 * temp + 0.393 * e + 3.94算出したWBGT推定値を、日本生気象学会の熱中症予防運動指針を参考にした5段階のしきい値で判定します。
| WBGT推定値 | 警戒レベル |
|---|---|
| 21未満 | ほぼ安全 |
| 21以上25未満 | 注意 |
| 25以上28未満 | 警戒 |
| 28以上31未満 | 厳重警戒 |
| 31以上 | 危険 |
def classify_wbgt(wbgt):
if wbgt < 21:
return "ほぼ安全"
elif wbgt < 25:
return "注意"
elif wbgt < 28:
return "警戒"
elif wbgt < 31:
return "厳重警戒"
else:
return "危険"実際に室温26℃・湿度49%の環境で試したところ、推定WBGTは25.2、警戒レベルは「警戒」と表示されました。手計算でも同じ値になることを確認済みです。
DIY LAB VOL.1
OLEDに顔アイコンで警戒レベルを表示する
数値だけでなく、一目で危険度が伝わるよう、OLEDに5段階の表情を顔アイコンで表示します。MicroPython標準のフォントは日本語(漢字)に対応していないため、レベル名は英語表記(SAFE/CAUTION/WARNING/SEVERE/DANGER)にしています。
顔のパーツはframebufの基本図形だけで表現しています。目はfill_rectで塗りつぶした四角、口は2次曲線の計算式で1ピクセルずつpixelを打って描き、mood(表情の度合い)の符号でにっこり顔としかめ顔を切り替えています。厳重警戒・危険レベルでは、ハの字の眉と汗マークも追加しました。
def draw_face(oled, mood):
# mood: 2=ほぼ安全(にっこり) 〜 -2=危険(困り顔)
cx, cy = 64, 34
eye_y = cy - 8
# 目
oled.fill_rect(cx - 14, eye_y, 4, 4, 1)
oled.fill_rect(cx + 10, eye_y, 4, 4, 1)
# 眉(厳重警戒・危険のみハの字に)
if mood <= -1:
oled.line(cx - 17, eye_y - 4, cx - 10, eye_y - 1, 1)
oled.line(cx + 17, eye_y - 4, cx + 10, eye_y - 1, 1)
# 口(2次曲線。mood>0で笑顔、mood<0でしかめ顔)
mouth_w = 20
mouth_y = cy + 10
amplitude = 6
for dx in range(-mouth_w, mouth_w + 1):
dy = mood * amplitude * (1 - (dx / mouth_w) ** 2)
oled.pixel(cx + dx, int(mouth_y + dy), 1)
# 危険レベルは汗マーク追加
if mood <= -2:
oled.line(cx + 22, eye_y - 6, cx + 20, eye_y + 2, 1)
oled.line(cx + 20, eye_y + 2, cx + 24, eye_y + 2, 1)5段階それぞれの表示結果です。
DHT11・OLED・計算ロジック・顔アイコン表示をすべて統合した本番用スクリプトは以下の通りです。
from machine import Pin, I2C
import dht
import ssd1306
import time
# I2C・DHT11初期化
i2c = I2C(0, scl=Pin(1), sda=Pin(0), freq=400000)
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
sensor = dht.DHT11(Pin(16))
# しきい値(WBGT上限, mood, 表示ラベル)
LEVELS = [
(21, 2, "SAFE"),
(25, 1, "CAUTION"),
(28, 0, "WARNING"),
(31, -1, "SEVERE"),
(999, -2, "DANGER"),
]
def estimate_wbgt(temp, humidity):
e = (humidity / 100) * 6.1078 * 10 ** (7.5 * temp / (temp + 237.3))
return 0.567 * temp + 0.393 * e + 3.94
def classify(wbgt):
for threshold, mood, label in LEVELS:
if wbgt < threshold:
return mood, label
return LEVELS[-1][1], LEVELS[-1][2]
def draw_face(mood):
cx, cy = 64, 34
eye_y = cy - 8
oled.fill_rect(cx - 14, eye_y, 4, 4, 1)
oled.fill_rect(cx + 10, eye_y, 4, 4, 1)
if mood <= -1:
oled.line(cx - 17, eye_y - 4, cx - 10, eye_y - 1, 1)
oled.line(cx + 17, eye_y - 4, cx + 10, eye_y - 1, 1)
mouth_w = 20
mouth_y = cy + 10
amplitude = 6
for dx in range(-mouth_w, mouth_w + 1):
dy = mood * amplitude * (1 - (dx / mouth_w) ** 2)
oled.pixel(cx + dx, int(mouth_y + dy), 1)
if mood <= -2:
oled.line(cx + 22, eye_y - 6, cx + 20, eye_y + 2, 1)
oled.line(cx + 20, eye_y + 2, cx + 24, eye_y + 2, 1)
def draw_status(temp, hum, label, mood):
oled.fill(0)
oled.text("T:{}C H:{}%".format(temp, hum), 0, 0)
draw_face(mood)
oled.text(label, 40, 56)
oled.show()
while True:
try:
sensor.measure()
temp = sensor.temperature()
hum = sensor.humidity()
wbgt = estimate_wbgt(temp, hum)
mood, label = classify(wbgt)
print("気温:{}C 湿度:{}% 推定WBGT:{:.1f} レベル:{}".format(temp, hum, wbgt, label))
draw_status(temp, hum, label, mood)
except OSError as e:
print("センサー読み取りエラー:", e)
time.sleep(2)実際にDHT11に指で触れて温度・湿度を上げると、WARNING→SEVEREへとレベルが切り替わる様子が確認できました。
DIY LAB VOL.1
main.pyをPico本体に保存してスタンドアロン動作させる
MicroPythonは電源投入時にboot.py→main.pyの順で自動実行する仕組みがあります。Pico本体のストレージにmain.pyという名前で保存しておけば、PCもThonnyも繋がずモバイルバッテリーなどの電源だけで単体動作します。
保存後、USBケーブルを一度抜き差しして、PCから切り離した状態でも動作することを確認しました。
DIY LAB VOL.1
まとめ・次回予告
Raspberry Pi Pico WとDHT11、0.96インチOLED(SSD1306)を使って、熱中症警戒アラート表示器を自作しました。センサーの値を取得し、計算し、表示するという電子工作の基本の流れを、実際に手を動かしながら一通り体験できたと思います。
今回作った回路と考え方は、DHT11以外のセンサーやOLED以外のディスプレイにも応用が効きます。夏休みの自由研究や、ちょっとした電子工作の入り口として、ぜひ挑戦してみてください。
次回予告
次回は、この装置をベースにした発展編を予定しています。お楽しみに。
DIY LAB VOL.1
よくある質問
QDHT11で計算した警戒レベルは、環境省が発表する熱中症警戒アラートと同じですか?
Aいいえ、正式な暑さ指数(WBGT)ではありません。黒球温度(輻射熱)を測定していない、気温・湿度のみからの簡易推定値です。目安としてご利用ください。
QOLEDに「警戒」などの日本語をそのまま表示できますか?
AMicroPython標準のフォントはASCIIのみ対応のため、漢字はそのままでは表示できません。本記事ではSAFE/CAUTION/WARNING/SEVERE/DANGERの英語表記を使っています。
Qプログラムを保存したのに、PCを外すと動かなくなります。
AThonnyでファイルを保存する際、保存先が「このコンピュータ」になっている可能性があります。「Raspberry Pi Pico」を選び、ファイル名をmain.pyにして保存し直してください。
QOLEDが「OSError: [Errno 110] ETIMEDOUT」で動きません。
AI2C配線の接続不良が主な原因です。特にブレイクアウトボードとPico本体の挿し込みが甘い「半挿入」で発生しやすいので、奥までしっかり挿し直してみてください。
QDHT11のDATAピンは何番を使えばいいですか?
A本記事ではGP16(物理21番ピン)を使用していますが、他の空きGPIOでも動作します。使用するピンに合わせてコード内のPin(16)を書き換えてください。
Qmicropython-ssd1306のインストールでエラーが出ます。
AWindowsのユーザーアカウント名が日本語表記の場合、インストールが失敗することがあります。アカウント名を半角英数字に変更すると解決する場合があります。
Follow me on X
本ブログの中の人「ニンジン🥕」はXやってます。新着記事はいち早くポストでお知らせしているので、見逃したくない方は @ninjin_py_vba をフォローしてみてください🥕
@ninjin_py_vba をフォローシリーズ記事一覧
電子工作・自動化ツールの製作記録をシリーズごとにまとめています。気になるテーマからお読みください。
-
FILE.01 — IoT
Raspberry Pi Pico W × GASラズパイPico W×GASで自作!「LINEで動く温湿度&スマートリモコン」完全ロードマップ
「外出中のペットの室温が心配…」そんな思いからスタートしたIoT自作プロジェクトの総集編。温湿度監視からエアコン遠隔操作まで、仕組みをゼロから作りたい方のための全5回の開発記録です。
シリーズを読む -
FILE.02 — CNC
Arduino × レーザー刻印CNCCNC自作シリーズ
高精度な加工を目指し、本格的な自作CNC製作に挑戦中。現在は基幹パーツであるオリエンタルモーターの納品を待つ「設計・準備編」を公開。ハードとソフトの両面から、理想のマシンを形にする過程をリアルタイムにお届けします。
シリーズを読む -
FILE.03 — XY軸制御
Raspberry Pi × ステッピングモーターXYテーブルシリーズ
Raspberry Piとステッパモーターを使い、ゼロから2軸制御に挑む記録。OS設定から回路設計、多軸制御のPythonコードまで、躓きやすいポイントを徹底図解。電子工作初心者が「動く感動」を味わうための実戦ガイドです。
シリーズを読む -
FILE.04 — 業務自動化
Python × Excel × CustomTkinter【Python開発記】NINJIN Mail制作記
PythonとExcelを連携させ、実務で即戦力となるメール送信ツールを開発。CustomTkinterによるUI構築や、ミスを防ぐテンプレート活用術など、現場の「痒い所に手が届く」自動化ノウハウを細部まで丁寧に解説します。
シリーズを読む -
FILE.05 — 業務自動化
Python × Excel × GUIアプリ化Invoice Maker(請求書・見積書自動作成)
手作業の請求書作成から卒業!PythonでExcelデータを読み込み一括PDF化する「Invoice_Maker」の作り方を全3回で解説。基本ロジックからGUIアプリ化まで、実務で役立つ自動化ノウハウが満載です。
シリーズを読む -
FILE.06 — 業務自動化
Access × VBA【Access VBA開発記】対応履歴管理データベース
問い合わせ・トラブル対応履歴がExcelでバラバラに散らばる悩みから、Access+VBAで検索性の高い管理データベースを自作。テンプレート配布から設計解説、Win32 API実装で味わった失敗談まで、生成AI時代の検証記録を全3回でお届けします。
シリーズを読む



コメント