บทความนี้เป็นตัวอย่างโปรแกรมสำหรับกรณีที่ต้องการแสดงแถบแสดงค่าอุณหภูมิและความชื้นดังภาพที่ 1 ด้วย MicroPython กับบอร์ด esp32 ที่ติดตั้ง OLED จะเขียนอย่างไร โดยอุปกรณ์ในการทดลองครั้งนี้ใช้ DHT22 เป็นอุปกรณ์วัดความชื้นและอุณหภูมิ โดยบอร์ดเชื่อมต่อกับบัส I2C เพื่อสื่อสารกับ OLED ผ่านทางขา GPIO4 และ GPIO5 สำหรับทำหน้าที่ SCL และ SDA ตามลำดับ พร้อมกันนี้ได้ต่อขาสัญญาณของ DHT22 เข้ากับขา GPIO15 เพื่อใช้สื่อสารกันระหว่างเซ็นเซอร์กับไมโครคอนโทรเลอร์
ขั้นตอนการทำงานของโปรแกรม
ขั้นตอนการทำงานของโปรแกรมตัวอย่างเป็นดังนี้
- กำหนดค่าการทำงานเบื้องต้น
- เริ่มต้นการทำงานของ OLED
- เริ่มต้นการทำงานของเซ็นเซอร์
- วงรอบโปรแกรมหลัก
- อ่านค่าจากเซ็นเซอร์
- แสดงค่าอุณหภูมิ
- แสดงข้อความค่าอุณหภูมิ
- แสดงค่าเริ่มต้น (0)
- แสดงค่าอุณหภูมิสูงสุด
- วาดเส้นกราฟแนวนอน
- คำนวณตำแหน่งของตัวชี้ค่าอุณหภูมิ (x1)
- วาดตัวชี้ตำแหน่งค่าอุณหภูมิ
- แสดงค่าความชื้น
- แสดงข้อความค่าความชื้น
- แสดงค่าเริ่มต้นของค่าความชื้น (0)
- แสดงค่าสูงสุดของค่าความชื้น
- วาดเส้นกราฟแนวนอน
- คำนวณตำแหน่งของตัวชี้ค่าความชื้น (x2)
- วาดตัวขี้ตำแหน่งของค่าความชื้น
โค้ดโปรแกรม
จากขั้นตอนของการทำงานนำมาเขียนโปรแกรมได้ดังนี้
# dhtBar.py
from machine import Pin,I2C
import dht
import machine
import gc
import ssd1306
import time
# system
gc.enable()
gc.collect()
machine.freq(240000000)
# OLED
sclPin = Pin(4)
sdaPin = Pin(5)
i2c = I2C(0,scl=sclPin,sda=sdaPin)
oled = ssd1306.SSD1306_I2C(128,32,i2c)
oled.poweron()
oled.contrast(255)
oled.init_display()
oled.fill(0)
oled.text("JarutEx", 40, 24)
for i in range(32):
oled.show()
oled.scroll(0,-1)
time.sleep_ms(30)
# Sensor
dht22 = dht.DHT22(Pin(15))
# main program
barWidth = 88
barHeight = 6
maxTem = 40.0
maxHum = 100.0
while True:
dht22.measure()
tem = dht22.temperature()
hum = dht22.humidity()
oled.fill(0)
oled.text("T={}C".format(tem), 10, 0)
oled.text("0",0,8)
oled.text("{}".format(int(maxTem)),100,8)
for x in range(barWidth):
oled.pixel(10+x,10,1)
x1 = int(barWidth*tem/maxTem)
for y in range(barHeight):
oled.pixel(x1-1,8+y,1)
oled.pixel(x1,8+y,1)
oled.pixel(x1+1,8+y,1)
oled.text("H={}%".format(hum), 10, 16)
oled.text("0",0,24)
oled.text("{}".format(int(maxHum)),100,24)
for x in range(barWidth):
oled.pixel(10+x,26,1)
x2 = int(barWidth*hum/maxHum)
for y in range(barHeight):
oled.pixel(x2-1,24+y,1)
oled.pixel(x2,24+y,1)
oled.pixel(x2+1,24+y,1)
oled.show()
time.sleep_ms(10000)
และเพื่อให้ดูแปลกตาในครั้งแรกที่ระบบทำงานเราจะให้ตัวชี้ค่าของอุณหภูมิและความชื้นวิ่งจาก 0 ไปหาค่าปัจจุบัน ทำให้โปรแกรมออกมาเป็นดังนี้
# dhtBar.py
from machine import Pin,I2C
import dht
import machine
import gc
import ssd1306
import time
# system
gc.enable()
gc.collect()
machine.freq(240000000)
# OLED
sclPin = Pin(4)
sdaPin = Pin(5)
i2c = I2C(0,scl=sclPin,sda=sdaPin)
oled = ssd1306.SSD1306_I2C(128,32,i2c)
oled.poweron()
oled.contrast(255)
oled.init_display()
oled.fill(0)
oled.text("JarutEx", 40, 24)
for i in range(32):
oled.show()
oled.scroll(0,-1)
time.sleep_ms(30)
# Sensor
dht22 = dht.DHT22(Pin(15))
# main program
barWidth = 88
barHeight = 6
maxTem = 40.0
maxHum = 100.0
bT0 = True
while True:
dht22.measure()
tem = dht22.temperature()
hum = dht22.humidity()
if (bT0): # 1st time ให้เอนิเมทกราฟ
bT0 = False
x1 = int(barWidth*tem/maxTem)
x2 = 0
xAnim = 0
while (xAnim <= x1):
oled.fill(0)
oled.text("T={}C".format(tem), 10, 0)
oled.text("0",0,8)
oled.text("{}".format(int(maxTem)),100,8)
oled.text("H={}%".format(hum), 10, 16)
oled.text("0",0,24)
oled.text("{}".format(int(maxHum)),100,24)
for x in range(barWidth):
oled.pixel(10+x,10,1)
oled.pixel(10+x,26,1)
for y in range(barHeight):
oled.pixel(xAnim-1,8+y,1)
oled.pixel(x2-1,24+y,1)
oled.pixel(xAnim,8+y,1)
oled.pixel(x2,24+y,1)
oled.pixel(xAnim+1,8+y,1)
oled.pixel(x2+1,24+y,1)
oled.show()
xAnim += 1
x2 = int(barWidth*hum/maxHum)
xAnim = 0
while (xAnim <= x2):
oled.fill(0)
oled.text("T={}C".format(tem), 10, 0)
oled.text("0",0,8)
oled.text("{}".format(int(maxTem)),100,8)
oled.text("H={}%".format(hum), 10, 16)
oled.text("0",0,24)
oled.text("{}".format(int(maxHum)),100,24)
for x in range(barWidth):
oled.pixel(10+x,10,1)
oled.pixel(10+x,26,1)
for y in range(barHeight):
oled.pixel(x1-1,8+y,1)
oled.pixel(xAnim-1,24+y,1)
oled.pixel(x1,8+y,1)
oled.pixel(xAnim,24+y,1)
oled.pixel(x1+1,8+y,1)
oled.pixel(xAnim+1,24+y,1)
oled.show()
xAnim += 1
else:
oled.fill(0)
oled.text("T={}C".format(tem), 10, 0)
oled.text("0",0,8)
oled.text("{}".format(int(maxTem)),100,8)
oled.text("H={}%".format(hum), 10, 16)
oled.text("0",0,24)
oled.text("{}".format(int(maxHum)),100,24)
for x in range(barWidth):
oled.pixel(10+x,10,1)
oled.pixel(10+x,26,1)
x1 = int(barWidth*tem/maxTem)
x2 = int(barWidth*hum/maxHum)
for y in range(barHeight):
oled.pixel(x1-1,8+y,1)
oled.pixel(x2-1,24+y,1)
oled.pixel(x1,8+y,1)
oled.pixel(x2,24+y,1)
oled.pixel(x1+1,8+y,1)
oled.pixel(x2+1,24+y,1)
oled.show()
time.sleep_ms(10000)
ส่วนตัวอย่างด้านล่างนี้เพิ่มเรื่องของการเอนิเมชันและให้แสดงค่าในช่วง min..max เพื่อให้ดูง่ายขึ้น
สรุป
จากบทความนี้จะพบว่าการแสดงกราฟแบบต่าง ๆ ต้องอาศัยการคำนวณเพื่อปรับค่าหรือแปลงค่าให้เหมาะสมกับการแสดงผล โดยหลักการคำนวณดังกล่าวนี้ยังคงเหมือนเดิมแม้เปลี่ยนอุปกรณ์แสดงผล แต่ค่าพารามิเตอร์ของความกว้าง ความสูง หรือตำแหน่งของการแสดงผลจะแตกต่างตามขนาดของอุปกรณ์ และผู้อ่านจะพบว่า ภาษาไพธอนของ Micropython เพียงพอสำหรับการแสดงผลเช่นกัน ถึงแม้การทำงานจริงนั้นช้ากว่าภาษา C/C++ ค่อนข้างมาก แต่ด้วยลักษณะของการทำงาน คือ อ่านค่าจากเซ็นเซอร์ DHT22 หรือ DHT11 ซึ่งทำงานแปลงค่า 2 วินาที และ 1 วินาที ตามลำดับ ซึ่งเป็นระยะเวลาที่มากพอสำหรับให้ภาษาไพธอนคำนวณและแสดงผล แต่การเขียนโปรแกรมทำได้ง่าย แก้ไขงานได้ันทีโดยไม่ต้องคอมไพล์และเริ่มต้นอัพโหลดใหม่ซึ่งกินเวลาในขั้นตอนของการพัฒนามากกว่าภาษาไพธอน นั่นหมายความว่าในข้อเสียย่อมมีข้อดีอยู่บ้าง และในข้อดีก็มีข้อเสียอยู่เช่นกัน
สุดท้าย ขอให้สนุกกับการเขียนโปรแกรมครับ
ท่านใดต้องการพูดคุยสามารถคอมเมนท์ได้เลยครับ
(C) 2020-2021, โดย อ.ดนัย เจษฎาฐิติกุล/อ.จารุต บุศราทิจ
ปรับปรุงเมื่อ 2021-08-26, 2021-11-25