บทความนี้เป็นการประยุกต์รวมการเขียนโปรแกรมภาษาไพธอนสำหรับ Micropython ที่ใช้กับ esp8266 หรือ esp32 ที่ต่อกับ DHT11 สำหรับเก็บค่าอุณหภูมิและความชื้น โดยรายงานผลอุณหภูมิ 10 รายการหลังสุดที่เก็บทุก 5 วินาทีให้เห็นดังภาพที่ 1
จากความต้องการแสดงผลค่าอุณหภูมิผ่านหน้าเว็บที่กำหนดให้เป็น AP ชื่อ JarutEx โดยแสดงข้อมูลย้อนหลัง 20 รายการ โดยให้ไมโครคอนโทรลเลอร์เก็บข้อมูลอุณหภูมิและความชื้นจากเซ็นเซอร์ DHT11 ซึ่งต้องการเขียนเป็นภาษาไพธอนกับบอร์ด esp8266 หรือ esp32 นั้น สามารถอ่านราชละเอียดที่เกี่ยวข้องได้จากบทความต่อไปนี้ครับ
อุปกรณ์
อุปกรณ์สำหรับการทดลองในบทความนี้ประกอบด้วย 2 อย่างดังนี้ ซึ่งเมื่อเชื่อมต่อให้เป็นตามภาพที่ 2 จะพบว่า ทีมงานเราเลือกใช้ esp32 และเชื่อมต่อ DHT11 เข้ากับขา GPIO23
- esp8266 หรือ esp32
- DHT11 หรือ DHT22
โปรแกรม
โปรแกรมที่เขียนขึ้นประกอบด้วยส่วนต่าง ๆ ดังนี้
- ส่วนของการเตรียมการ
- กำหนดชื่อ AP และรหัสผ่าน
- สร้างวัตถุประเภทคิวเพื่อใช้เป็นที่พักข้อมูล
- ส่วนของโปรแกรมย่อย getDHT11 สำหรับเป็นฟังก์ชันเรียกกลับของตัวตั้งเวลา และทำหน้าที่อ่านอุณหภูมิและความชื้นไปเก็บใน items ของคิว
- ส่วนของการทำงานหลัก ประกอบด้วย
- สั่งให้ DHT เริ่มทำงาน
- สร้างตัวตั้งเวลาและกำหนดให้ทำงานทุก 5 วินาที แบบ PERIODIC โดยทุกครั้งที่ทำงานให้เรียกฟังก์ชัน getDHT11
- กำหนดโหมดงานของเครือข่ายไร้สายเป็นแบบ AP โดยกำหนดชื่อและรหัสผ่านตามที่กำหนดใน ssid และ password
- รอให้ระบบเริ่มทำงาน
- เตรียม socket สำหรับใช้ดักกับพอร์ต 80 และทำการรอการติดต่อกับลูกข่ายโดยกำหนดจำนวนสูงสุดในการเชื่อมต่อพร้ิมกันไว้ที่ 5 โหนด
- เมื่อมีการเชื่อมต่อ (ในการวนรอบ 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