บทความ: สร้างระบบบันทึกข้อมูลหลาย Sensor ด้วย ESP32 และ SD Card

เรียนรู้วิธีสร้างระบบบันทึกข้อมูลอุณหภูมิ ความชื้น และความดันบรรยากาศด้วย ESP32 พร้อมบันทึกลง SD Card และส่งข้อมูลไป CynoIoT Platform พร้อมโค้ดตัวอย่างและคำอธิบายภาษาไทย

📅 29 มีนาคม 2026⏱️ 15 นาที🎯 ระดับกลาง
ESP32SD CardData LoggerCynoIoT

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

โปรเจกต์นี้จะสอนวิธีสร้าง ระบบบันทึกข้อมูลหลาย Sensor (Multi-Sensor Data Logger) โดยใช้ ESP32 เพื่ออ่านค่าจาก:

  • DHT22 - วัดอุณหภูมิและความชื้น
  • BMP280 - วัดความดันบรรยากาศและอุณหภูมิ

และบันทึกข้อมูลลง SD Card ในรูปแบบ CSV พร้อมส่งข้อมูลไปยัง CynoIoT Platform ผ่าน WiFi

✨ จุดเด่นของโปรเจกต์นี้:

  • บันทึกข้อมูลได้ต่อเนื่องแม้ไม่มี Internet
  • นำข้อมูลไปวิเคราะห์ด้วย Excel ได้ทันที
  • เชื่อมต่อ CynoIoT เพื่อ monitoring ผ่านเว็บ
  • ใช้งานได้จริงกับสถานการณ์ต่างๆ

สถานการณ์ที่ใช้งานได้:

  • 🏠 ติดตามสภาพอากาศในบ้าน
  • 🏭 ตรวจสอบสภาพแวดล้อมในโกดัง
  • 🌾 ติดตามสภาพอากาศในฟาร์ม
  • 📦 ตรวจสอบอุณหภูมิในคอนเทนเนอร์ขนส่งสินค้า
  • 🔬 บันทึกข้อมูลการทดลองในห้อง lab

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

Hardware Components:

ESP32 Development Board

หรือ NodeMCU ESP32

~฿150-250

DHT22 Sensor Module

อุณหภูมิและความชื้น

~฿60-100

BMP280 Sensor

ความดันบรรยากาศ

~฿80-150

MicroSD Card Module

พร้อม SD Card 4GB+

~฿50-80

Jumper Wires

สายเชื่อมต่อ Male-to-Female

~฿30-50

Breadboard

ขนาด 400 หรือ 830 points

~฿40-80

💡 รวมค่าใช้จ่ายโดยประมาณ: ฿410-710 (ไม่รวม SD Card)

Software & Tools:

  • Arduino IDE - สำหรับเขียนและอัปโหลดโค้ด
  • CynoIoT Account - ฟรี! สมัครที่ cynoiot.com
  • Libraries: DHT, Adafruit BMP280, SD (ติดตั้งผ่าน Library Manager)

🔌 การต่อสาย

ComponentPinESP32 Pin
DHT22 Sensor
VCC-3.3V
Data-GPIO 4
GND-GND
BMP280 Sensor (I2C)
VCC-3.3V
GND-GND
SCL-GPIO 22
SDA-GPIO 21
SD Card Module (SPI)
VCC-5V
GND-GND
CS-GPIO 5
MOSI-GPIO 23
MISO-GPIO 19
SCK-GPIO 18

⚠️ ข้อควรระวัง:

  • SD Card Module ต้องใช้ 5V ไม่ใช่ 3.3V
  • ต่อสาย DHT22 อย่าลืมใส่ Resistor 10kΩ ระหว่าง VCC และ Data
  • ตรวจสอบขา SCL/SDA ของ BMP280 ให้ถูกต้อง

💻 การเขียนโปรแกรม

