เนื้อหาในบทความ
ทำไมต้องสร้าง Energy Monitor?
การติดตามการใช้พลังงานไฟฟ้าในบ้านหรือที่ทำงานเป็นสิ่งสำคัญมากในยุคที่ค่าไฟฟ้าแพงขึ้น การรู้ว่าอุปกรณ์ไหนใช้ไฟเยอะ เมื่อไหร่ที่ไฟฟ้าสูงสุด จะช่วยให้คุณ:
- ประหยัดค่าไฟฟ้า: รู้ว่าอุปกรณ์ไหนกินไฟเยอะ เพื่อปรับเปลี่ยนพฤติกรรม
- ตรวจจับอุปกรณ์เสีย: ถ้าไฟฟ้าสูงผิดปกติ อาจเป็นสัญญาณเตือนว่ามีอุปกรณ์ทำงานผิดปกติ
- วางแผนการใช้ไฟ: ดูรูปแบบการใช้ไฟตลอดทั้งวัน/สัปดาห์
- ตรวจสอบหนี้ไฟ: ตรวจสอบว่าค่าไฟที่การไฟฟ้าเรียกเก็บถูกต้องหรือไม่
💡 ความจริง: บ้านทั่วไปใช้ไฟฟ้า 300-500 kWh ต่อเดือน หากคุณลดการใช้ไฟได้ 10% อาจประหยัดได้ถึง 300-500 บาทต่อเดือน!
อุปกรณ์ที่ต้องใช้
Hardware
- ✓ ESP32 Dev Board - ~฿150
- ✓ SCT-013-000 Current Transformer (100A) - ~฿200
- ✓ Burden Resistor 33Ω 2W (ถ้า SCT-013 ไม่มี内置) - ~฿10
- ✓ Breadboard & Jumper Wires - ~฿50
- ✓ (ถ้าวัดแรงดัน) AC-AC Adapter 9V - ~฿100
Software/Tools
- ✓ Arduino IDE หรือ PlatformIO
- ✓ Library: EmonLib (Energy Monitor)
- ✓ Library: PubSubClient (สำหรับ MQTT)
- ✓ CynoIoT Account (ฟรี)
- ✓ Multimeter (สำหรับสอเทียบ)
🛡️ คำเตือนความปลอดภัย!
⚠️ อันตราย: SCT-013 เป็น Non-invasive sensor คือไม่ต้องต่อกับไฟ 220V โดยตรง แต่ถ้าคุณจะติดตั้งกับกระแสไฟจริง ต้อง:
- ปิดเบรกเกอร์ก่อนติดตั้งเสมอ
- ใช้เคสกันน้ำ/กันไฟฟ้า
- ตรวจสอบสายไฟให้แน่ใจว่าไม่มีรอยขูดขีด
- ถ้าไม่มั่นใจ ให้ช่างไฟมืออาชีพติดตั้ง
หลักการทำงานของ SCT-013 Current Transformer
SCT-013 เป็น Current Transformer (CT) ที่ใช้หลักการ Induction ในการวัดกระแสไฟฟ้า โดยไม่ต้องตัดสายไฟ หรือต่อเข้ากับวงจรโดยตรง (Non-invasive)
🔬 หลักการทำงาน:
- คลิปเซ็นเซอร์: คลิป SCT-013 ไปที่สายไฟ 1 เส้น (เฉพาะ Live หรือ Neutral เท่านั้น)
- สนามแม่เหล็ก: กระแสไฟฟ้าที่ไหลในสายสร้างสนามแม่เหล็กรอบๆ
- เหนี่ยวนำ: สนามแม่เหล็กนี้เหนี่ยวนำกระแสในขดลวดคอยล์ของ SCT-013
- สัดส่วน: กระแสที่วัดได้ = กระแสจริง ÷ 1000 (สำหรับ SCT-013-000)
SCT-013-000 (ไม่มี Burden Resistor)
สำหรับโปรเจกต์ที่ต้องการความแม่นยำสูง
• 100A:50mA (2000 turns)
• ต้องต่อ Burden Resistor เอง
• ยืดหยุ่นในการออกแบบ
SCT-013-030 (มี Burden Resistor ในตัว)
สำหรับมือใหม่ ใช้ง่าย
• 30A:1V (มี burden resistor built-in)
• Output เป็น Voltage 1V @ 30A
• ไม่ต้องต่อ Burden Resistor
⚠️ ข้อควรระวัง: SCT-013 ต้องคลิปเฉพาะสาย 1 เส้นเท่านั้น! ถ้าคลิปสาย 2 เส้นพร้อมกัน (Live + Neutral) สนามแม่เหล็กจะตัดกันและวัดค่าได้ = 0
การต่อวงจร (Wiring)
📌 การต่อสายสำหรับ SCT-013-000 (ใช้ Burden Resistor)
SCT-013 → ESP32:
- • SCT-013 Pin 1 → ESP32 GPIO 34 (VP)
- • SCT-013 Pin 2 → ESP32 GND
- • Burden Resistor 33Ω 2W ต่อข้าม Pin 1-2
หมายเหตุ:
- • GPIO 34 เป็น Input Only
- • รองรับ ADC 12-bit (0-4095)
- • ไม่มี Voltage Divider
📌 การต่อสายสำหรับ SCT-013-030 (มี Burden ในตัว)
SCT-013 → ESP32:
- • SCT-013 Red Wire → ESP32 GPIO 34 (VP)
- • SCT-013 Black Wire → ESP32 GND
- • White Wire (ถ้ามี) → ไม่ต้องต่อ
หมายเหตุ:
- • Output เป็น AC Voltage
- • ต้องใช้ Voltage Divider
- • หรือใช้ Capacitive Coupling
✅ ข้อแนะนำ: ใช้ SCT-013-000 เพราะยืดหยุ่นกว่า สามารถปรับ Burden Resistor เพื่อให้ได้ Range ที่ต้องการ
โค้ดตัวอย่าง - วัดกระแสไฟฟ้า
โค้ดนี้ใช้ Library EmonLib ซึ่งเป็น Library ยอดนิยมสำหรับ Energy Monitoring จาก OpenEnergyMonitor project
/*
* ESP32 Energy Monitor ด้วย SCT-013 Current Transformer
*
* อุปกรณ์:
* - ESP32 Dev Board
* - SCT-013-000 Current Transformer (100A)
* - Burden Resistor 33Ω 2W
*
* การต่อสาย:
* - SCT-013 Pin 1 → ESP32 GPIO 34 (VP)
* - SCT-013 Pin 2 → ESP32 GND
* - Burden Resistor ต่อข้าม SCT-013 Pin 1-2
*
* Library ที่ต้องติดตั้ง:
* - EmonLib: https://github.com/openenergymonitor/EmonLib
*/
#include "EmonLib.h" // Library สำหรับ Energy Monitoring
// ตั้งค่าขา GPIO สำหรับ Current Sensor
const int CURRENT_SENSOR_PIN = 34; // GPIO 34 (VP) - Input Only
// ตั้งค่าพารามิเตอร์ Energy Monitor
const int CALIBRATION = 111.1; // ค่าสอเทียบเริ่มต้น (ปรับได้)
const int NUMBER_OF_SAMPLES = 1480; // จำนวน Samples สำหรับวัด (ควรเป็นเลขคู่)
// สร้างออบเจกต์ Energy Monitor
EnergyMonitor emon1;
// ตัวแปรสำหรับเก็บค่า
double Irms = 0; // กระแสไฟฟ้า (Ampere)
double apparentPower = 0; // กำลังไฟฟ้า (Watt)
unsigned long lastMillis = 0; // สำหรับคำนวณเวลา
void setup() {
// เริ่มต้น Serial Monitor สำหรับ Debug
Serial.begin(115200);
Serial.println("\n\n=== ESP32 Energy Monitor ===");
Serial.println("เริ่มต้นระบบวัดพลังงานไฟฟ้า...\n");
// ตั้งค่า Current Sensor
// รูปแบบ: currentSensor(pin, calibration)
// calibration = ค่าที่ใช้แปลง ADC เป็น Ampere
emon1.current(CURRENT_SENSOR_PIN, CALIBRATION);
// แสดงข้อมูลการตั้งค่า
Serial.printf("Current Sensor Pin: GPIO %d\n", CURRENT_SENSOR_PIN);
Serial.printf("Calibration Value: %.1f\n", CALIBRATION);
Serial.printf("Number of Samples: %d\n", NUMBER_OF_SAMPLES);
Serial.println("\nเริ่มวัดกระแสไฟฟ้า...\n");
Serial.println("----------------------------------------");
}
void loop() {
// อ่านค่ากระแสไฟฟ้า (RMS)
// calcIrms(number_of_samples) - คำนวณ RMS Current
Irms = emon1.calcIrms(NUMBER_OF_SAMPLES);
// คำนวณกำลังไฟฟ้า (Apparent Power)
// Power = Current × Voltage (สมมติ 220V)
apparentPower = Irms * 220.0;
// แสดงผลทุก 2 วินาที
if (millis() - lastMillis > 2000) {
lastMillis = millis();
// แสดงผลใน Serial Monitor
Serial.println("📊 สถิติการใช้พลังงาน:");
Serial.printf(" กระแสไฟฟ้า: %.2f A\n", Irms);
Serial.printf(" กำลังไฟฟ้า: %.2f W\n", apparentPower);
Serial.printf(" ค่าไฟฟ้า/ชม: %.2f บาท (สมมติ 4.42 บาท/หน่วย)\n", (apparentPower / 1000.0) * 4.42);
Serial.println("----------------------------------------");
// แจ้งเตือนถ้ากระแสสูงเกินไป
if (Irms > 50.0) {
Serial.println("⚠️ แจ้งเตือน: กระแสไฟฟ้าสูง! (กว่า 50A)");
}
}
// รอ 100ms ก่อนวัดใหม่
delay(100);
}📝 คำอธิบายโค้ด:
- •
CALIBRATION = 111.1คือค่าเริ่มต้น ต้องสอเทียบให้แม่นยำ - •
calcIrms(1480)วัดค่า RMS จาก 1480 samples (เลขคู่เพื่อให้ตัดหน่วย) - •
Irms × 220คำนวณกำลังไฟฟ้า สมมติแรงดัน 220V - •
delay(100)วัดใหม่ทุก 100ms เพื่อได้ค่าเฉลี่ยที่ดี
การสอเทียบค่า (Calibration)
ค่า CALIBRATION เริ่มต้น (111.1) อาจไม่แม่นยำ เพราะขึ้นกับ:
- ความแม่นยำของ Burden Resistor
- ค่า Voltage Reference ของ ESP32 (มักไม่เท่ากับ 3.3V พอดี)
- ความแม่นยำของ SCT-013
🔧 วิธีสอเทียบ:
- เตรียมอุปกรณ์อ้างอิง: ใช้ Multimeter หรือ Clamp Meter ที่แม่นยำ
- วัดค่าจริง: เปิดเครื่องใช้ไฟฟ้าที่รู้กระแส (เช่น หลอดไฟ 100W ≈ 0.45A)
- อ่านค่าจาก ESP32: ดูค่าที่ Serial Monitor แสดง
- คำนวณ CALIBRATION ใหม่: ใช้สูตร:
NEW_CAL = CURRENT_CAL × (ACTUAL_CURRENT / MEASURED_CURRENT) - อัปเดตโค้ด: เปลี่ยนค่า CALIBRATION และอัปโหลดใหม่
💡 เคล็ดลับ: สอเทียบด้วยกระแสที่รู้ค่าแน่นอน เช่น หลอดไฟ LED 10W (≈0.045A), พัดลมไฟ (≈0.3A), หรือเตาอบไมโครเวฟ (≈5A) เพื่อให้ได้ค่าที่แม่นยำ
ส่งข้อมูลไปยัง CynoIoT ด้วย MQTT
ต่อไปเราจะส่งข้อมูลกระแสไฟฟ้าไปยัง CynoIoT Platform เพื่อเก็บข้อมูลและแสดงใน Dashboard
/*
* ESP32 Energy Monitor + MQTT
* ส่งข้อมูลกระแสไฟฟ้าไปยัง CynoIoT Platform
*/
#include "EmonLib.h"
#include <WiFi.h>
#include <PubSubClient.h>
// WiFi Credentials
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";
// MQTT Settings (CynoIoT)
const char* mqtt_server = "mqtt.cynoiot.com";
const int mqtt_port = 1883;
const char* mqtt_user = "YOUR_CYNOIOT_USERNAME";
const char* mqtt_password = "YOUR_CYNOIOT_API_KEY";
// Topics
const char* current_topic = "cynoiot/your-device-id/current";
const char* power_topic = "cynoiot/your-device-id/power";
// Sensor & WiFi Objects
EnergyMonitor emon1;
WiFiClient espClient;
PubSubClient client(espClient);
// ตัวแปร
double Irms = 0;
double apparentPower = 0;
unsigned long lastMQTT = 0;
void setup() {
Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_server, mqtt_port);
// ตั้งค่า Current Sensor
emon1.current(34, 111.1); // GPIO 34, Calibration 111.1
}
void setup_wifi() {
delay(10);
Serial.println("Connecting to WiFi...");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
}
void reconnect() {
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
if (client.connect("ESP32_Energy_Monitor", mqtt_user, mqtt_password)) {
Serial.println("connected");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" retrying in 5 seconds");
delay(5000);
}
}
}
void loop() {
// ตรวจสอบการเชื่อมต่อ MQTT
if (!client.connected()) {
reconnect();
}
client.loop();
// วัดกระแสไฟฟ้า
Irms = emon1.calcIrms(1480);
apparentPower = Irms * 220.0;
// ส่งข้อมูลทุก 5 วินาที
if (millis() - lastMQTT > 5000) {
lastMQTT = millis();
// แปลงเป็น String
char currentStr[10];
char powerStr[10];
dtostrf(Irms, 2, 2, currentStr);
dtostrf(apparentPower, 2, 2, powerStr);
// ส่งข้อมูล MQTT
client.publish(current_topic, currentStr);
client.publish(power_topic, powerStr);
Serial.printf("MQTT: Current=%.2fA, Power=%.2fW\n", Irms, apparentPower);
}
delay(100);
}✅ ข้อดีของ MQTT:
- • Real-time: ส่งข้อมูลทันทีที่วัดได้
- • Lightweight: ใช้ Bandwidth น้อย
- • Scalable: เพิ่ม Sensor ได้ไม่จำกัด
- • CynoIoT Integration: เชื่อมต่อกับ Dashboard ได้ทันที
เทคนิคขั้นสูง
1. วัดทั้งกระแสและแรงดัน (Real Power)
โค้ดด้านบนวัดเฉพาะ Apparent Power (V × I) แต่ถ้าอยากได้ Real Power (W) ต้องวัดทั้งกระแสและแรงดันพร้อมกัน
วิธี: ใช้ AC-AC Adapter 9V + Voltage Divider วัดแรงดัน เพื่อคำนวณ Power Factor
2. Deep Sleep สำหรับ Battery Powered
ถ้าอยากใช้แบตเตอรี่ ให้ ESP32 เข้า Deep Sleep ระหว่างการวัด
ข้อแลกเปลี่ยน: อัปเดตช้าลง (เช่น ทุก 5 นาที) แต่แบตอยู่ได้เดือน
3. หลายช่องสัญญาณ (3-Phase)
สำหรับโรงงานหรือบ้านที่ใช้ 3-Phase ใช้ SCT-013 3 ตัว + ESP32 ที่มี ADC หลายช่อง
คำแนะนำ: ใช้ ESP32-S3 ที่มี ADC 2 ช่อง หรือใช้ External ADC (เช่น ADS1115)
4. แจ้งเตือน Telegram
ส่งแจ้งเตือนเมื่อกระแสสูงเกินกำหนด หรือตรวจจับ Load ผิดปกติ
ดูเพิ่ม: บทความ ESP32 Telegram Tutorial
สรุป
ในบทความนี้คุณได้เรียนรู้:
- ✓หลักการทำงานของ SCT-013 Current Transformer
- ✓การต่อวงจรวัดกระแสไฟฟ้าด้วย ESP32
- ✓โค้ดตัวอย่างสำหรับวัดกระแสและกำลังไฟฟ้า
- ✓การสอเทียบค่าให้แม่นยำ
- ✓การส่งข้อมูลไปยัง CynoIoT ด้วย MQTT
🚀 ถัดไป:
- • วัดทั้งกระแสและแรงดันเพื่อคำนวณ Real Power
- • สร้าง Dashboard ด้วย CynoIoT
- • แจ้งเตือนเมื่อใช้ไฟเกินโควต้า
- • วิเคราะห์รูปแบบการใช้ไฟฟ้า