สร้างชุดวัดอุณหภูมิและความชื้นในอากาศด้วย AM2302/DHT22

สร้างชุดวัดอุณหภูมิและความชื้นในอากาศด้วย AM2302/DHT22

เริ่มต้นเนื้อหา

สร้างชุดวัดอุณหภูมิและความชื้นในอากาศด้วย AM2302/DHT22

โปรเจคต่อไปนี้เป็นการสร้างชุดวัดอุณหภูมิและความชื้นในอากาศด้วยเซนเซอร์ AM2302/DHT22 โดยแสดงผลการวัดบนจอ OLED ขนาด 0.96″ ประมวลผลด้วย Esp32 เพื่อใช้วัดอุณหภูมิและความชื้นในสำนักงงานหรือบ้านพักอาศัย โดยเลือกประกอบชิ้นส่วนลงบอร์ด DIN Rail Esp32 NodeMCU Screw Terminal เนื่องจากมองเห็นว่าการที่มีแผงวงจรขยายขาบอร์ดประมวลผล ESP32 NodeMCU ด้วย Screw Terminal จะทำให้สะดวกในการติดตั้ง Input และ Output เพิ่มเติมได้ในอนาคตหากมีการพัฒนาต่อยอดระบบ

คุณสมบัติของเครื่อง

  1. แสดงผลค่าอุณหภูมิ
  2. แสดงผลค่าความชื้น
  3. สามารถติดตั้งเซนเซอร์เพิ่มเติมได้ในอนาคต

อุปกรณ์

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;
    }
  }
}

ประกอบอุปกรณ์ลงบอร์ด

ประกอบอุปกรณ์ทั้งหมดลงบอร์ดดังรูปด้านบน ดังนี้

  1. ต่อสายประกอบเซนเซอร์ AM2302 เข้า Screw terminal ช่อง 3V3, GND, D2
  2. เสียบ Esp32 ลง Pin Header บนบอร์ด
  3. บัดกรี 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 เพิ่มเติมสำหรับการการพัฒนาระบบต่อไปในอนาคต

adminสร้างชุดวัดอุณหภูมิและความชื้นในอากาศด้วย AM2302/DHT22