ติดตั้ง Libraries:

  1. เปิด Arduino IDE
  2. ไปที่ Sketch → Include Library → Manage Libraries
  3. ค้นหาและติดตั้ง:
    • "DHT sensor library" โดย Adafruit
    • "Adafruit BMP280 Library"
    • "Adafruit Unified Sensor"
    • "SD" (มีมากับ Arduino IDE อยู่แล้ว)

โค้ดสมบูรณ์ (Complete Code):

/**
 * ESP32 Multi-Sensor Data Logger
 * บันทึกข้อมูลอุณหภูมิ ความชื้น และความดันลง SD Card
 * และส่งข้อมูลไป CynoIoT Platform
 *
 * Hardware:
 * - ESP32 Board
 * - DHT22 Sensor (GPIO 4)
 * - BMP280 Sensor (I2C: SCL=GPIO 22, SDA=GPIO 21)
 * - SD Card Module (SPI: CS=5, MOSI=23, MISO=19, SCK=18)
 */

#include <DHT.h>
#include <Adafruit_BMP280.h>
#include <SD.h>
#include <WiFi.h>
#include <HTTPClient.h>

// === ตั้งค่า Sensor ===
#define DHTPIN 4           // DHT22 Data pin
#define DHTTYPE DHT22      // DHT 22

DHT dht(DHTPIN, DHTTYPE);
Adafruit_BMP280 bmp;      // I2C

// === ตั้งค่า SD Card ===
#define SD_CS 5            // CS pin สำหรับ SD Card

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

// === ตั้งค่า CynoIoT ===
const char* cynoiot_server = "api.cynoiot.com";
const char* device_id = "YOUR_DEVICE_ID";
const char* api_key = "YOUR_API_KEY";

// === ตั้งค่าการบันทึก ===
#define LOG_INTERVAL 60000  // บันทึกทุกๆ 60 วินาที
unsigned long lastLogTime = 0;

void setup() {
  Serial.begin(115200);
  Serial.println("\n=== ESP32 Multi-Sensor Data Logger ===");

  // เริ่มต้น DHT22
  dht.begin();
  Serial.println("✓ DHT22 started");

  // เริ่มต้น BMP280
  if (!bmp.begin(0x76)) {
    Serial.println("✗ BMP280 not found!");
    while (1);
  }
  Serial.println("✓ BMP280 started");

  // เริ่มต้น SD Card
  if (!SD.begin(SD_CS)) {
    Serial.println("✗ SD Card initialization failed!");
    while (1);
  }
  Serial.println("✓ SD Card initialized");

  // สร้างไฟล์ CSV ถ้ายังไม่มี
  if (!SD.exists("/datalog.csv")) {
    File dataFile = SD.open("/datalog.csv", FILE_WRITE);
    if (dataFile) {
      dataFile.println("Timestamp,Temperature_DHT,Temperature_BMP,Humidity,Pressure");
      dataFile.close();
      Serial.println("✓ Created datalog.csv");
    }
  }

  // เชื่อมต่อ WiFi
  WiFi.begin(ssid, password);
  Serial.print("Connecting to WiFi");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\n✓ WiFi connected");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  Serial.println("\n=== System Ready ===\n");
}

