↑測定値をWeb上で確認する際に必要なIPアドレスをOLED画面に表示させた
温湿度の測定値表示にてこずる
PR2040 TypeC 16MBとRP2040 Zero、Raspberry Pi Pico W
たまにはと電子工作をしてみました。今更ながらですが、使用したのは以前購入してそのまま放置していたRaspberry Pi Pico互換機とPico Wです(旧~! Pico 2/2 Wの世代だというのに)。互換機は、PR2040 TypeC 16MBとRP2040 Zeroの2つです。
●試用結果

↑左からPR2040 TypeC 16MB、RP2040 Zero、Raspberry Pi Pico W
・PR2040 TypeC
PR-2040 TypeC(基板裏面にYD-RP2040 2022-V1.3 VCC-GND.COMの印刷がある)は、結果的になぜかOLEDの表示に成功しません。製品の不良あるいは眼が非常に悪くなっていて半田付けがうまくできていないせいかもしれません。
・RP2040 Zero
RP2040 Zero(基板上にRP2040 Zeroの文字とWaveShareのロゴが見える)では、温湿度センサーで測定した値をOLEDに表示できました。大きなメモリー容量が必要でなければ、小型かつ安価な点でお気に入りになりそうです。

↑PR2040 Zeroを使って温湿度センサーの測定値をOLEDに表示
・Raspberry Pi Pico W
Raspberry Pi Pico Wは、温湿度センサーの測定値をOLEDに表示するばかりか、Wi-Fi機能によりWeb上での表示もできるようになりました。
●OLEDの表示がおかしかったのは
試用は一見順調なようですが、実はOLEDをSSD1315ではなくてSSD1306とばかり思い込み、四苦八苦していました。
0.96インチのOLEDには種類があるのは知っていたはずなのに、確認を忘れてSSD1315のものを購入していたのでした。
0.96インチのOLEDには種類があるのは知っていたはずなのに、確認を忘れてSSD1315のものを購入していたのでした。
それでも、多少は動き、センサーなどをつけなければOLEDが表示できたりするので、間違いに気付きにくいところはありました。
OLEDが表示しないのは、低質な温湿度センサー(Si7021)とOLEDとで処理の速さが合わないのかと、タイミングをとったり、いちいち初期化させたり、IC2を分離し2パス構成にしたり、プルアップ抵抗を入れるなどと試行錯誤の上、ようやくOLEDの違いに気付いて動かすことができたもの。
簡単な電子工作だと思ったのにこんなにてこずるとは。簡単なはずなのに恥ずかしいと思ったからこそ、ここまで粘れたのでしょうが。
OLEDが表示しないのは、低質な温湿度センサー(Si7021)とOLEDとで処理の速さが合わないのかと、タイミングをとったり、いちいち初期化させたり、IC2を分離し2パス構成にしたり、プルアップ抵抗を入れるなどと試行錯誤の上、ようやくOLEDの違いに気付いて動かすことができたもの。
簡単な電子工作だと思ったのにこんなにてこずるとは。簡単なはずなのに恥ずかしいと思ったからこそ、ここまで粘れたのでしょうが。
●測定値のWebページ表示
↑測定値をWeb表示させた例
Webページ表示というのは、クラウドサービス利用ではなく、Pico WがWi-FiでWEBサーバーとなり、センサーの測定値をブラウザを開いて確認できるようにしたもののことです。ChatGPTに教えられるまで知りませんでした。
温湿度センサーの値をOLEDとWebページに表示させるプログラムにしては、OLEDの勘違いでたいそうなものになってしまいました。本来なら整理が必要なんでしょうが、全文を以下に示します。
import network
import socket
import time
from machine import Pin, I2C
from ssd1315 import SSD1315_I2C
# ===== Wi-Fi設定 =====
SSID = "Wi-Fiネットワーク名"
PASSWORD = "パスワード"
# ===== I2C初期化 =====
i2c_oled = I2C(0, scl=Pin(1), sda=Pin(0), freq=40000)
i2c_sensor = I2C(1, scl=Pin(3), sda=Pin(2), freq=40000)
print("OLED I2C:", i2c_oled.scan())
print("SENSOR I2C:", i2c_sensor.scan()) # 0x40が見えるはず
# ===== OLED初期化 =====
oled = SSD1315_I2C(128, 64, i2c_oled, addr=0x3C)
oled.fill(0)
oled.text("Booting...", 0, 20)
oled.show()
# ===== SI7021クラス (Hold Master) =====
class SI7021:
def __init__(self, i2c, addr=0x40):
self.i2c = i2c
self.addr = addr
def read(self):
try:
self.i2c.writeto(self.addr, b'\xE3')
t = self.i2c.readfrom(self.addr, 2)
temp = (175.72 * (t[0]<<8 | t[1]) / 65536) - 46.85
self.i2c.writeto(self.addr, b'\xE5')
h = self.i2c.readfrom(self.addr, 2)
hum = (125.0 * (h[0]<<8 | h[1]) / 65536) - 6
return temp, hum
except OSError:
return None, None
sensor = SI7021(i2c_sensor)
# ===== Wi-Fi接続 =====
oled.fill(0)
oled.text("WiFi connecting...", 0, 20)
oled.show()
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(SSID, PASSWORD)
while not wlan.isconnected():
time.sleep(1)
ip = wlan.ifconfig()[0]
print("IP:", ip)
# ===== グローバル =====
latest_temp = None
latest_hum = None
last_update = 0
# ===== Webサーバー準備 =====
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('0.0.0.0', 80))
s.listen(1)
s.settimeout(0.1) # 非ブロッキング
print("Server running at http://{}".format(ip))
# ===== メインループ =====
while True:
# ---- センサー更新 ----
if time.time() - last_update > 2:
t, h = sensor.read()
if t is not None:
latest_temp = t
latest_hum = h
# OLED表示
oled.fill(0)
oled.text("Temp:{:.1f} C".format(latest_temp), 0, 0)
oled.text("Hum: {:.1f} %".format(latest_hum), 0, 15)
oled.text("IP:" + ip, 0, 50)
oled.show()
last_update = time.time()
# ---- Web応答(非ブロッキング) ----
try:
cl, addr = s.accept()
cl.settimeout(1.0)
try:
request = cl.recv(1024)
except OSError:
request = b""
if latest_temp is None:
body = '{"temp":null,"hum":null}'
else:
body = '{{"temp":{:.1f},"hum":{:.1f}}}'.format(latest_temp, latest_hum)
# HTMLページで自動更新
html = f"""
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="refresh" content="2">
</head>
<body style="text-align:center;font-family:sans-serif;margin-top:40px;">
<h1>環境モニター</h1>
<h2>温度: {latest_temp:.1f} ℃</h2>
<h2>湿度: {latest_hum:.1f} %</h2>
<p>IP: {ip}</p>
</body>
</html>
"""
cl.send("HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n")
cl.send(html)
cl.close()
except OSError:
# 接続なしでもループ継続
pass
プログラムの作成には、CatGPTの力を借りましたので、そのことを付記します。

