前回の投稿では pico wに搭載された無線(Wi-Fi)の使い方を公式サイトを参考に、実際に動かしてみましたが、今回はネットに、スマホで綺麗に表示する方法が在りましたので、自分なりに少しアレンジし部屋の気温、湿度をDHT20で測定しスマホで表示できるようにしてみました。
動作環境
ラズベリーパイ Pico W セットアップ済み
Windowsパソコン WIN10 か WIN11
開発環境Thonny(最新バージョン)4.1.3
接続図
DHT20をPico-Wに下図のように接続します。

実際の画像

プログラム
ネットワークの接続は、前回の投稿を参考にしてください。
今回はHTMLの部分と、ラズパイpicowのプログラムを説明します。
HTML
基本のHTMLは外国のサイトにあったと思いますが、これを参考にして、ボタンを1個追加して3個にしました。
あと日本語を表示させるために
<!DOCTYPE html> の下に <html lang=”ja”> を <head>の下に
<meta charset=”UTF-8″>を追加します。
またスタイルシートはパラメターを{}で囲むので使いませんので、タグに直接書きました。
データのやり取りは下記のようにします。
<p>{ti} {mi} {se}<p><br></br>
<p>{tp} {hu}<p></body>
それが下記のHTMLです。
html = f"""
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<center><h1>Raspberry Pi Pico W</h1></center>
<form><center>
<center> <button style = "background-color: #4CAF50; border: 2px solid #000000; color: white; padding: 15px 32px; text-align: center; display: inline-block; font-size: 18px; cursor: pointer;" name="led" value="on" type="submit">LED ON</button>
<br></br>
<center> <button style = "background-color: #D11D53; border: 2px solid #000000; color: white; padding: 15px 31px; text-align: center; display: inline-block; font-size: 18px; cursor: pointer;" name="led" value="off" type="submit">LED OFF</button>
<br></br>
<center> <button style = "background-color: #b3b61a; border: 2px solid #000000; color: white; padding: 15px 26px; text-align: center; display: inline-block; font-size: 18px; cursor: pointer;" name="temp" value="get" type="submit">TEMP GET</button>
</form>
<br></br>
<p>{ti} 時 {mi} 分 {se} 秒<p>
<p> 気温 {tem} 湿度 {hmu}</p>
</body>
</html>
"""
スマホで表示画面

DHT20プログラム
プログラムの見通しを良くするため、DHT20のデータ取得をするのを、モジュール化します。
from machine import Pin, I2C
import time
import utime
aab=[0,0]
def crc8(bytlist):
crc=0xFF #crc初期値DHT20
poly = 0x31
for i in bytlist:
crc ^= i
for indx in range(8):
if crc & 0x80:
crc = ((crc << 1) & 0xFF) ^ poly
else:
crc = ((crc << 1) & 0xFF)
return crc
def dht20():
global aab
time.sleep(0.05)
i2c = I2C(0, scl=Pin(1), sda=Pin(0), freq=200000)
addr = i2c.scan()
# print( "address is :" + str(addr) )
address=0x38
set = [0xAC, 0x33, 0x00]
buff = bytearray(set)
ret=i2c.readfrom_mem(address,0x71,1)
# print(ret)
dat=[]
i2c.writeto(address, buff)
time.sleep(0.1)
dat = i2c.readfrom(address,7)
hum = dat[1] << 12 | dat[2] << 4 | ((dat[3] & 0xF0) >> 4)
tmp = ((dat[3] & 0x0F) << 16) | dat[4] << 8 | dat[5]
hum = hum / 2**20 * 100
tmp = tmp / 2**20 * 200 - 50
dat1=dat[0:6]
a1 = crc8(dat1)
a2=(dat[6])
hum = int(hum*10)/10
tmp = int(tmp*10)/10
aab[0] = hum
aab[1] = tmp
def g_data():
global aab
return aab
上記のプログラムをget_dht20.pyとしてピコw本体に保存し、 メインプログラムで
from get_dht20 import dht20,g_data を定義してdht20()を呼びだし温度湿度確定、g_data()でデータを取得します。
今回二つの関数を定義し別々に呼び出さないと、メインプログラムで、私は安定してうまく動かすことができませんでした。
別の方法もあると思いまが、一例です。
メインプログラム
こちらがメインプログラムです。
import network
import socket
from time import sleep
from picozero import pico_temp_sensor, pico_led
from machine import Pin, I2C
from get_data import dht20 , g_data
import machine
import ntptime
import utime
# Wi-Fi ルーターのSSIDとパスワード
# 自分の環境に書き換えてください。
ssid = '??????????'
password = '??????????'
def connect():
#Connect to WLAN
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, password)
while wlan.isconnected() == False:
print('Waiting for connection...')
sleep(1)
ip = wlan.ifconfig()[0]
print(f'Connected on {ip}')
return ip
def webpage(ti,fun,byu,ond,hum):
html = f"""
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<center><h1>Raspberry Pi Pico W</h1></center>
<form><center>
<center> <button style = "background-color: #4CAF50; border: 2px solid #000000; color: white; padding: 15px 32px; text-align:
center; display: inline-block; font-size: 18px; cursor: pointer;" name="led" value="on" type="submit">LED ON</button>
<br></br>
<center> <button style = "background-color: #D11D53; border: 2px solid #000000; color: white; padding: 15px 31px; text-align:
center; display: inline-block; font-size: 18px; cursor: pointer;" name="led" value="off" type="submit">LED OFF</button>
<br></br>
<center> <button style = "background-color: #b3b61a; border: 2px solid #000000; color: white; padding: 15px 26px; text-align:
center; display: inline-block; font-size: 18px; cursor: pointer;" name="temp" value="get" type="submit">TEMP GET</button>
</form>
<br></br>
<p>{ti}時 {fun}分 {byu}秒<p>
<p> 温度 {ond} 湿度 {hum} </p>
</body>
</html>
"""
return str(html)
def serve(connection):
#Start a web server
state = 'OFF'
pico_led.off()
aaa = dht20()
while True:
client = connection.accept()[0]
request = client.recv(1024)
request = str(request)
try:
request = request.split()[1]
except IndexError:
pass
if request == '/?led=on':
pico_led.on()
elif request =='/?led=off':
pico_led.off()
elif request == '/?temp=get':
dht20()
jst_time=ntptime.time() + 3600 * 9
local_t=utime.localtime(jst_time)
temp_hum = g_data()
html = webpage(local_t[3],local_t[4],local_t[5],temp_hum[1],temp_hum[0])
client.send(html)
client.close()
def open_socket(ip):
# Open a socket
address = (ip, 80)
connection = socket.socket()
connection.bind(address)
connection.listen(1)
return connection
try:
ip = connect()
connection = open_socket(ip)
serve(connection)
except KeyboardInterrupt:
machine.reset()
main.py名前でpicoW本体に保存すれば、プログラムは自動実行され、ラズベリーパイpicowのプライベートアドレスにアクセスすれば表示されます。
不安定な時もありましたが、動きました。
スマホ表示画面

LED ON で点灯 LED OFF で消灯 TEMP GET で温度、湿度、更新です。
DHT20は、温度湿度ともに実際より高く表示されるので、調整が必要なようです。