void loop() {
  unsigned long currentTime = millis();

  // บันทึกข้อมูลทุกๆ ที่กำหนด
  if (currentTime - lastLogTime >= LOG_INTERVAL) {
    lastLogTime = currentTime;

    // อ่านค่าจาก DHT22
    float tempDHT = dht.readTemperature();
    float humidity = dht.readHumidity();

    // ตรวจสอบการอ่านค่า DHT22
    if (isnan(tempDHT) || isnan(humidity)) {
      Serial.println("✗ Failed to read from DHT sensor!");
      return;
    }

    // อ่านค่าจาก BMP280
    float tempBMP = bmp.readTemperature();
    float pressure = bmp.readPressure() / 100.0;  // แปลงเป็น hPa

    // สร้าง timestamp
    String timestamp = getTimestamp();

    // แสดงผลบน Serial Monitor
    Serial.println("=== Sensor Readings ===");
    Serial.print("Timestamp: ");
    Serial.println(timestamp);
    Serial.print("Temperature (DHT): ");
    Serial.print(tempDHT);
    Serial.println(" °C");
    Serial.print("Temperature (BMP): ");
    Serial.print(tempBMP);
    Serial.println(" °C");
    Serial.print("Humidity: ");
    Serial.print(humidity);
    Serial.println(" %");
    Serial.print("Pressure: ");
    Serial.print(pressure);
    Serial.println(" hPa");

    // บันทึกลง SD Card
    if (logToSD(timestamp, tempDHT, tempBMP, humidity, pressure)) {
      Serial.println("✓ Data saved to SD Card");
    } else {
      Serial.println("✗ Failed to save to SD Card");
    }

    // ส่งข้อมูลไป CynoIoT
    if (sendToCynoIoT(tempDHT, humidity, pressure)) {
      Serial.println("✓ Data sent to CynoIoT");
    } else {
      Serial.println("✗ Failed to send to CynoIoT");
    }

    Serial.println();
  }
}

// ฟังก์ชันสร้าง timestamp
String getTimestamp() {
  char timestamp[20];
  sprintf(timestamp, "%04d-%02d-%02d %02d:%02d:%02d",
          year(), month(), day(), hour(), minute(), second());
  return String(timestamp);
}

// ฟังก์ชันบันทึกลง SD Card
bool logToSD(String timestamp, float tempDHT, float tempBMP, float humidity, float pressure) {
  File dataFile = SD.open("/datalog.csv", FILE_APPEND);
  if (!dataFile) {
    return false;
  }

  // เขียนข้อมูลในรูปแบบ CSV
  dataFile.print(timestamp);
  dataFile.print(",");
  dataFile.print(tempDHT);
  dataFile.print(",");
  dataFile.print(tempBMP);
  dataFile.print(",");
  dataFile.print(humidity);
  dataFile.print(",");
  dataFile.println(pressure);

  dataFile.close();
  return true;
}

// ฟังก์ชันส่งข้อมูลไป CynoIoT
bool sendToCynoIoT(float temperature, float humidity, float pressure) {
  if (WiFi.status() != WL_CONNECTED) {
    return false;
  }

  HTTPClient http;
  http.begin(cynoiot_server);
  http.addHeader("Content-Type", "application/json");
  http.addHeader("X-API-Key", api_key);

  // สร้าง JSON payload
  String payload = "{\"device_id\":\"" + String(device_id) + "\",";
  payload += "\"data\":{";
  payload += "\"temperature\":" + String(temperature) + ",";
  payload += "\"humidity\":" + String(humidity) + ",";
  payload += "\"pressure\":" + String(pressure);
  payload += "}}";

  int httpResponseCode = http.POST(payload);
  http.end();

  return (httpResponseCode == 200);
}

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

  • Libraries - ใช้ DHT, BMP280, SD สำหรับ sensor และ SD Card
  • PIN Definitions - กำหนดขาที่ใช้งานที่ต้นไฟล์
  • setup() - เริ่มต้น sensor, SD Card, WiFi และสร้างไฟล์ CSV
  • loop() - อ่านค่า sensor ทุกๆ 60 วินาที
  • logToSD() - บันทึกข้อมูลลง SD Card ในรูปแบบ CSV
  • sendToCynoIoT() - ส่งข้อมูลไป CynoIoT Platform

💡 เคล็ดลับ:

  • เปลี่ยน LOG_INTERVAL เพื่อปรับความถี่ในการบันทึก
  • ไฟล์ datalog.csv สามารถเปิดด้วย Excel ได้ทันที
  • ใช้ Serial Plotter (Tools → Serial Plotter) เพื่อดูกราฟแบบ real-time

🧪 การทดสอบ

