บทความ: สร้างเครื่องวัดคุณภาพอากาศด้วย ESP32 ตรวจจับ PM2.5 และ CO2

เรียนรู้วิธีสร้างระบบตรวจวัดคุณภาพอากาศ IoT ด้วย ESP32 วัดฝุ่น PM2.5, PM10 และก๊าซ CO2 แบบ Real-time เชื่อมต่อกับ CynoIoT Platform เพื่อติดตามค่า AQI ได้ตลอด 24 ชั่วโมง

📅 7 มีนาคม 2026⏱️ 20 นาที🎯 ระดับ: กลาง - ขั้นสูง
PM2.5
ฝุ่นละออง
CO2
ก๊าซคาร์บอน
AQI
ดัชนีคุณภาพอากาศ
IoT
เชื่อมต่อออนไลน์

ภาพรวมโปรเจกต์

คุณภาพอากาศภายในอาคาร (Indoor Air Quality - IAQ) ส่งผลต่อสุขภาพของเรามากกว่าที่คิด ฝุ่นละออง PM2.5 และก๊าซ CO2 ที่สูงเกินไปสามารถก่อให้เกิดอาการปวดหัว ระคายเคืองตา และทำให้เหนื่อยง่าย ในบทความนี้เราจะมาสร้างเครื่องวัดคุณภาพอากาศ IoT ที่สามารถติดตามค่า AQI ได้ตลอด 24 ชั่วโมง

สิ่งที่คุณจะได้เรียนรู้

  • การเชื่อมต่อ PMS5003 PM2.5 sensor กับ ESP32
  • การอ่านค่า CO2, Temperature และ Humidity จาก SCD30/SCD4x
  • การคำนวณค่า AQI (Air Quality Index) จากค่า PM2.5
  • การส่งข้อมูล Sensor ไปยัง CynoIoT Platform
  • เทคนิคการประหยัดพลังงานด้วย Deep Sleep Mode
  • การแก้ปัญหา Sensor ที่พบบ่อย

💡 ทำไมต้องวัด PM2.5 และ CO2?

PM2.5 คือฝุ่นละอองขนาดเล็กกว่า 2.5 ไมครอนที่สามารถเข้าไปในระบบทางเดินหายใจและกระแสเลือดได้ ส่วน CO2 ที่สูงกว่า 1,000 ppm จะทำให้เกิดอาการง่วงซึมและสมาธิสั้น การติดตามทั้งสองค่าช่วยให้เราจัดการระบบระบายอากาศได้อย่างเหมาะสม

อุปกรณ์ที่ต้องใช้

ESP32 DevKit

จำเป็น

ไมโครคอนโทรลเลอร์ WiFi + Bluetooth หลักของโปรเจกต์

ราคาโดยประมาณ: ~150 บาท

PMS5003 / SDS011

จำเป็น

Sensor วัดฝุ่น PM2.5 และ PM10 เลือกใช้อย่างใดอย่างหนึ่ง

ราคาโดยประมาณ: 250-500 บาท

SCD30 / SCD4x

จำเป็น

Sensor วัด CO2, Temperature และ Humidity จาก Sensirion

ราคาโดยประมาณ: 400-600 บาท

OLED Display 0.96"

เลือกได้

จอแสดงผลค่า AQI แบบ Real-time (เลือกได้)

ราคาโดยประมาณ: ~80 บาท

Buzzer / LED

เลือกได้

ตัวแจ้งเตือนเมื่อค่า AQI สูงเกินกำหนด (เลือกได้)

ราคาโดยประมาณ: ~20 บาท

Power Bank / Battery

เลือกได้

แหล่งจ่ายไฟสำหรับใช้งานแบบ Portable (เลือกได้)

ราคาโดยประมาณ: ~200 บาท

💰 งบประมาณรวม

หากใช้ Sensor PMS5003 + SCD30 คุณจะใช้งบประมาณ 850-1,000 บาท (ราคาอาจแตกต่างตามร้านค้า) หรือเลือกใช้ SDS011 + SCD4x เพื่อประหยัดงบได้มากขึ้น

วิธีต่อสาย (Wiring Diagram)

การเชื่อมต่อ PMS5003 (PM2.5 Sensor)

PMS5003 ESP32
VCC (5V)VIN
GNDGND
TXGPIO16 (RX2)
RXGPIO17 (TX2)

การเชื่อมต่อ SCD30/SCD4x (CO2 Sensor)

