Pico W (Wi-Fi)の使い方Ⅱスマホにデータ表示

Pico W (Wi-Fi)の使い方2スマホにデータ表示

前回の投稿では 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は、温度湿度ともに実際より高く表示されるので、調整が必要なようです。

タイトルとURLをコピーしました