[TH] DHT11 Web Report

บทความนี้เป็นการประยุกต์รวมการเขียนโปรแกรมภาษาไพธอนสำหรับ Micropython ที่ใช้กับ esp8266 หรือ esp32 ที่ต่อกับ DHT11 สำหรับเก็บค่าอุณหภูมิและความชื้น โดยรายงานผลอุณหภูมิ 10 รายการหลังสุดที่เก็บทุก 5 วินาทีให้เห็นดังภาพที่ 1

ภาพที่ 1 ตัวอย่างผลลัพธ์ของการแสดงผล

จากความต้องการแสดงผลค่าอุณหภูมิผ่านหน้าเว็บที่กำหนดให้เป็น AP ชื่อ JarutEx โดยแสดงข้อมูลย้อนหลัง 20 รายการ โดยให้ไมโครคอนโทรลเลอร์เก็บข้อมูลอุณหภูมิและความชื้นจากเซ็นเซอร์ DHT11 ซึ่งต้องการเขียนเป็นภาษาไพธอนกับบอร์ด esp8266 หรือ esp32 นั้น สามารถอ่านราชละเอียดที่เกี่ยวข้องได้จากบทความต่อไปนี้ครับ

  1. การใช้เครือข่ายไร้สาย
  2. การใช้ Timer
  3. โครงสร้างข้อมูลแบบคิว
  4. การใช้งาน DHT11/DHT22

อุปกรณ์

อุปกรณ์สำหรับการทดลองในบทความนี้ประกอบด้วย 2 อย่างดังนี้ ซึ่งเมื่อเชื่อมต่อให้เป็นตามภาพที่ 2 จะพบว่า ทีมงานเราเลือกใช้ esp32 และเชื่อมต่อ DHT11 เข้ากับขา GPIO23

  1. esp8266 หรือ esp32
  2. DHT11 หรือ DHT22
ภาพที่ 2 อุปกรณ์ในการทดลอง

โปรแกรม

โปรแกรมที่เขียนขึ้นประกอบด้วยส่วนต่าง ๆ ดังนี้

  1. ส่วนของการเตรียมการ
    1. กำหนดชื่อ AP และรหัสผ่าน
    2. สร้างวัตถุประเภทคิวเพื่อใช้เป็นที่พักข้อมูล
  2. ส่วนของโปรแกรมย่อย getDHT11 สำหรับเป็นฟังก์ชันเรียกกลับของตัวตั้งเวลา และทำหน้าที่อ่านอุณหภูมิและความชื้นไปเก็บใน items ของคิว
  3. ส่วนของการทำงานหลัก ประกอบด้วย
    1. สั่งให้ DHT เริ่มทำงาน
    2. สร้างตัวตั้งเวลาและกำหนดให้ทำงานทุก 5 วินาที แบบ PERIODIC โดยทุกครั้งที่ทำงานให้เรียกฟังก์ชัน getDHT11
    3. กำหนดโหมดงานของเครือข่ายไร้สายเป็นแบบ AP โดยกำหนดชื่อและรหัสผ่านตามที่กำหนดใน ssid และ password
    4. รอให้ระบบเริ่มทำงาน
    5. เตรียม socket สำหรับใช้ดักกับพอร์ต 80 และทำการรอการติดต่อกับลูกข่ายโดยกำหนดจำนวนสูงสุดในการเชื่อมต่อพร้ิมกันไว้ที่ 5 โหนด
    6. เมื่อมีการเชื่อมต่อ (ในการวนรอบ while True) จะทำการส่ง HTML+JavaScript กลับไป
#
# dht11stat.py
# 2021, JarutEx
# https://www.jarutex.com
#
import network as nw
from machine import Pin
import dht
import time
from machine import Timer
from jQueue import Queue
import socket

#set up
maxData = const(20)
dht11PinNo = const(23)
ssid = 'JarutEx-AP'
password = '123456789'
storage = Queue(maxData)
for i in range(maxData):
    storage.push([0,0])

def getDHT11(x):
    dht11.measure()
    tem = dht11.temperature()
    hum = dht11.humidity()
    #print("{}. T: {}C H: {}%".format(i, tem,hum))
    storage.pop()
    storage.push([tem,hum])

if __name__=='__main__':
    dht11 = dht.DHT11(Pin(dht11PinNo))
    dht11Timer = Timer( 0 )
    dht11Timer.init( period=5000, mode=Timer.PERIODIC, callback=getDHT11 )
    ap = nw.WLAN(nw.AP_IF)
    ap.active(True)
    ap.config(essid=ssid, password=password)
    while ap.active() == False:
        pass
    print("AP configuration\n{}".format(ap.ifconfig()))
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind(('', 80))
    s.listen(5)
    while True:
        conn, addr = s.accept()
        print('conn {} from {}'.format(conn, addr))
        request = conn.recv(1024)
        print('request = {}'.format(request))
        conn.send('HTTP/1.1 200 OK\n')
        conn.send('Content-Type: text/html\n')
        conn.send('Connection: close\n\n')
        conn.send("""<html><head><meta name="viewport"
          content="width=device-width, initial-scale=1">
          <meta charset="utf-8">
          </head>
          <body><div><h1>DHT11</h1>
            <canvas id="myCanvas" width="200" height="200" style="border:1px solid #000000;"></canvas>
            </div>
            <script>
                var canvas = document.getElementById("myCanvas");
                var ctx = canvas.getContext("2d");
            """)
        for i in range(maxData):
            conn.send("""
                ctx.fillStyle = "#AA0000";
                ctx.fillRect(0,
                """)
            conn.send(str(i*10))
            conn.send(",")
            conn.send(str(storage.items[i][0]*2))
            conn.send(",4);")
            conn.send("""
                ctx.fillStyle = "#000099";
                ctx.fillRect(0,
                """)
            conn.send(str(i*10+4))
            conn.send(",")
            conn.send(str(storage.items[i][1]*2))
            conn.send(",4);")
        conn.send("</script></body></html>")
        conn.close()

สรุป

จากตัวอย่างในบทความนี้จะเห็นว่าการเขียนโปรแกรมนั้นสามารถทำให้อุปกรณ์เพียงน้อยนิดทำงานได้หลากหลายและนำเสนอข้อมูลได้มากกว่าการแค่อ่านค่าของอุณหภูมิและความชื้น ซึ่งถ้านำข้อมูลทั้งหมดไปประกอบกับการใช้ ulab เพื่อนำไปคำนวณด้วยฟังก์ชันทางคณิตศาสตร์เพื่อหาความสำคัญหรือแปลงค่าเป็นค่าแบบอื่น ๆ ยิ่งทำให้นำเสนอข้อมูลได้หลากหลายยิ่งขึ้น ประกอบกับการเขียน JavaScript เพื่อวาดลง Canvas จะทำให้ผู้อ่านสามารถสร้างกราฟที่หลากหลาย หรือเพิ่มเติมข้อความอธิบายกราฟได้ดียิ่งขึ้น สุดท้ายขอให้สนุกกับการเขียนโปรแกรมครับ

ท่านใดต้องการพูดคุยคอมเมนท์ไว้ได้เลยครับ

(C) 2020-2021, โดย อ.ดนัย เจษฎาฐิติกุล/อ.จารุต บุศราทิจ

ปรับปรุงเมื่อ 2021-08-19, 2011-11-25