Latest Post

หน้าแรก

This is home content

ESP32 + PZEM-004T วัดค่าปริมาณไฟฟ้าและคิดค่าไฟ

การใช้งาน ESP32+PZEM-004T เพื่อวัดปริมาณการใช้ไฟฟ้า วัดกำลังและพลังงานไฟฟ้ากระแสสลับ (Electric Power – Watt) และพลังงานไฟฟ้า (Energy – Wh)

ในการวัดค่าเพื่อบันทึกการใช้ปริมาณไฟฟ้า เพื่อการตรวจสอบ วัดค่าการใช้พลังงาน ควบคุมค่าไฟฟ้า แล้ว  อุปกรณ์วัดจำเป็นต้องให้ข้อมูลหลายๆ ค่า ได้แก่  แรงดัน (VAC) กระแส (IAC) กำลังไฟฟ้าจริง (Active power)  ค่าตัวประกอบกำลัง (Power Factor) ค่าพลังงานไฟฟ้า (Energy) เพื่อมาใช้ในการคำนวณคิค่าการใช้ไฟฟ้า โดยใช้โมดูล PZEM รับหน้าที่การคำนวณค่าต่างๆ ไปเรียบร้อย และส่งผลการคำนวณต่างๆ ออกมาจากโมดูลผ่านการสื่อสารแบบ serial (TX, RX) ซึ่งสามารถใช้เพื่อควบคุมสั่งการต่อด้วยบอร์ด Arduino หรือ ส่งค่าต่อไปที่คอมพิวเตอร์ การต่อวงจรดูรูปด้านล่าง

โปรแกรม

#define BLYNK_TEMPLATE_ID "TMPxxxx"
#define BLYNK_DEVICE_NAME "ESP32xxx"
#define BLYNK_FIRMWARE_VERSION        "0.1.0"
#define BLYNK_PRINT Serial
#define APP_DEBUG

#include "BlynkEdgent.h"
#include <PZEM004Tv30.h>
#if !defined(PZEM_RX_PIN) && !defined(PZEM_TX_PIN)
#define PZEM_RX_PIN 16
#define PZEM_TX_PIN 17
#endif

#if !defined(PZEM_SERIAL)
#define PZEM_SERIAL Serial2
#endif
#if defined(ESP32)
PZEM004Tv30 pzem(PZEM_SERIAL, PZEM_RX_PIN, PZEM_TX_PIN);
#elif defined(ESP8266)
#else
PZEM004Tv30 pzem(PZEM_SERIAL);
#endif
float cost_total = 0;
int v8;
int SW_Reset = 27;

void setup()
{
pinMode(SW_Reset,INPUT);
Serial.begin(115200);
delay(100);
BlynkEdgent.begin();
}

BLYNK_WRITE(V8)
{
v8 = param.asInt(); // Get value v21 Selector
}

BLYNK_WRITE(V9) {         //man reset kWh  
int pin_v9 = param.asInt();
if(v8 == 1) {
  pzem.resetEnergy();
}
}

void read_pzem()
{
  Serial.print("Custom Address:");
  Serial.println(pzem.readAddress(), HEX);
  // Read the data from the sensor
  float voltage = pzem.voltage();
  float current = pzem.current();
  float power = pzem.power();
  float energy = pzem.energy();
  float frequency = pzem.frequency();
  float pf = pzem.pf();
  Blynk.virtualWrite(V1,voltage);  
  Blynk.virtualWrite(V2,current);
  Blynk.virtualWrite(V3,power);
  Blynk.virtualWrite(V4,energy);
  Blynk.virtualWrite(V5,pf);    
  Blynk.virtualWrite(V6,frequency);
  float rate_1 = 3.2484;
  float rate_2 = 4.2218;
  float rate_3 = 4.4217;
      if (energy > 0 && energy <= 150) {   //หน่วยที่ 0-150
        rate_1 = energy * 3.8;
    }
    if (energy > 150) {
      rate_1 = 150 * 4.5;
    }
    if (energy >= 151 && energy <= 400) { //หน่วยที่ 151-400
      rate_2 = (energy - 150) * 4.4217;
    }
    if (energy > 400) { //เกิน 400
      rate_2 = 250 * 4.4217;
      rate_3 = (energy - 400) * 4.4217;
    }
    float ft = energy*(-0.116);
    float total_vat = (rate_1 + rate_2 + rate_3 + ft + 38.22)*0.07;
    float total = (rate_1 + rate_2 + rate_3 + ft + 38.22) + total_vat;
    cost_total = total;
    Blynk.virtualWrite(V7,cost_total);

    // Check if the data is valid
  if(isnan(voltage)){
      Serial.println("Error reading voltage");
  } else if (isnan(current)) {
      Serial.println("Error reading current");
  } else if (isnan(power)) {
      Serial.println("Error reading power");
  } else if (isnan(energy)) {
      Serial.println("Error reading energy");
  } else if (isnan(frequency)) {
      Serial.println("Error reading frequency");
  } else if (isnan(pf)) {
      Serial.println("Error reading power factor");
  } else {

      // Print the values to the Serial console
      Serial.print("Voltage: ");      Serial.print(voltage);      Serial.println("V");
      Serial.print("Current: ");      Serial.print(current);      Serial.println("A");
      Serial.print("Power: ");        Serial.print(power);        Serial.println("W");
      Serial.print("Energy: ");       Serial.print(energy,3);     Serial.println("kWh");
      Serial.print("Frequency: ");    Serial.print(frequency, 1); Serial.println("Hz");
      Serial.print("PF: ");           Serial.println(pf);
  }  
  Serial.println();
  delay(2000);
}

void CheckSW()
{
if(digitalRead(SW_Reset) == 0) {
  pzem.resetEnergy();
  cost_total = 0;
  delay(5000);
}
}

void loop() {
BlynkEdgent.run();
read_pzem();
CheckSW();
}"