ขั้นตอนการทดสอบ:

  1. อัปโหลดโค้ดไปยัง ESP32
  2. เปิด Serial Monitor (115200 baud)
  3. ดูข้อความ "=== System Ready ===" แสดงว่าโปรแกรมทำงานได้
  4. นำ SD Card มาเสียบในคอมพิวเตอร์
  5. เปิดไฟล์ datalog.csv ด้วย Excel
  6. ตรวจสอบว่ามีข้อมูลบันทึกถูกต้อง

ตัวอย่างข้อมูลใน CSV:

Timestamp,Temperature_DHT,Temperature_BMP,Humidity,Pressure
2026-03-29 18:12:00,28.50,28.30,65.20,1013.25
2026-03-29 18:13:00,28.60,28.40,65.10,1013.20
2026-03-29 18:14:00,28.70,28.50,65.00,1013.18

การตรวจสอบข้อมูลใน CynoIoT:

  • ล็อกอินเข้าสู่ cynoiot.com
  • ไปที่หน้า Devices
  • คลิกที่ device ของคุณ
  • ดูกราฟข้อมูล sensor แบบ real-time

🔧 การแก้ปัญหา

ปัญหา: SD Card initialization failed

อาการ: แสดง "✗ SD Card initialization failed!"

สาเหตุ: SD Card ไม่ได้ฟอร์แมต หรือต่อสายไม่ถูกต้อง

วิธีแก้: ฟอร์แมต SD Card เป็น FAT32 และตรวจสอบการต่อสาย SPI

ปัญหา: BMP280 not found

อาการ: แสดง "✗ BMP280 not found!"

สาเหตุ: ต่อสาย I2C ผิด หรือใช้ address ไม่ถูกต้อง

วิธีแก้: ตรวจสอบว่า BMP280 ใช้ address 0x76 หรือ 0x77 และแก้ในโค้ด

ปัญหา: Failed to read from DHT sensor

อาการ: แสดง "✗ Failed to read from DHT sensor!"

สาเหตุ: ไม่ได้ต่อ Resistor หรือต่อสายผิดขา

วิธีแก้: ใส่ Resistor 10kΩ ระหว่าง VCC และ Data pin

ปัญหา: WiFi connection failed

อาการ: เชื่อมต่อ WiFi ไม่ได้

สาเหตุ: ชื่อ WiFi หรือรหัสผ่านผิด

วิธีแก้: ตรวจสอบ ssid และ password ในโค้ด

ปัญหา: ข้อมูลใน CSV ไม่ถูกต้อง

อาการ: ข้อมูลกระจายตัวไม่เป็นคอลัมน์

สาเหตุ: Excel ไม่รู้จักการแยก comma

วิธีแก้: ใช้ Data → Text to Columns และเลือก Delimited → Comma

📝 สรุป

ในบทความนี้คุณได้เรียนรู้:

  • ✅ วิธีต่อ DHT22, BMP280 และ SD Card กับ ESP32
  • ✅ การอ่านค่าจากหลาย sensor พร้อมกัน
  • ✅ การบันทึกข้อมูลลง SD Card ในรูปแบบ CSV
  • ✅ การส่งข้อมูลไป CynoIoT Platform ผ่าน WiFi
  • ✅ การแก้ปัญหาที่พบบ่อย

🎯 สิ่งที่คุณสามารถทำต่อได้:

  • เพิ่ม sensor อื่นๆ เช่น วัดแสง (BH1750) หรือวัดฝุ่น (PMS5003)
  • ต่อหน้าจอ OLED เพื่อแสดงผลแบบ real-time
  • ใช้ Deep Sleep Mode เพื่อประหยัดแบตเตอรี่
  • สร้าง Web Server บน ESP32 เพื่อดูข้อมูลผ่าน browser
  • ต่อ IoT Relay เพื่อควบคุมอุปกรณ์ไฟฟ้าอัตโนมัติ

บทความที่เกี่ยวข้อง:

© 2026 CynoIoT. All rights reserved.