SCD30/SCD4x ESP32
VCC3.3V
GNDGND
SDA
SCLGPIO22 (SCL)

⚠️ คำเตือนสำคัญ

  • • PMS5003 ใช้ไฟเลี้ยง 5V ต้องต่อ VIN ของ ESP32 ไม่ใช่ 3.3V
  • • SCD30/SCD4x ใช้ไฟเลี้ยง 3.3V - 5V แนะนำให้ต่อ 3.3V เพื่อความปลอดภัย
  • • ต้องใช้ Logic Level Converter หากต่อกับ sensor ที่ใช้ 5V

ติดตั้ง Library ที่จำเป็น

วิธีติดตั้ง Library ผ่าน Arduino IDE

  1. เปิด Arduino IDE และไปที่ Sketch → Include Library → Manage Libraries
  2. ค้นหา library ต่อไปนี้และกด Install:

Adafruit SCD30

Adafruit

1.x.x

Adafruit SCD4x

Adafruit

1.x.x

PMS Library

Markus Schätzl

1.x.x

HTTPClient

Built-in

Included

Wire

Built-in

Included

โค้ดโปรแกรม ESP32 Air Quality Monitor

โค้ดหลัก (Main Code)

โค้ดนี้อ่านค่า PM2.5, PM10 และ CO2 จาก sensor และคำนวณค่า AQI พร้อมส่งข้อมูลไปยัง CynoIoT Platform ทุก 30 วินาที

#include <Wire.h>
#include <Adafruit_SCD30.h>
#include <Adafruit_SCD4x.h>
#include "PMS.h"
#include <WiFi.h>
#include <HTTPClient.h>

// ตั้งค่า WiFi
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";

// ตั้งค่า CynoIoT
const char* deviceToken = "YOUR_DEVICE_TOKEN";
const char* cynoiotUrl = "https://api.cynoiot.com/v1/devices/data";

// Sensor objects
Adafruit_SCD30 scd30;
Adafruit_SCD4x scd4x;
PMS pms(Serial2);
PMS::DATA pmsData;

// Timing variables
unsigned long lastSendTime = 0;
const long sendInterval = 30000; // ส่งทุก 30 วินาที

void setup() {
  Serial.begin(115200);
  
  // เชื่อมต่อ WiFi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\nWiFi connected");
  
  // เริ่มต้น SCD30/SCD4x sensor
  if (!scd30.begin() && !scd4x.begin()) {
    Serial.println("Failed to find SCD30/SCD4x chip");
    while (1) { delay(10); }
  }
  
  // เริ่มต้น PMS5003 sensor
  Serial2.begin(9600, SERIAL_8N1, 16, 17); // RX2=GPIO16, TX2=GPIO17
  
  Serial.println("Air Quality Monitor initialized");
}

void loop() {
  // อ่านค่า PM2.5 และ PM10
  if (pms.read(pmsData)) {
    float pm25 = pmsData.PM_AE_UG_2_5;
    float pm10 = pmsData.PM_AE_UG_10_0;
    
    // อ่านค่า CO2, Temperature, Humidity
    float co2 = 0, temp = 0, hum = 0;
    
    if (scd30.dataReady()) {
      scd30.read();
      co2 = scd30.CO2;
      temp = scd30.temperature;
      hum = scd30.relative_humidity;
    } else if (scd4x.readMeasurement()) {
      co2 = scd4x.CO2;
      temp = scd4x.temperature;
      hum = scd4x.relativeHumidity;
    }
    
    // คำนวณ AQI จาก PM2.5
    int aqi = calculateAQI(pm25);
    
    // แสดงผลใน Serial Monitor
    Serial.printf("PM2.5: %.1f µg/m³, PM10: %.1f µg/m³\n", pm25, pm10);
    Serial.printf("CO2: %.0f ppm, Temp: %.1f°C, Hum: %.0f%%\n", co2, temp, hum);
    Serial.printf("AQI: %d\n", aqi);
    
    // ส่งข้อมูลไป CynoIoT ทุก 30 วินาที
    if (millis() - lastSendTime >= sendInterval) {
      sendToCynoIoT(pm25, pm10, co2, aqi, temp, hum);
      lastSendTime = millis();
    }
  }
  
  delay(1000);
}

