เริ่มต้นเนื้อหา
สร้างชุดวัดอุณหภูมิและความชื้นในอากาศด้วย AM2302/DHT22
โปรเจคต่อไปนี้เป็นการสร้างชุดวัดอุณหภูมิและความชื้นในอากาศด้วยเซนเซอร์ AM2302/DHT22 โดยแสดงผลการวัดบนจอ OLED ขนาด 0.96″ ประมวลผลด้วย Esp32 เพื่อใช้วัดอุณหภูมิและความชื้นในสำนักงงานหรือบ้านพักอาศัย โดยเลือกประกอบชิ้นส่วนลงบอร์ด DIN Rail Esp32 NodeMCU Screw Terminal เนื่องจากมองเห็นว่าการที่มีแผงวงจรขยายขาบอร์ดประมวลผล ESP32 NodeMCU ด้วย Screw Terminal จะทำให้สะดวกในการติดตั้ง Input และ Output เพิ่มเติมได้ในอนาคตหากมีการพัฒนาต่อยอดระบบ
คุณสมบัติของเครื่อง
- แสดงผลค่าอุณหภูมิ
- แสดงผลค่าความชื้น
- สามารถติดตั้งเซนเซอร์เพิ่มเติมได้ในอนาคต
อุปกรณ์
AM2302/DHT22 Digital | X 1 | ||
ESP32 DEVKIT V1 | X 1 | ||
จอแสดงผล OLED Display I2C IIC 0.96″ | X 1 | ||
บอร์ด DIN Rail Esp32 NodeMCU Screw Terminal | X 1 |
ซอฟแวร์ที่เกี่ยวข้อง
Arduino IDE | |
U8glib library |
ขั้นตอนการปฏิบัติ
วางแผนผังระบบ
IO ของระบบประกอบด้วย
- 1 Digital input (AM2302/DHT22)
- 1 I2C output (SSD1306OLED Display Module 0.96″ 128 × 64)
ทดลองสร้างต้นแบบ
บอร์ดทดลอง Arduino และ Esp32 NodeMCU Dev Board แบบ 2 in 1 ช่วยอำนวยความสะดวกอย่างมากในการทดลองประกอบวงจรก่อนใช้งานจริง เมื่อประกอบวงจรเสร็จแล้วขั้นตอนต่อไปคือการทดสอบโค้ดโปรแกรม
ทดสอบโค้ดโปรแกรม
Flash โปรแกรมต่อไปนี้ลง Esp32 และทดลองรัน
#include
#include "DHT.h"
#define DHTPIN 15
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
int draw_state = 0;
unsigned long previousMillis = 0;
long interval = 3000;
String Temp, Humi;
#define TempIcon_width 27
#define TempIcon_height 47
static const unsigned char TempIcon_bits[] U8X8_PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x30, 0x06, 0x00, 0x00,
0x18, 0x0c, 0x00, 0x00, 0x18, 0x08, 0x00, 0x00, 0x18, 0x08, 0x00, 0x00,
0x18, 0x08, 0x00, 0x00, 0x18, 0x08, 0x00, 0x00, 0x18, 0x08, 0x00, 0x00,
0x18, 0x08, 0x00, 0x00, 0xd8, 0xc9, 0x3f, 0x00, 0xd8, 0x09, 0x00, 0x00,
0xd8, 0x09, 0x00, 0x00, 0xd8, 0x09, 0x00, 0x00, 0xd8, 0x09, 0x00, 0x00,
0xd8, 0xc9, 0x03, 0x00, 0xd8, 0xc9, 0x01, 0x00, 0xd8, 0x09, 0x00, 0x00,
0xd8, 0x09, 0x00, 0x00, 0xd8, 0x09, 0x00, 0x00, 0xd8, 0xc9, 0xff, 0x00,
0xd8, 0xc9, 0xff, 0x01, 0xd8, 0x09, 0x00, 0x00, 0xd8, 0x09, 0x00, 0x00,
0xd8, 0x09, 0x00, 0x00, 0xd8, 0x09, 0x00, 0x00, 0xd8, 0xc9, 0x0f, 0x00,
0xd8, 0x09, 0x00, 0x00, 0xd8, 0x09, 0x00, 0x00, 0xd8, 0x09, 0x00, 0x00,
0xd8, 0x09, 0x00, 0x00, 0xd8, 0x09, 0x00, 0x00, 0xd8, 0x09, 0xe0, 0x00,
0xdc, 0x19, 0xf8, 0x00, 0xcc, 0x31, 0x0c, 0x00, 0xe6, 0x27, 0x0c, 0x00,
0xd3, 0x67, 0x0c, 0x00, 0x8b, 0x4f, 0x0c, 0x00, 0xcb, 0x4f, 0x1c, 0x00,
0xfb, 0x4f, 0xf8, 0x00, 0xfb, 0x4f, 0x00, 0x00, 0xf3, 0x6f, 0x00, 0x00,
0xe6, 0x67, 0x00, 0x00, 0xc6, 0x31, 0x00, 0x00, 0x1c, 0x18, 0x00, 0x00,
0xf8, 0x0f, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00
};
#define HumiIcon_width 27
#define HumiIcon_height 47
static const unsigned char HumiIcon_bits[] U8X8_PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
0x00, 0x70, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00,
0x00, 0xdc, 0x01, 0x00, 0x00, 0x8e, 0x01, 0x00, 0x00, 0x86, 0x03, 0x00,
0x00, 0x06, 0x03, 0x00, 0x00, 0x03, 0x07, 0x00, 0x80, 0x03, 0x06, 0x00,
0x80, 0x01, 0x0c, 0x00, 0xc0, 0x01, 0x1c, 0x00, 0xc0, 0x00, 0x18, 0x00,
0xe0, 0x00, 0x38, 0x00, 0x60, 0x00, 0x30, 0x00, 0x70, 0x00, 0x70, 0x00,
0x30, 0x00, 0xe0, 0x00, 0x38, 0x00, 0xc0, 0x00, 0x18, 0x00, 0xc0, 0x01,
0x1c, 0x00, 0x80, 0x01, 0x0c, 0x00, 0x80, 0x03, 0x0e, 0x00, 0x80, 0x03,
0x06, 0x00, 0x00, 0x03, 0x06, 0x00, 0x00, 0x03, 0x07, 0x00, 0x00, 0x07,
0x03, 0x00, 0x00, 0x06, 0x03, 0x00, 0x00, 0x06, 0x03, 0x00, 0x00, 0x06,
0x63, 0x00, 0x00, 0x06, 0x63, 0x00, 0x00, 0x06, 0x63, 0x00, 0x00, 0x06,
0xe3, 0x00, 0x00, 0x06, 0xc7, 0x00, 0x00, 0x06, 0xc6, 0x01, 0x00, 0x07,
0x86, 0x03, 0x00, 0x03, 0x0e, 0x1f, 0x00, 0x03, 0x0e, 0x1e, 0x80, 0x01,
0x1c, 0x00, 0xc0, 0x01, 0x38, 0x00, 0xe0, 0x00, 0x78, 0x00, 0x70, 0x00,
0xf0, 0x00, 0x38, 0x00, 0xe0, 0x07, 0x1f, 0x00, 0x80, 0xff, 0x0f, 0x00,
0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00
};
void setup() {
dht.begin();
u8g2.begin();
}
void drawTemp() {
int t = dht.readTemperature();
if (isnan(t)) {
return;
}
Temp = String(t) + char(176) + "C";
u8g2.setFont(u8g2_font_helvR14_tr);
u8g2.setCursor(12, 15);
u8g2.print("TEMP");
u8g2.setFont(u8g2_font_fub30_tf);
u8g2.setCursor(36, 58);
u8g2.print(Temp);
u8g2.drawXBMP( 0, 17, TempIcon_width, TempIcon_height, TempIcon_bits);
}
void drawHumi() {
int h = dht.readHumidity();
if (isnan(h)) {
return;
}
Humi = String(h) + "%";
u8g2.setFont(u8g2_font_helvR14_tr);
u8g2.setCursor(24, 15);
u8g2.print("HUMI");
u8g2.setFont(u8g2_font_fub30_tf);
u8g2.setCursor(36, 58);
u8g2.print(Humi);
u8g2.drawXBMP( 0, 17, HumiIcon_width, HumiIcon_height, HumiIcon_bits);
}
void loop() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis > interval) {
previousMillis = currentMillis;
u8g2.firstPage();
do {
switch (draw_state) {
case 0: drawTemp(); break;
case 1: drawHumi(); break;
}
} while (u8g2.nextPage());
draw_state++;
if (draw_state > 1) {
draw_state = 0;
}
}
}
ประกอบอุปกรณ์ลงบอร์ด
ประกอบอุปกรณ์ทั้งหมดลงบอร์ดดังรูปด้านบน ดังนี้
- ต่อสายประกอบเซนเซอร์ AM2302 เข้า Screw terminal ช่อง 3V3, GND, D2
- เสียบ Esp32 ลง Pin Header บนบอร์ด
- บัดกรี OLED ลงบนบอร์ด (ควรใส่ Pin Header) และจั๊มสายเข้าจุด SDA, SCL, 5V, GND บนบอร์ดให้ถูกต้อง
อธิบายโค้ด
เรียกใช้งานไลบรารี่
#include <U8g2lib.h>
#include "DHT.h"
เรียกใช้งานไลบรารี่ Ug2 สำหรับการควบคุมแสดงผลบนหน้าจอ OLED ขนาด 128×64 และ ไลบรารี่ DHT เพื่ออ่านค่าอุณหภูมิและความชื้นจากเซ็นเซอร์ DHT22
สร้างอ็อบเจกต์-DHT
#define DHTPIN 15
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
ในส่วนนี้ของโค้ดคือการกำหนดค่าคงที่ (constants) สำหรับเซ็นเซอร์ DHT22 และการสร้างอ็อบเจกต์ของคลาส DHT เพื่อเชื่อมต่อกับเซ็นเซอร์:
1. `#define DHTPIN 15`: ใช้สำหรับกำหนดค่าของขาที่เชื่อมต่อกับเซ็นเซอร์ DHT22 ซึ่งในที่นี้คือขาที่ 15 (หรือ D15 หรือ GPIO 15) ของ Esp32
2. `#define DHTTYPE DHT22`: ใช้สำหรับกำหนดค่าประเภทของเซ็นเซอร์ DHT ที่ใช้ ซึ่งในที่นี้คือ DHT22 ซึ่งเป็นเซ็นเซอร์วัดอุณหภูมิและความชื้น.
3. `DHT dht(DHTPIN, DHTTYPE);`: คำสั่งนี้จะสร้างอ็อบเจกต์ชื่อ `dht` จากคลาส DHT โดยกำหนดขาที่เชื่อมต่อกับเซ็นเซอร์และประเภทของเซ็นเซอร์ตามที่กำหนดในค่าคงที่ `DHTPIN` และ `DHTTYPE` ที่ได้กำหนดไว้ด้านบน.
อ็อบเจกต์ `dht` ที่สร้างขึ้นในบรรทัดนี้จะถูกใช้ในฟังก์ชัน `drawTemp()` และ `drawHumi()` เพื่ออ่านค่าอุณหภูมิและความชื้นจากเซ็นเซอร์ DHT22 และแสดงผลบนหน้าจอ OLED ตามที่ได้ทำการระบุไว้ในฟังก์ชันดังกล่าว.
สร้างอ็อบเจกต์-U8G2
U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
int draw_state = 0;
unsigned long previousMillis = 0;
long interval = 3000;
String Temp, Humi;
ในส่วนนี้ของโค้ด เราจะเห็นการกำหนดค่าและอ็อบเจกต์สำหรับการควบคุมหน้าจอ OLED และตัวแปรที่ใช้สำหรับการจัดการกับการแสดงผลบนหน้าจอ:
1. `U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);`:
– ในบรรทัดนี้ เราสร้างอ็อบเจกต์ `u8g2` ของคลาส U8G2_SSD1306_128X64_NONAME_1_HW_I2C เพื่อควบคุมหน้าจอ OLED ขนาด 128×64 ที่เชื่อมต่อผ่าน I2C โดยใช้ hardware I2C (HW_I2C).
– `U8G2_R0` คือการกำหนดการหมุนหน้าจอที่ไม่มีการหมุน (rotation 0).
– `U8X8_PIN_NONE` ใช้สำหรับการกำหนดขาที่ใช้เชื่อมต่อเส้น Reset ของหน้าจอ ในที่นี้เราไม่ได้ใช้เส้น Reset จึงใส่ค่า `U8X8_PIN_NONE`.
2. `int draw_state = 0;`:
– ตัวแปร `draw_state` เป็นตัวแปรที่ใช้เก็บสถานะการแสดงผลบนหน้าจอ OLED ว่าเรากำลังแสดงผลอุณหภูมิหรือความชื้นอยู่.
– เริ่มต้นที่ 0 หมายถึงเราจะเริ่มแสดงผลอุณหภูมิก่อน.
3. `unsigned long previousMillis = 0;`:
– ตัวแปร `previousMillis` เป็นตัวแปรที่ใช้เก็บค่าเวลาล่าสุดที่มีการเปลี่ยนสถานะการแสดงผล.
– เริ่มต้นที่ 0 หมายถึงเราจะเริ่มจับเวลาตั้งแต่เริ่มต้น.
4. `long interval = 3000;`:
– ตัวแปร `interval` เป็นตัวแปรที่ใช้กำหนดช่วงเวลาระหว่างการเปลี่ยนสถานะการแสดงผล.
– ค่าเวลานี้คือ 3000 มิลลิวินาทีหรือ 3 วินาที.
5. `String Temp, Humi;`:
– ตัวแปร `Temp` และ `Humi` เป็นตัวแปรที่ใช้เก็บค่าอุณหภูมิและความชื้นที่อ่านมาจากเซ็นเซอร์ DHT22 และจะถูกนำมาแสดงผลบนหน้าจอ OLED.
– เป็นตัวแปรประเภท `String` เพื่อเก็บข้อความที่จะแสดง.
สร้างไอคอน
#define TempIcon_width 27
#define TempIcon_height 47
static const unsigned char TempIcon_bits[] U8X8_PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x30, 0x06, 0x00, 0x00,
0x18, 0x0c, 0x00, 0x00, 0x18, 0x08, 0x00, 0x00, 0x18, 0x08, 0x00, 0x00,
0x18, 0x08, 0x00, 0x00, 0x18, 0x08, 0x00, 0x00, 0x18, 0x08, 0x00, 0x00,
0x18, 0x08, 0x00, 0x00, 0xd8, 0xc9, 0x3f, 0x00, 0xd8, 0x09, 0x00, 0x00,
0xd8, 0x09, 0x00, 0x00, 0xd8, 0x09, 0x00, 0x00, 0xd8, 0x09, 0x00, 0x00,
0xd8, 0xc9, 0x03, 0x00, 0xd8, 0xc9, 0x01, 0x00, 0xd8, 0x09, 0x00, 0x00,
0xd8, 0x09, 0x00, 0x00, 0xd8, 0x09, 0x00, 0x00, 0xd8, 0xc9, 0xff, 0x00,
0xd8, 0xc9, 0xff, 0x01, 0xd8, 0x09, 0x00, 0x00, 0xd8, 0x09, 0x00, 0x00,
0xd8, 0x09, 0x00, 0x00, 0xd8, 0x09, 0x00, 0x00, 0xd8, 0xc9, 0x0f, 0x00,
0xd8, 0x09, 0x00, 0x00, 0xd8, 0x09, 0x00, 0x00, 0xd8, 0x09, 0x00, 0x00,
0xd8, 0x09, 0x00, 0x00, 0xd8, 0x09, 0x00, 0x00, 0xd8, 0x09, 0xe0, 0x00,
0xdc, 0x19, 0xf8, 0x00, 0xcc, 0x31, 0x0c, 0x00, 0xe6, 0x27, 0x0c, 0x00,
0xd3, 0x67, 0x0c, 0x00, 0x8b, 0x4f, 0x0c, 0x00, 0xcb, 0x4f, 0x1c, 0x00,
0xfb, 0x4f, 0xf8, 0x00, 0xfb, 0x4f, 0x00, 0x00, 0xf3, 0x6f, 0x00, 0x00,
0xe6, 0x67, 0x00, 0x00, 0xc6, 0x31, 0x00, 0x00, 0x1c, 0x18, 0x00, 0x00,
0xf8, 0x0f, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00
};
#define HumiIcon_width 27
#define HumiIcon_height 47
static const unsigned char HumiIcon_bits[] U8X8_PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
0x00, 0x70, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00,
0x00, 0xdc, 0x01, 0x00, 0x00, 0x8e, 0x01, 0x00, 0x00, 0x86, 0x03, 0x00,
0x00, 0x06, 0x03, 0x00, 0x00, 0x03, 0x07, 0x00, 0x80, 0x03, 0x06, 0x00,
0x80, 0x01, 0x0c, 0x00, 0xc0, 0x01, 0x1c, 0x00, 0xc0, 0x00, 0x18, 0x00,
0xe0, 0x00, 0x38, 0x00, 0x60, 0x00, 0x30, 0x00, 0x70, 0x00, 0x70, 0x00,
0x30, 0x00, 0xe0, 0x00, 0x38, 0x00, 0xc0, 0x00, 0x18, 0x00, 0xc0, 0x01,
0x1c, 0x00, 0x80, 0x01, 0x0c, 0x00, 0x80, 0x03, 0x0e, 0x00, 0x80, 0x03,
0x06, 0x00, 0x00, 0x03, 0x06, 0x00, 0x00, 0x03, 0x07, 0x00, 0x00, 0x07,
0x03, 0x00, 0x00, 0x06, 0x03, 0x00, 0x00, 0x06, 0x03, 0x00, 0x00, 0x06,
0x63, 0x00, 0x00, 0x06, 0x63, 0x00, 0x00, 0x06, 0x63, 0x00, 0x00, 0x06,
0xe3, 0x00, 0x00, 0x06, 0xc7, 0x00, 0x00, 0x06, 0xc6, 0x01, 0x00, 0x07,
0x86, 0x03, 0x00, 0x03, 0x0e, 0x1f, 0x00, 0x03, 0x0e, 0x1e, 0x80, 0x01,
0x1c, 0x00, 0xc0, 0x01, 0x38, 0x00, 0xe0, 0x00, 0x78, 0x00, 0x70, 0x00,
0xf0, 0x00, 0x38, 0x00, 0xe0, 0x07, 0x1f, 0x00, 0x80, 0xff, 0x0f, 0x00,
0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00
};
ในส่วนนี้ของโค้ด คือการกำหนดขนาดและข้อมูลของไอคอน (icons) สำหรับการแสดงผลบนหน้าจอ OLED:
1. `#define TempIcon_width 27` และ `#define TempIcon_height 47`:
– ใช้สำหรับกำหนดขนาดของไอคอนที่จะแสดงผลบนหน้าจอ OLED เมื่อเรียกใช้ฟังก์ชัน `u8g2.drawXBMP`.
– ในที่นี้ `TempIcon_width` คือความกว้างของไอคอน (27 พิกเซล) และ `TempIcon_height` คือความสูงของไอคอน (47 พิกเซล).
2. `static const unsigned char TempIcon_bits[] U8X8_PROGMEM = {…}`:
– นี่คือแบบอาร์เรย์ของข้อมูลบิตที่เป็นรูปแบบไอคอน สำหรับแสดงบนหน้าจอ OLED.
– โค้ดทั้งหมดจะถูกเก็บในแรมแบบคงที่ (PROGMEM) เนื่องจากข้อมูลเป็นค่อนข้างมาก.
– ข้อมูลที่กำหนดในรูปแบบนี้เป็นข้อมูลบิตของไอคอน ที่เรียงตามลำดับแต่ละแถวของไอคอน.
3. แบบเดียวกันกับข้อมูลไอคอน `HumiIcon_width`, `HumiIcon_height`, และ `HumiIcon_bits[]` สำหรับไอคอนของความชื้น.
ไอคอนทั้งสองจะถูกใช้ในฟังก์ชัน `drawTemp()` และ `drawHumi()` เพื่อแสดงไอคอนของอุณหภูมิและความชื้นตามลำดับ เรียกใช้งานการแสดงผลบนหน้าจอ OLED ด้วย `u8g2.drawXBMP` และเรียกฟังก์ชันดึงข้อมูลไอคอนจากแรมคงที่ที่เก็บไว้.
การสร้างอาร์เรย์ของข้อมูลบิตที่เป็นรูปแบบไอคอน สามารถทำได้โดยใช้โปรแกรม GIMP เปิดรูปที่ต้องการขึ้นมา ปรับขนาดให้พอดีกับหน้าจอ OLED แล้วเซฟเป็นไฟล์สกุล .xbm จากนั้นเปิดไฟล์ที่เซฟด้วยโปรแกรม Notepad จะเห็นโค้ดที่สามารถก๊อบปี้มามาใช้ในโปรแกรมได้
ฟังก์ชัน-setup
void setup() {
dht.begin();
u8g2.begin();
}/* Your code... */
ในส่วนนี้ของโค้ดเป็นฟังก์ชัน `setup()` ที่จะถูกเรียกเมื่อเราเปิดตัวอุปกรณ์หรือโปรแกรมเพื่อกำหนดค่าเริ่มต้น:
1. `dht.begin();`:
– ในบรรทัดนี้ เราเรียกใช้เมธอด `begin()` บนอ็อบเจกต์ `dht` ซึ่งเป็นตัวแปรชนิด DHT เพื่อเริ่มเชื่อมต่อกับเซ็นเซอร์ DHT22 และเตรียมให้เซ็นเซอร์พร้อมทำงาน.
2. `u8g2.begin();`:
– ในบรรทัดนี้ เราเรียกใช้เมธอด `begin()` บนอ็อบเจกต์ `u8g2` ซึ่งเป็นตัวแปรชนิด U8G2_SSD1306_128X64_NONAME_1_HW_I2C เพื่อเริ่มเชื่อมต่อกับหน้าจอ OLED และเตรียมให้หน้าจอพร้อมทำงาน.
การเรียกใช้ `begin()` สำหรับทั้ง DHT เซ็นเซอร์และหน้าจอ OLED เป็นขั้นตอนที่จำเป็นต้องทำใน `setup()` เพื่อให้ตัวเซ็นเซอร์และหน้าจอพร้อมใช้งานเมื่อโปรแกรมเริ่มทำงาน.
การวาดแสดงผล
void drawTemp() {
int t = dht.readTemperature();
if (isnan(t)) {
return;
}
Temp = String(t) + char(176) + "C";
u8g2.setFont(u8g2_font_helvR14_tr);
u8g2.setCursor(12, 15);
u8g2.print("TEMP");
u8g2.setFont(u8g2_font_fub30_tf);
u8g2.setCursor(36, 58);
u8g2.print(Temp);
u8g2.drawXBMP( 0, 17, TempIcon_width, TempIcon_height, TempIcon_bits);
}
void drawHumi() {
int h = dht.readHumidity();
if (isnan(h)) {
return;
}
Humi = String(h) + "%";
u8g2.setFont(u8g2_font_helvR14_tr);
u8g2.setCursor(24, 15);
u8g2.print("HUMI");
u8g2.setFont(u8g2_font_fub30_tf);
u8g2.setCursor(36, 58);
u8g2.print(Humi);
u8g2.drawXBMP( 0, 17, HumiIcon_width, HumiIcon_height, HumiIcon_bits);
}
ในส่วนนี้ของโค้ดคือฟังก์ชันสำหรับการวาดแสดงผลอุณหภูมิและความชื้นที่ถูกอ่านจากเซ็นเซอร์ DHT22 และแสดงผลบนหน้าจอ OLED:
1. `void drawTemp() { … }`:
– นี่คือฟังก์ชันที่ใช้ในการวาดแสดงผลอุณหภูมิบนหน้าจอ OLED.
– `int t = dht.readTemperature();`: อ่านค่าอุณหภูมิจากเซ็นเซอร์ DHT22 และเก็บค่าไว้ในตัวแปร `t`.
– `if (isnan(t)) { return; }`: ตรวจสอบว่าค่าอุณหภูมิที่อ่านได้ไม่เป็นตัวเลข (NaN) หากเป็นเช่นนั้นจะไม่ทำอะไรและจบฟังก์ชัน.
– `Temp = String(t) + char(176) + “C”;`: สร้างข้อความสำหรับแสดงผลอุณหภูมิโดยรวมค่าอุณหภูมิและหน่วย (องศาเซลเซียส).
– `u8g2.setFont(u8g2_font_helvR14_tr);`: เลือกตัวอักษรขนาดเล็กสำหรับการแสดงคำว่า “TEMP”.
– `u8g2.setCursor(12, 15);`: กำหนดตำแหน่งเริ่มต้นที่จะแสดงคำว่า “TEMP”.
– `u8g2.print(“TEMP”);`: แสดงคำว่า “TEMP”.
– `u8g2.setFont(u8g2_font_fub30_tf);`: เลือกตัวอักษรขนาดใหญ่สำหรับการแสดงค่าอุณหภูมิ.
– `u8g2.setCursor(36, 58);`: กำหนดตำแหน่งที่จะแสดงค่าอุณหภูมิ.
– `u8g2.print(Temp);`: แสดงค่าอุณหภูมิที่เตรียมไว้.
– `u8g2.drawXBMP(0, 17, TempIcon_width, TempIcon_height, TempIcon_bits);`: แสดงไอคอนของอุณหภูมิที่เตรียมไว้.
2. `void drawHumi() { … }`:
– นี่คือฟังก์ชันที่ใช้ในการวาดแสดงผลความชื้นบนหน้าจอ OLED.
– `int h = dht.readHumidity();`: อ่านค่าความชื้นจากเซ็นเซอร์ DHT22 และเก็บค่าไว้ในตัวแปร `h`.
– `if (isnan(h)) { return; }`: ตรวจสอบว่าค่าความชื้นที่อ่านได้ไม่เป็นตัวเลข (NaN) หากเป็นเช่นนั้นจะไม่ทำอะไรและจบฟังก์ชัน.
– `Humi = String(h) + “%”;`: สร้างข้อความสำหรับแสดงผลความชื้นโดยรวมค่าความชื้นและหน่วยเป็นเปอร์เซ็นต์.
– `u8g2.setFont(u8g2_font_helvR14_tr);`: เลือกตัวอักษรขนาดเล็กสำหรับการแสดงคำว่า “HUMI”.
– `u8g2.setCursor(24, 15);`: กำหนดตำแหน่งเริ่มต้นที่จะแสดงคำว่า “HUMI”.
– `u8g2.print(“HUMI”);`: แสดงคำว่า “HUMI”.
– `u8g2.setFont(u8g2_font_fub30_tf);`: เลือกตัวอักษรขนาดใหญ่สำหรับการแสดงค่าความชื้น.
– `u8g2.setCursor(36, 58);`: กำหนดตำแหน่งที่จะแสดงค่าความชื้น.
– `u8g2.print(Humi);`: แสดงค่าความชื้นที่เตรียมไว้.
– `u8g2.drawXBMP(0, 17, HumiIcon_width, HumiIcon_height, HumiIcon_bits);`: แสดงไอคอนของความชื้นที่เตรียมไว้.
ฟังก์ชันเหล่านี้จะถูกเรียกในลูป `loop()` เมื่อหน่วยความจำเวลาที่ผ่านไปมากกว่าช่วงเวลาที่กำหนดไว้ (`interval`) และจะสลับการแสดงผลระหว่างอุณหภูมิและความชื้นในทุก 3 วินาที.
ฟังก์ชัน -loop
void loop() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis > interval) {
previousMillis = currentMillis;
u8g2.firstPage();
do {
switch (draw_state) {
case 0: drawTemp(); break;
case 1: drawHumi(); break;
}
} while (u8g2.nextPage());
draw_state++;
if (draw_state > 1) {
draw_state = 0;
}
}
}
ในส่วนนี้คือฟังก์ชัน `loop()` ซึ่งทำงานอย่างต่อเนื่องในลูปเพื่อการแสดงผลอุณหภูมิและความชื้นที่อ่านจากเซ็นเซอร์ DHT22 ลงบนหน้าจอ OLED โดยใช้ไลบรารี U8g2:
– `unsigned long currentMillis = millis();`: อ่านค่าเวลาปัจจุบันในมิลลิวินาที.
– `if (currentMillis – previousMillis > interval) { … }`: ตรวจสอบว่าเวลาที่ผ่านไปตั้งแต่ครั้งที่แสดงผลล่าสุดมากกว่าช่วงเวลาที่กำหนดไว้ (`interval`).
– `previousMillis = currentMillis;`: อัปเดตค่าเวลาที่ผ่านไปล่าสุด.
– `u8g2.firstPage();`: เตรียมหน้าจอ OLED สำหรับการแสดงผล.
– `do { … } while (u8g2.nextPage());`: วนลูปเพื่อแสดงผลบนหน้าจอ OLED โดยใช้หน้าจอจนกว่าจะไม่มีหน้าจอสำหรับแสดงต่อ.
– `switch (draw_state) { … }`: ใช้ค่า `draw_state` เพื่อตัดสินใจว่าจะแสดงผลอุณหภูมิหรือความชื้น.
– `case 0: drawTemp(); break;`: ถ้า `draw_state` เป็น 0 จะเรียกใช้ฟังก์ชัน `drawTemp()` เพื่อแสดงผลอุณหภูมิ.
– `case 1: drawHumi(); break;`: ถ้า `draw_state` เป็น 1 จะเรียกใช้ฟังก์ชัน `drawHumi()` เพื่อแสดงผลความชื้น.
– `draw_state++;`: เพิ่มค่า `draw_state` ขึ้นเพื่อสลับการแสดงผลไปยังสถานะถัดไป.
– `if (draw_state > 1) { draw_state = 0; }`: ถ้า `draw_state` เกินค่า 1 จะรีเซ็ตเป็น 0 เพื่อเริ่มการแสดงผลใหม่.
โดยอัตราเร็วในการแสดงผลจะอยู่ที่ 3 วินาทีต่อครั้งและจะสลับการแสดงผลระหว่างอุณหภูมิและความชื้นในทุกครั้งที่แสดงผล.
สรุป
ชุดวัดอุณหภูมิและความชื้นในอากาศด้วย AM2302/DHT22 ที่สร้างขึ้นมาในโปรเจคนี้ สามารถใช้งานได้ตามวัตถุประสงค์ โดยจะสลับการแสดงผลระหว่างอุณหภูมิและความชื้นในทุก 3 วินาที บนหน้าจอ OLED ด้วยตัวอักษรที่ชัดเจนอ่านง่าย นอกจากนี้จุดต่อขยายขาแผงวงจรประมวลผลแบบ Screw Terminal บนบอร์ดทำให้สะดวกมากสำหรับการติดตั้ง IO เพิ่มเติมสำหรับการการพัฒนาระบบต่อไปในอนาคต