// คำนวณ AQI จากค่า PM2.5
int calculateAQI(float pm25) {
  if (pm25 <= 12.0) return map(pm25, 0, 12, 0, 50);
  else if (pm25 <= 35.4) return map(pm25, 12.1, 35.4, 51, 100);
  else if (pm25 <= 55.4) return map(pm25, 35.5, 55.4, 101, 150);
  else if (pm25 <= 150.4) return map(pm25, 55.5, 150.4, 151, 200);
  else if (pm25 <= 250.4) return map(pm25, 150.5, 250.4, 201, 300);
  else return map(pm25, 250.5, 500.4, 301, 500);
}

// ส่งข้อมูลไปยัง CynoIoT Platform
void sendToCynoIoT(float pm25, float pm10, float co2, int aqi, float temp, float hum) {
  if (WiFi.status() == WL_CONNECTED) {
    HTTPClient http;
    http.begin(cynoiotUrl);
    http.addHeader("Content-Type", "application/json");
    http.addHeader("Authorization", deviceToken);
    
    // สร้าง JSON payload
    String payload = "{";
    payload += "\"pm25\":" + String(pm25) + ",";
    payload += "\"pm10\":" + String(pm10) + ",";
    payload += "\"co2\":" + String(co2) + ",";
    payload += "\"aqi\":" + String(aqi) + ",";
    payload += "\"temperature\":" + String(temp) + ",";
    payload += "\"humidity\":" + String(hum);
    payload += "}";
    
    int httpResponseCode = http.POST(payload);
    
    if (httpResponseCode > 0) {
      Serial.println("Data sent to CynoIoT successfully");
    } else {
      Serial.println("Error sending data to CynoIoT");
    }
    
    http.end();
  }
}

📝 คำอธิบายโค้ดสำคัญ

  • Serial.begin(115200): เปิด Serial Monitor สำหรับ Debug
  • pms.begin(): เริ่มต้นการทำงานของ PMS5003 sensor
  • scd.begin(): เริ่มต้นการทำงานของ SCD30/SCD4x sensor
  • calculateAQI(): ฟังก์ชันคำนวณค่า Air Quality Index จากค่า PM2.5
  • sendToCynoIoT(): ส่งข้อมูลไปยัง CynoIoT Platform

เชื่อมต่อกับ CynoIoT Platform

ขั้นตอนการเชื่อมต่อ

  1. สร้าง Device ใหม่

    ไปที่ CynoIoT Dashboard → Devices → Add New Device → เลือก "ESP32 Air Quality Monitor"

  2. รับ Device Token

    คัดลอก Device Token มาใส่ในบรรทัด const char* deviceToken = "YOUR_DEVICE_TOKEN";

  3. ตั้งค่า Sensor Fields

    สร้าง fields ตามนี้:

    • • pm25 (Number)
    • • pm10 (Number)
    • • co2 (Number)
    • • aqi (Number)
    • • temperature (Number)
    • • humidity (Number)
  4. อัปโหลดและทดสอบ

    อัปโหลดโค้ดไปยัง ESP32 และดูผลใน CynoIoT Dashboard

🎯 เคล็ดลับ: ใช้ MQTT เพื่อ Real-time Updates

หากต้องการรับข้อมูลแบบ Real-time คุณสามารถใช้ MQTT Protocol แทน HTTP โดยเพิ่ม PubSubClient library และเชื่อมต่อกับ CynoIoT MQTT Broker ดูรายละเอียดเพิ่มเติมได้ที่ ESP32 MQTT Tutorial

การแก้ปัญหาที่พบบ่อย

สรุปและขั้นตอนถัดไป

สิ่งที่เราได้เรียนรู้

  • วิธีการเชื่อมต่อ PMS5003 และ SCD30/SCD4x sensors กับ ESP32
  • การอ่านค่า PM2.5, PM10, CO2, Temperature และ Humidity
  • การคำนวณค่า AQI จากค่า PM2.5
  • การส่งข้อมูลไปยัง CynoIoT Platform

แนวคิดการพัฒนาต่อ

  • เพิ่มจอ LCD/OLED เพื่อแสดงค่า AQI แบบ Real-time
  • เพิ่ม Buzzer แจ้งเตือนเมื่อ AQI สูงเกินกำหนด
  • ใช้ Deep Sleep Mode เพื่อยืดอายุการใช้งานแบตเตอรี่
  • สร้าง Dashboard ด้วย CynoIoT เพื่อติดตามข้อมูลย้อนหลัง

© 2026 CynoIoT. All rights reserved.