จากกระทู้
ว่าด้วยเรื่อง Pzem 004t v3.0 จะวัดพลังงาน+ค่าใช้จ่าย/เดือน
ค่าไฟฟ้าสะสมลดลงเรื่อยๆเลยค่ะ เกิดจากอะไรหรอคะ
จากกระทู้
ว่าด้วยเรื่อง Pzem 004t v3.0 จะวัดพลังงาน+ค่าใช้จ่าย/เดือน
ค่าไฟฟ้าสะสมลดลงเรื่อยๆเลยค่ะ เกิดจากอะไรหรอคะ
ใช้โค้ตอะไร จากไหนครับ
ใช้โค้ตนี้ จากกระทู้ที่อ้างอิงค่ะ
//------ WiFi manager ----------------------------------------------------------------------------------------------------//
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include "WiFiManager.h"
#include <FS.h>
#include <DNSServer.h>
#include "ArduinoJson.h"
//--------Line Notify ------------------------------------------------------------------------------------------------------//
#include "TridentTD_LineNotify.h"
char line_token[45] = " ";
String LineText;
String string1 = "ค่าไฟฟ้าสะสม วันที่ ";
String string2 = "/";
String string3 = " จำนวน ";
String string4 = " หน่วย เป็นจำนวนเงินทั้งสิ้น ";
String string5 = " บาท ระบบทำการ Reset kWh = 0 แล้ว ***ให้ตรวจสอบค่า Ft ประจำเดือนด้วย*** ";
String string6 = " บาท *** ";
String string7 = " เวลา ";
String string8 = ":";
String string9 = "ขณะนี้กำลังไฟฟ้าเกินค่าที่กำหนดไว้";
//-------- Blynk ----------------------------------------------------------------------------------------------------------//
#define BLYNK_MAX_SENDBYTES 1200
#include <BlynkSimpleEsp8266.h>
#define BLYNK_DEBUG
#define BLYNK_PRINT Serial
int blynkIsDownCount = 0;
char blynk_token[34] = " ";
BlynkTimer timer;
char server[] = "oasiskit.com";
int port = 8080;
//-------- PB Reset & PB AP Config ----------------------------------------------------------------------------------------//
#define D0 16 // ใช้ไฟ LED สีฟ้า ของบอร์ด MCU ESP8266 ให้มีสัญญาณไฟกระพริบ ตาม Code ที่เขียน
#define D3 1 // ใช้เป็นปุ่มกด เพื่อเข้า AP Config ได้ตามความต้องการของผู้ใช้
// ------- โหลดไลบารี่ของจอ LCD มาใช้งาน โดยแบบนี้จะสามารถ Create Characterได้ --------------------------------------------------//
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4); //// ตั้งค่า Address ของอุปกรณ์จอ LCD ที่มีการเชื่อมต่อแบบ I2C
//----------การเก็บค่า จาก WiFimanager----------------------------------------------------------------------------------------//
bool shouldSaveConfig = false;
void saveConfigCallback () {
Serial.println("Should save config");
shouldSaveConfig = true;
}
//------------------------------------------------------------------------------------------------------------------------//
#include <EEPROM.h>
//----------PZEM --------------------------------------------------------------------------------------------------------//
#include <PZEM004Tv30.h>
#define lcd_SDA D2
#define lcd_SCL D1
#define lcd_RX D6
#define lcd_TX D7
#define buzzer D8
#define Relay D5
int relayState = 1;
PZEM004Tv30 pzem(D6, D7); // 12(D6)=RX , 13(D7) = TX : TX->D6(GPIO012),RX->D7(GPIO013)
//ตัวแปรรับค่า Ft จาก Blynk มาเก็บใน EEPROM
float Ft;
String Ft_1;
float Ft_2;
//ตัวแปรรับค่า วันที่ จาก Blynk มาเก็บใน EEPROM
float Rst_D;
String Rst_D1;
float Rst_D2;
//ตัวแปรรับค่า ชั่วโมง จาก Blynk มาเก็บใน EEPROM
float Rst_H;
String Rst_H1;
float Rst_H2;
//ตัวแปรรับค่า นาที จาก Blynk มาเก็บใน EEPROM
float Rst_M;
String Rst_M1;
float Rst_M2;
//ตัวแปรรับค่า MaxPower จาก Blynk มาเก็บใน EEPROM
float Set_MP;
String Set_MP1;
float Set_MP2;
//ตัวแปรรับค่า ค่าไฟประจำเดือน
float Electric_bill;
float kWh_1;
float kWh_2;
float kWh_3;
float kWh_T;
float kWh_T1;
//---- กดปุ่ม Reset kWh จาก Blynk -----------------------------------------------------------------------------------------//
int Blynkreset_kWh;
WidgetLED led_rst_kWh(V12);//จะ ON เมื่อกดปุ่มค้างไว้ 5 วินาที
//---- กดปุ่ม ON/OFF จาก Blynk -----------------------------------------------------------------------------------------//
int Blynk_CB;
WidgetLED led_CB(V31);
//ชุดกำหนดการส่ง Line แค่ครั้งเดียว
//----- รายงาน ตามวันที่ตั้งค่าจาก Blynk-----
int Line_status = 0;
int Line_status1 = 0;
//----- รายงาน ทุกวัน-----
//06.00 น.
int Line1_status = 0;
int Line1_status1 = 0;
//12.00 น.
int Line12_status = 0;
int Line12_status1 = 0;
//23.50 น.
int Line13_status = 0;
int Line13_status1 = 0;
//----- Restart ทุกวัน-----
int Line2_status ;
int Line2_status1 = 0;
int countcheck_Blynk = 0;
float energy1;
float energy2;
//------------------------------ ระบบเวลาและการเชื่อมต่อ Web Server ของNTP Server -----------------------------------------//
#include <time.h>
int timezone = 7 * 3600; //ตั้งค่า TimeZone ตามเวลาประเทศไทย
int dst = 0; //กำหนดค่า Date Swing Time
BLYNK_WRITE(V10) {
Ft_1 = param.asString();//รับค่าข้อความจาก Blynk เข้ามา เก็บในรูปแบบ String
Ft_2 = Ft_1.toFloat();//แปลงค่าจาก String เป็น Float
//เราป้อนค่า จาก Blynk เป็น String = -0.116 ให้ Ft_1 รับค่ามา
//Ft จะรับค่าการแปลง จาก Ft_1 เป็น Float = -0.12
//จะเห็นว่า ค่า Folat จะปัดค่าเป็นจุดทศนิยม ไปเป็น 2 ตำแหน่งจะไม่มากกว่านี้เนื่องด้วยความสามารถตัวของอุปกรณ์เอง
//ทำให้ค่าเพี้ยนไป ประมาณ 3.44% ทำให้ค่าไฟ/เดือน น้อยกว่าค่าจริงไป 3.44% ประมาณ 0.64(150หน่วย) - 2.14(500หน่วย) บาท
//โปรเจคนี้จะไม่เปลี่ยนค่า ใดๆ เพราะค่าต่างกันเล็กน้อย (1 เดือน ใช้ไฟไม่ถึง 500 หน่วยแน่นอน)
//ชุดนี้ทำขึ้นในกรณีที่ ไม่ได้เชื่อมต่อกับ App Blynk ก็ยังสามารถดูค่าทั้งหมดได่อย่างถูกต้อง แต่ทุกครั้งที่มีการเปลี่ยนค่า Ft วันที่ ชั่วโมง นาที จะต้องถูกกำนดค่าผ่าน App Blynk มาทุกครั้ง
EEPROM.put(0, Ft_2); //เขียนค่า Ft_2 ที่เป็น Float ลงใน Address 0
EEPROM.commit(); //จบการเขียน
Ft = EEPROM.get(0, Ft_2);//อ่าน ค่า Ft_2 ที่เป็น Float จาก Address 0
Serial.println(Ft);//แสดงค่า Ft ใน Serial Monitor
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("...... Sync Ft .....");
lcd.setCursor(7, 2);
lcd.print(Ft, 3);
delay(2000);
lcd.clear();
}
BLYNK_WRITE(V20)//Reset kWh Automatic ตามวันที่ ที่ตั้งจาก Blynk เข้าเครื่อง
{
Rst_D1 = param.asString();//รับค่าข้อความจาก Blynk เข้ามา เก็บในรูปแบบ String
Rst_D2 = Rst_D1.toFloat();//แปลงค่าจาก String เป็น Float
//ชุดนี้ทำขึ้นในกรณีที่ ไม่ได้เชื่อมต่อกับ App Blynk ก็ยังสามารถ Rst ค่า kWh ได้ แต่ทุกครั้งที่มีการเปลี่ยนค่า วัน เวลา จะต้องถูกกำนดค่าผ่าน App Blynk มาทุกครั้ง
EEPROM.put(20, Rst_D2); //เขียนค่า Rst_D2 ที่เป็น Float ลงใน Address 20
EEPROM.commit(); //จบการเขียน
Rst_D = EEPROM.get(20, Rst_D2);//อ่าน ค่า Rst_2 ที่เป็น Float จาก Address 20
Serial.println(Rst_D);//แสดงค่า Rst ใน Serial Monitor
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("Sync Auto Rst By Day");
lcd.setCursor(6, 2);
lcd.print("Day : ");
lcd.setCursor(12, 2);
lcd.print(Rst_D, 0);
delay(2000);
lcd.clear();
}
BLYNK_WRITE(V21)//Reset kWh Automatic ตามชั่วโมง ที่ตั้งจาก Blynk เข้าเครื่อง
{
Rst_H1 = param.asString();//รับค่าข้อความจาก Blynk เข้ามา เก็บในรูปแบบ String
Rst_H2 = Rst_H1.toFloat();//แปลงค่าจาก String เป็น Float
//ชุดนี้ทำขึ้นในกรณีที่ ไม่ได้เชื่อมต่อกับ App Blynk ก็ยังสามารถ Rst ค่า kWh ได้ แต่ทุกครั้งที่มีการเปลี่ยนค่า วัน เวลา จะต้องถูกกำนดค่าผ่าน App Blynk มาทุกครั้ง
EEPROM.put(30, Rst_H2); //เขียนค่า Rst_H2 ที่เป็น Float ลงใน Address 30
EEPROM.commit(); //จบการเขียน
Rst_H = EEPROM.get(30, Rst_H2);//อ่าน ค่า Rst_H2 ที่เป็น Float จาก Address 30
Serial.println(Rst_H);//แสดงค่า Rst ใน Serial Monitor
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("Sync AutoRst By Hour");
lcd.setCursor(5, 2);
lcd.print("Hour : ");
lcd.setCursor(12, 2);
lcd.print(Rst_H, 0);
delay(2000);
lcd.clear();
}
BLYNK_WRITE(V22)//Reset kWh Automatic ตามนาที ที่ตั้งจาก Blynk เข้าเครื่อง
{
Rst_M1 = param.asString();//รับค่าข้อความจาก Blynk เข้ามา เก็บในรูปแบบ String
Rst_M2 = Rst_M1.toFloat();//แปลงค่าจาก String เป็น Float
//ชุดนี้ทำขึ้นในกรณีที่ ไม่ได้เชื่อมต่อกับ App Blynk ก็ยังสามารถ Rst ค่า kWh ได้ แต่ทุกครั้งที่มีการเปลี่ยนค่า วัน เวลา จะต้องถูกกำนดค่าผ่าน App Blynk มาทุกครั้ง
EEPROM.put(40, Rst_M2); //เขียนค่า Rst_M2 ที่เป็น Float ลงใน Address 40
EEPROM.commit(); //จบการเขียน
Rst_M = EEPROM.get(40, Rst_M2);//อ่าน ค่า Rst_M2 ที่เป็น Float จาก Address 40
Serial.println(Rst_M);//แสดงค่า Rst ใน Serial Monitor
lcd.clear();
lcd.setCursor(3, 0);
lcd.print("Sync Auto Rst");
lcd.setCursor(5, 1);
lcd.print("By Minute");
lcd.setCursor(4, 2);
lcd.print("Minute : ");
lcd.setCursor(13, 2);
lcd.print(Rst_M, 0);
delay(2000);
lcd.clear();
}
BLYNK_WRITE(V23)//Setting MaxPower จาก Blynk
{
Set_MP1 = param.asString();//รับค่าข้อความจาก Blynk เข้ามา เก็บในรูปแบบ String
Set_MP2 = Set_MP1.toFloat();//แปลงค่าจาก String เป็น Float
//ชุดนี้ทำขึ้นในกรณีที่ ไม่ได้เชื่อมต่อกับ App Blynk ก็ยังสามารถ Rst ค่า kWh ได้ แต่ทุกครั้งที่มีการเปลี่ยนค่า วัน เวลา จะต้องถูกกำนดค่าผ่าน App Blynk มาทุกครั้ง
EEPROM.put(50, Set_MP2); //เขียนค่า Rst_MP2 ที่เป็น Float ลงใน Address 50
EEPROM.commit(); //จบการเขียน
Set_MP = EEPROM.get(50, Set_MP2);//อ่าน ค่า Rst_MP2 ที่เป็น Float จาก Address 50
Serial.println(Set_MP);//แสดงค่า MaxPower ใน Serial Monitor
lcd.clear();
lcd.setCursor(2, 1);
lcd.print("Setting MaxPower");
lcd.setCursor(3, 2);
lcd.print("MaxPower = ");
lcd.setCursor(14, 2);
lcd.print(Set_MP, 0);
delay(2000);
lcd.clear();
}
BLYNK_WRITE(V11)//Reset kWh ภายใน 5 วินาที จาก Blynk
{
int pinValue = param.asInt();
if (pinValue == 1) {
Blynkreset_kWh = 1;
}
if (pinValue == 0) {
Blynkreset_kWh = 0;
}
}
BLYNK_WRITE(V30) { // ON/OFF Energy Meter
int pinValue = param.asInt();
if (pinValue == 1) {
Blynk_CB = 1;
digitalWrite(Relay, HIGH);
}
if (pinValue == 0) {
Blynk_CB = 0;
digitalWrite(Relay, LOW);
}
}
//------------------------------------------------------------------------------------------------------------------------//
//********************************************* void setup **************************************************//
//------------------------------------------------------------------------------------------------------------------------//
void setup() {
//-------IO NODE MCU Esp8266-------//
pinMode(D0, OUTPUT); //กำหนดโหมดใช้งานให้กับขา D0 เป็นขา สัญญาณไฟ ในสภาวะต่างๆ
pinMode(D3, INPUT_PULLUP);//กำหนดโหมดใช้งานให้กับขา D4 เป็นขา กดปุ่ม ค้าง เพื่อตั้งค่า AP config
pinMode(buzzer, OUTPUT);
pinMode(Relay, OUTPUT);
digitalWrite(buzzer, LOW);
digitalWrite(Relay, HIGH);
// ให้ LED ทั้งหมดดับก่อน
digitalWrite(D0, LOW);//ให้หลอด LED สีฟ้าดับก่อน
Serial.begin(115200);
Serial.setDebugOutput(true);
EEPROM.begin(512);
//ต้องการให้รู้ว่า ค่า Ft ที่เป็น Float ที่เก็บใน EEPROM มีค่า = ค่าที่ถูกป้อนมาจาก Bylnk จริงๆหรือปล่าว
Ft = EEPROM.get(0, Ft_2);
Serial.print("Ft in Void setup : ");
Serial.println(Ft);
//ต้องการให้รู้ว่า ค่า วันที่ ที่เป็น Float ที่เก็บใน EEPROM มีค่า = ค่าที่ถูกป้อนมาจาก Bylnk จริงๆหรือปล่าว
Rst_D = EEPROM.get(20, Rst_D2);
Serial.print("Day in Void setup : ");
Serial.println(Rst_D);
//ต้องการให้รู้ว่า ค่า ชั่วโมง ที่เป็น Float ที่เก็บใน EEPROM มีค่า = ค่าที่ถูกป้อนมาจาก Bylnk จริงๆหรือปล่าว
Rst_H = EEPROM.get(30, Rst_H2);
Serial.print("Hour in Void setup : ");
Serial.println(Rst_H);
//ต้องการให้รู้ว่า ค่า นาที ที่เป็น Float ที่เก็บใน EEPROM มีค่า = ค่าที่ถูกป้อนมาจาก Bylnk จริงๆหรือปล่าว
Rst_M = EEPROM.get(40, Rst_M2);
Serial.print("Minute in Void setup : ");
Serial.println(Rst_M);
Set_MP = EEPROM.get(50, Set_MP2);
Serial.print("Setting MaxPower : ");
Serial.println(Set_MP);
//******ช่วงแรก เก็บค่าLine2_status ได้ = -1 ดังนั้น ต้องแก้ int Line2_status ;
// และใส่ชุดนี้เข้าไปก่อน เพื่อให้เก็บค่า Line2_status ได้ = 0 ได้ จากนั้นไม่ต้องใช้อีก
// EEPROM.put(90, 0);
// EEPROM.commit(); //จบการเขียน
// Serial.println("Line2_status:");
// Serial.println(Line2_status);
//Restart ทุกวัน เพื่อให้รู้ว่าค่า Line2_status อยู่ในสถานะอะไร แล้วเอาค่านี้ไปทำต่อ
Line2_status = EEPROM.get(90, Line2_status);//อ่าน ค่า Rst_H2 ที่เป็น Float จาก Address 90
Serial.print("Line2_status:");//แสดงค่า Rst ใน Serial Monitor
Serial.println(Line2_status);//แสดงค่า Rst ใน Serial Monitor
lcd.init();
lcd.clear();
//read configuration from FS json
Serial.println("mounting FS...");//แสดงข้อความใน Serial Monitor
if (SPIFFS.begin()) {
Serial.println("mounted file system");//แสดงข้อความใน Serial Monitor
if (SPIFFS.exists("/config.json")) {
//file exists, reading and loading
Serial.println("reading config file");//แสดงข้อความใน Serial Monitor
File configFile = SPIFFS.open("/config.json", "r");
if (configFile) {
Serial.println("opened config file");
size_t size = configFile.size();
// Allocate a buffer to store contents of the file.
std::unique_ptr<char[]> buf(new char[size]);
configFile.readBytes(buf.get(), size);
DynamicJsonBuffer jsonBuffer;
JsonObject& json = jsonBuffer.parseObject(buf.get());
json.printTo(Serial);
if (json.success()) {
Serial.println("\nparsed json");//แสดงข้อความใน Serial Monitor
strcpy(blynk_token, json["blynk_token"]);
strcpy(line_token, json["line_token"]);
} else {
Serial.println("failed to load json config");//แสดงข้อความใน Serial Monitor
}
}
}
} else {
Serial.println("failed to mount FS");//แสดงข้อความใน Serial Monitor
}
//end read
//------------สร้างชื่อกำกับช่อง-----------------------------------------------------------------------//
WiFiManagerParameter custom_text0("<p> </p>");
WiFiManagerParameter custom_text1("<label>ป้อน Blynk Token</label>");
WiFiManagerParameter custom_text2("<label>ป้อน LINE Token</label>");
//------------สร้างช่อง----------------------------------------------------------------------------//
WiFiManagerParameter custom_blynk_token("blynk", "blynk token", blynk_token, 34);
WiFiManagerParameter custom_line_token("LINE", "line_token", line_token, 45);
//WiFiManager
//Local intialization. Once its business is done, there is no need to keep it around
WiFiManager wifiManager;
//set config save notify callback
wifiManager.setSaveConfigCallback(saveConfigCallback);
//------------เรียงลำดับ ชื่อกำกับช่อง + ช่อง-----------------------------------------------------------//
wifiManager.addParameter(&custom_text0);
wifiManager.addParameter(&custom_text1);
wifiManager.addParameter(&custom_blynk_token);
wifiManager.addParameter(&custom_text2);
wifiManager.addParameter(&custom_line_token);
delay(1000);
for (int i = 5; i > -1; i--) { // นับเวลาถอยหลัง 5 วินาทีก่อนกดปุ่ม AP Config
digitalWrite(D0, HIGH);
delay(500);
digitalWrite(D0, LOW);
delay(500);
Serial.print (String(i) + " ");
}
if (digitalRead(D3) == LOW) {
digitalWrite(D0, LOW);
Serial.println("Button Pressed");
wifiManager.resetSettings();//ให้ล้างค่า SSID และ Password ที่เคยบันทึกไว้
// wifiManager.autoConnect(); ใช้สร้างชื่อแอคเซสพอยต์อันโนมัติจาก ESP + ChipID
if (!wifiManager.autoConnect("AutoConnectAP")) {
Serial.println("failed to connect and hit timeout");
delay(3000);
//reset and try again, or maybe put it to deep sleep
ESP.reset();
delay(5000);
}
}
Serial.println(": Connected.......OK!)");
strcpy(blynk_token, custom_blynk_token.getValue());
strcpy(line_token, custom_line_token.getValue());
//save the custom parameters to FS
if (shouldSaveConfig) {
DynamicJsonBuffer jsonBuffer;
JsonObject& json = jsonBuffer.createObject();
//------------------------------------------------------------------
Serial.println("saving Blynk config");
json["blynk_token"] = blynk_token;
File configFile = SPIFFS.open("/config.json", "w");
//------------------------------------------------------------------
Serial.println("saving line config");
json["line_token"] = line_token;
File configFile1 = SPIFFS.open("/config.json", "w");
//------------------------------------------------------------------
if (!configFile) {
Serial.println("failed to open config file for writing");//แสดงข้อความใน Serial Monitor
}
json.printTo(configFile);
configFile.close();
json.printTo(configFile1);
configFile1.close();
}
//-----------------------------------------------------------------------------------------------------------------------//
Serial.println();
Serial.print("local ip : ");
delay(100);
Serial.println(WiFi.localIP());
delay(100);
Serial.print("SSID : ");
delay(100);
Serial.println(WiFi.SSID());
Serial.print("Password : ");
delay(100);
Serial.println(WiFi.psk());
//-----------------------------------------------------------------------------------------------------------------------//
Serial.println();
//Print เพื่อเชคว่าค่าที่บันทึกไว้ยังอยู่หรือไม่
Serial.println("เชคว่าค่าที่บันทึกไว้ยังอยู่หรือไม่");
Serial.print("Blynk_token = ");
Serial.println(blynk_token);
Serial.print("Line_token = ");
Serial.println(line_token);
LINE.setToken(line_token);
//-----------------------------------------------------------------------------------------------------------------------//
configTime(timezone, dst, "1.th.pool.ntp.org", "0.asia.pool.ntp.org", "3.asia.pool.ntp.org"); //แสดงเวลาปัจจุบัน ดึงจากServer
while (!time(nullptr)) {//วนจนกว่า ค่าเวลา จะถูกต้อง แล้วจึงปล่อยออกไป
delay(500);
}
Blynk.config(blynk_token, server, port); // Blynk.config(blynk_token);////เริ่มการเชื่อมต่อ Blynk Server แบบปกติ
////เริ่มการเชื่อมต่อ Blynk Server*********สำหรับ Server local ที่แจกให้ เพิ่ม, server, port แค่นี้จบ
timer.setInterval(30000L, reconnecting);
lcd.init();
lcd.backlight();
lcd.setCursor(5,0);
lcd.print("PROJECT 4C1");
lcd.setCursor(4,1);
lcd.print("Smart Energy");
lcd.setCursor(7,2);
lcd.print("Meter");
lcd.setCursor(5,3);
lcd.print("GROUP 6321");
delay(5000);
lcd.clear();
}
//------------------------------------------------------------------------------------------------------------------------//
//********************************************* void Loop ***************************************************//
//------------------------------------------------------------------------------------------------------------------------//
void loop() {
//------- แสดงค่า เวลา -------------------------//
time_t now = time(nullptr);
struct tm* p_tm = localtime(&now);
String now_time = "";
now_time = now_time + p_tm->tm_hour; // hour
now_time = now_time + ":"; // hour:
now_time = now_time + p_tm->tm_min; // hour:min
now_time = now_time + ":"; // hour:min:
now_time = now_time + p_tm->tm_sec; // hour:min:sec
// Serial.println(now_time); // ส่งข้อความออกทาง Serial Monitor พร้อมขึ้นบรรทัดใหม่
String now_day = "";
now_day = now_day + p_tm->tm_mday; // day
now_day = now_day + "/"; // -
now_day = now_day + (p_tm->tm_mon + 1); // month
now_day = now_day + "/"; // -
now_day = now_day + (p_tm->tm_year + 1900 + 543); // year
//Serial.println(now_day); // ส่งข้อความออกทาง Serial Monitor พร้อมขึ้นบรรทัดใหม่
String dateTime = now_day + " "; // day-mon-year
lcd.setCursor(0, 3);
//เติม 0 กรณีเป็นเลข วัน เดือน ชม. นาที วินาที ตัวเดียว
if (p_tm->tm_mday < 10) {
lcd.print("0");
lcd.print(p_tm->tm_mday);
} else lcd.print(p_tm->tm_mday);
lcd.print('/');
if ((p_tm->tm_mon + 1) < 10) {
lcd.print("0");
lcd.print((p_tm->tm_mon + 1));
} else lcd.print((p_tm->tm_mon + 1));
lcd.print('/');
lcd.print((p_tm->tm_year + 1900 + 543 - 2500));
lcd.setCursor(12, 3);
if (p_tm->tm_hour < 10) {
lcd.print("0");
lcd.print(p_tm->tm_hour);
} else lcd.print(p_tm->tm_hour);
lcd.print(':');
if (p_tm->tm_min < 10) {
lcd.print("0");
lcd.print(p_tm->tm_min);
} else lcd.print(p_tm->tm_min);
lcd.print(':');
if (p_tm->tm_sec < 10) {
lcd.print("0");
lcd.print(p_tm->tm_sec);
} else lcd.print(p_tm->tm_sec);
if (Blynk_CB == 1) {
Blynk.virtualWrite(V0, "ระบบเริ่มทำงาน");
led_CB.on();
}
if (Blynk_CB == 0) {
Blynk.virtualWrite(V0, "POWER OFF");
led_CB.off();
}
// กดปุ่มจาก Blynk 5 วินาที เพื่อ Reset kWh กดค้างจนกว่า LED จะดับ แบบที่ 2
// จะมีการ Restart ระบบด้วย
if (Blynkreset_kWh == 1) {
led_rst_kWh.on();
lcd.setCursor(5, 3);
lcd.print((char)0x20);
lcd.print((char)0x20);
lcd.print((char)0x20);
lcd.print((char)0x20);
lcd.print((char)0x20);
Blynk.virtualWrite(V0, "มีการ RESET ระบบ");
delay(3000);
pzem.resetEnergy();
led_rst_kWh.off();
ESP.restart();
}
if (Blynkreset_kWh == 0) {
led_rst_kWh.off();
}
// Reset kWh แบบ Auto โดยการตั้งค่ามาจาก Blynk โดยเก็บไว้ใน EEPROM ของเครื่อง แบบที่ 3 กรณีประจำเดือน
// ส่ง Line 1 ครั้งเท่านั้น กรณีประจำเดือน จากนั้นระบบจะ Restart
if (Rst_D == p_tm->tm_mday && Rst_H == p_tm->tm_hour && Rst_M == p_tm->tm_min && Line_status == 0) {
//loop ป้องกันการอ่านค่าไม่ได้
loop9 :
energy2 = pzem.energy();
if (isnan(energy2)) {
delay(1000);
goto loop9 ;
}
LineText = string1 + now_day + string7 + now_time +
string3 + energy2 + string4 + Electric_bill + string5;
//ค่าไฟฟ้าสะสม วันที่ x/x/xxx เวลา x:x:x จำนวน 2.65 หน่วย เป็นจำนวนเงินทั้งสิ้น 49.78 บาท
//ระบบทำการ Reset kWh = 0 แล้ว ***ให้ตรวจสอบค่า Ft ประจำเดือนด้วย***
LINE.notify(LineText);
delay(200);
Blynk.virtualWrite(V0, "จะ RST ระบบใน 1นาที");
//Serial.println("reset kWh");มันจะ Reset ซ้ำ กันใน 1 นาทีนี้ และยกเลิกจนกว่าจะขึ้นนาทีใหม่
Line_status = 1;
Line_status1 = 0;
}
else if (Rst_D == p_tm->tm_mday && Rst_H == p_tm->tm_hour && Rst_M == p_tm->tm_min && Line_status == 1) {
delay(10);
Line_status1 = 1;
}
//หลังจากส่งไลน์ เสร็จแล้ว อีก 1 นาที ให้ระบบ resetEnergy และ Restart
if (Rst_M != p_tm->tm_min && Line_status1 == 1 ) {
delay(10);
Line_status = 0;
delay(1500);
pzem.resetEnergy();
delay(1500);
ESP.restart();
}
// ส่ง Line ค่าไฟ ประจำวัน
// ส่ง Line 1 ครั้งเท่านั้น 6.00 น.
if (p_tm->tm_hour == 06 && p_tm->tm_min == 00 && Line1_status == 0) {
Blynk.virtualWrite(V0, "Line Notify 6.00");
delay(100);
loop10 :
energy1 = pzem.energy();
if (isnan(energy1)) {
delay(1000);
goto loop10 ;
}
LineText = string1 + now_day + string7 + now_time +
string3 + energy1 + string4 + Electric_bill + string6;
LINE.notify(LineText);
delay(200);
Line1_status = 1;
Line1_status1 = 0;
}
else if (p_tm->tm_hour == 06 && p_tm->tm_min == 00 && Line1_status == 1) {
delay(10);
Line1_status1 = 1;
}
if (p_tm->tm_hour == 06 && p_tm->tm_min == 01 && Line1_status1 == 1 ) {
delay(10);
Line1_status = 0;
}
// ส่ง Line 1 ครั้งเท่านั้น 12.00 น.
if (p_tm->tm_hour == 12 && p_tm->tm_min == 00 && Line12_status == 0) {
Blynk.virtualWrite(V0, "Line Notify 12.00");
delay(100);
loop11 :
energy1 = pzem.energy();
if (isnan(energy1)) {
delay(1000);
goto loop11 ;
}
LineText = string1 + now_day + string7 + now_time +
string3 + energy1 + string4 + Electric_bill + string6;
LINE.notify(LineText);
delay(200);
Line12_status = 1;
Line12_status1 = 0;
}
else if (p_tm->tm_hour == 12 && p_tm->tm_min == 00 && Line12_status == 1) {
delay(10);
Line12_status1 = 1;
}
if (p_tm->tm_hour == 12 && p_tm->tm_min == 03 && Line12_status1 == 1 ) {
delay(10);
Line12_status = 0;
}
// ส่ง Line 1 ครั้งเท่านั้น 23.50 น.
if (p_tm->tm_hour == 23 && p_tm->tm_min == 50 && Line13_status == 0) {
Blynk.virtualWrite(V0, "Line Notify 23.50");
delay(100);
loop12 :
energy1 = pzem.energy();
if (isnan(energy1)) {
delay(1000);
goto loop12 ;
}
LineText = string1 + now_day + string7 + now_time +
string3 + energy1 + string4 + Electric_bill + string6;
LINE.notify(LineText);
delay(200);
Line13_status = 1;
Line13_status1 = 0;
}
else if (p_tm->tm_hour == 23 && p_tm->tm_min == 50 && Line13_status == 1) {
delay(10);
Line13_status1 = 1;
}
if (p_tm->tm_hour == 23 && p_tm->tm_min == 51 && Line13_status1 == 1 ) {
delay(10);
Line13_status = 0;
}
//---------------------- Restart ทุกวัน
// สั่ง Restart 1 ครั้งเท่านั้น
if (p_tm->tm_hour == 1 && p_tm->tm_min == 0 && Line2_status == 0) {
//ถึงเวลาที่ตั้ง ส่ง Line บอกว่า เครื่อง Restart
Blynk.virtualWrite(V0, "Pzem RST");
delay(100);
LINE.notify("PZEM SYSTEM RESTART");
delay(200);
// ให้ Line2_status = 1 แล้วเก็บใน EEPROMP จากนั้นเครื่องจะ Restart โดยเก็บค่า Line2_status = 1ไว้
Line2_status = 1;
Line2_status1 = 0;
EEPROM.put(90, Line2_status); //เขียนค่า Line2_status = 1 ที่เป็น Float ลงใน Address 90
EEPROM.commit(); //จบการเขียน
Serial.println("Line2_status:");//แสดงค่า Rst ใน Serial Monitor
Serial.println(Line2_status);//แสดงค่า Rst ใน Serial Monitor
ESP.restart();
}
else if (p_tm->tm_hour == 1 && p_tm->tm_min == 0 && Line2_status == 1) {
delay(10);
Line2_status1 = 1;
}
//ต้องใส่วินาทีเข้าไปด้วย ไม่อย่างนั้นช่วงรอยต่อ 1 นาที จะมีการบันทึกค่าซ้ำ กัน 60 ครั้ง ซึ่งจะทำให้ EEPROMP อายุสั้นลง
if (p_tm->tm_hour == 1 && p_tm->tm_min == 0 && p_tm->tm_sec <= 5 && Line2_status1 == 1 ) {
delay(10);
Line2_status = 0;
EEPROM.put(90, Line2_status);//เขียนค่า Line2_status = 0 ที่เป็น Float ลงใน Address 90
EEPROM.commit(); //จบการเขียน
Serial.print("Line2_status:");
Serial.println(Line2_status);
}
//--------- แสดงค่า ต่างๆ ของ PZEM --------------//
float voltage = pzem.voltage();
lcd.setCursor(0,0);
lcd.print("V");
lcd.setCursor(3,0);
if(isnan(voltage)){
lcd.setCursor(5,0);
}
lcd.print(voltage, 1);
Blynk.virtualWrite(V1, voltage);
float current = pzem.current();
lcd.setCursor(12,0);
lcd.print("A");
lcd.setCursor(16,0);
if(isnan(current)){
lcd.setCursor(17,0);
}
lcd.print(current, 2);
Blynk.virtualWrite(V2, current);
float power = pzem.power();
lcd.setCursor(0,1);
lcd.print("W");
if(power < 10) lcd.setCursor(5,1);
else if(power < 100) lcd.setCursor(4,1);
else if(power < 1000) lcd.setCursor(3,1);
else if(power < 10000) lcd.setCursor(2,1);
else {
lcd.setCursor(5,1);
}
lcd.print(power, 1);
Blynk.virtualWrite(V3, power);
float energy = pzem.energy();
lcd.setCursor(12,1);
lcd.print("U");
if(energy < 10) lcd.setCursor(17,1);
else if(energy < 100) lcd.setCursor(16,1);
else if(energy < 1000) lcd.setCursor(15,1);
else {
lcd.setCursor(17,1);
}
lcd.print(energy, 1);
Blynk.virtualWrite(V4, energy);
float frequency = pzem.frequency();
lcd.setCursor(0,2);
lcd.print("Hz");
lcd.setCursor(4,2);
if(isnan(frequency)){
lcd.setCursor(5,2);
}
lcd.print(frequency, 1);
Blynk.virtualWrite(V5, frequency);
float pf = pzem.pf();
if (isnan(pf)) {
Blynk.virtualWrite(V6, 0);
} else {
lcd.setCursor(12,2);
lcd.print("PF");
lcd.setCursor(16,2);
lcd.print(pf, 2);
Blynk.virtualWrite(V6, pf);
}
//-------------------------overpower();------------------------------
if (power - Set_MP >= Set_MP/5) { //ถ้ากระแสมากกว่ากระแสสูงสุดที่กำหนดไว้ buzzer จะดังและ relay จะตัด
LineText = string9;
LINE.notify(LineText);
delay(100);
Blynk.virtualWrite(V0, "Over Power");
digitalWrite(buzzer, HIGH);
delay(150);
digitalWrite(buzzer, LOW);
digitalWrite(Relay, LOW);
}
relayState = digitalRead(Relay);
if (relayState == 0) {
lcd.clear();
lcd.setCursor(5,1);
lcd.print("OVER POWER");
lcd.setCursor(4,2);
lcd.print("PLEASE RESET");
delay(5000);
lcd.clear();
}
//--------------------------------------------------------------------
//1.2 อัตราปกติปริมาณการใช้พลังงานไฟฟ้าเกินกว่า 150 หน่วยต่อเดือน
//ที่บ้านเราใช้ค่านี้ ประเภท 1125 คือ ใช้ไฟฟ้าเกิน 150 หน่วย/เดือน อัตราค่าบริการ 38.22 บาท/เดือน
//1 - 150 หน่วยละ 3.2484 บาท
if (energy >= 1 && energy <= 150) {
kWh_1 = energy * 3.2484;
}
if (energy > 150) {
kWh_1 = 150 * 3.2484;
}
//หน่วยที่ 151 - 400 หน่วยละ 4.2218 บาท
if (energy >= 151 && energy <= 400) {
kWh_2 = (energy - 150) * 4.2218;
}
if (energy > 400) {
kWh_2 = 250 * 4.2218;
//401 -- > หน่วยละ 4.4217 บาท
kWh_3 = (energy - 400) * 4.4217;
}
//รวมค่าใช้จ่ายทั้งหมด
kWh_T = kWh_1 + kWh_2 + kWh_3;
kWh_T1 = kWh_T + 38.22 + (energy * Ft);
Electric_bill = kWh_T1 + (kWh_T1 * 0.07);
Blynk.virtualWrite(V7, Electric_bill);
countcheck_Blynk ++;
if (countcheck_Blynk == 2) {//ทุกๆ 3 วินาที เชค temp + humid 1 ครั้ง
check_Blynk();
}
if (countcheck_Blynk == 3) {//ทุกๆ 3 วินาที เชค temp + humid 1 ครั้ง
countcheck_Blynk = 0;
}
timer.run();//ให้เวลาของ Blynk ทำงาน
delay(2000);
}
void check_Blynk() {
//------------- Blynk Connect ---------------//
if (Blynk.connected()) {
Blynk.run();
digitalWrite(D0, LOW);
} else {
digitalWrite(D0, LOW);
delay(200);
digitalWrite(D0, HIGH);
delay(100);
}
}
void reconnecting() {
if (!Blynk.connected()) {
blynkIsDownCount++;
BLYNK_LOG("blynk server is down! %d times", blynkIsDownCount);
Blynk.connect(5000);
}
}
BLYNK_CONNECTED() {
Blynk.syncAll();//ให้ซิงค์ข้อมูลทั้งหมดล่าสุดจาก Blynk Server
}
คุณพระ! เกิดอะไรขึ้นกับค่า FT ครับ ทำไมมันมีค่าติดลบอยู่ครับ
ดูค่า ft จาก https://www.mea.or.th/content/detail/2985/2987/474 แล้วก็นำมาใช้ปกติเลยนะคะ แต่ทำไมค่าลดลงก็ไม่รู้ค่ะ
ตอนนี้ตั้งขอสังเกตอะไรไว้บ้างครับ สงสัย ตรงจุดไหนเป็นพิเศษว่าอาจจะเป๋นสาเหตุนั้นๆ
ขอ capture ของblynk.เต็มๆ ได้มั๊ยครับ
ค่า แรงดัน กระแส PF ถูกแล้วครับ ลองดู code ที่นำค่า 38.60W ไปเป็นค่าเงิน ดูสูตร แล้วลองคำนวณดูก่อนครับ ถ้าคำนวณถูก ก็มาดูตัวแปรที่รับค่ามาว่า มันแสดงค่าถูกหรือปล่าวครับ อีกส่วนหนึ่ง code ที่แสดงให้ดูคือ code ที่กำลังใช้อยู่ใช่มั๊ยครับ
ผมลองคำนวนเล่นๆ เหมือนว่าเราไปดึงค่า ft มาจาก eeprom ผมไม่แน่ใจว่า มันดึงมาถูกหรือไม่ ตอนนี้ผมสนใจอยู่ 2 ค่าคือ energy กับ Ft ในระดับจุดทศนิยม หากมีการเพี้ยนไป 0.1 หรือ 0.01 มันสามารถ ส่งผลต่อผลลัพธ์ ได้ใกล้เคียงกับ พิกัดค่าไฟที่ถ่ายมาให้ดู
ลอง prinf 2 ค่านี้ออกมาดูก่อนที่จะให้ส่ง line ก็ได้ครับ สัก 2 - 3 รอบ
ใช่ค่ะ เดี๋ยวจะลองสั่งให้ print ค่า ft กับ energy ดูว่าค่าปกติมั้ย
ค่ากลับมาปกติแล้วค่ะ เหมือน library มันรวนเลยอัพเดทเวอร์ชั่นแล้วอัพโหลดโค้ดใหม่
ขอสอบถามหน่อยค่ะ
//---------------------- Restart ทุกวัน
// สั่ง Restart 1 ครั้งเท่านั้น
if (p_tm->tm_hour == 1 && p_tm->tm_min == 0 && Line2_status == 0) {
//ถึงเวลาที่ตั้ง ส่ง Line บอกว่า เครื่อง Restart
Blynk.virtualWrite(V0, "Pzem RST");
delay(100);
LINE.notify("PZEM SYSTEM RESTART");
delay(200);
// ให้ Line2_status = 1 แล้วเก็บใน EEPROMP จากนั้นเครื่องจะ Restart โดยเก็บค่า Line2_status = 1ไว้
Line2_status = 1;
Line2_status1 = 0;
EEPROM.put(90, Line2_status); //เขียนค่า Line2_status = 1 ที่เป็น Float ลงใน Address 90
EEPROM.commit(); //จบการเขียน
Serial.println("Line2_status:");//แสดงค่า Rst ใน Serial Monitor
Serial.println(Line2_status);//แสดงค่า Rst ใน Serial Monitor
ESP.restart();
}
else if (p_tm->tm_hour == 1 && p_tm->tm_min == 0 && Line2_status == 1) {
delay(10);
Line2_status1 = 1;
}
//ต้องใส่วินาทีเข้าไปด้วย ไม่อย่างนั้นช่วงรอยต่อ 1 นาที จะมีการบันทึกค่าซ้ำ กัน 60 ครั้ง ซึ่งจะทำให้ EEPROMP อายุสั้นลง
if (p_tm->tm_hour == 1 && p_tm->tm_min == 0 && p_tm->tm_sec <= 5 && Line2_status1 == 1 ) {
delay(10);
Line2_status = 0;
EEPROM.put(90, Line2_status);//เขียนค่า Line2_status = 0 ที่เป็น Float ลงใน Address 90
EEPROM.commit(); //จบการเขียน
Serial.print("Line2_status:");
Serial.println(Line2_status);
}
โค้ดตรงส่วนนี้เอาไว้ใช้ทำอะไรหรอคะ
เป็นการสั่งให้ esp8266 Restart ทุกวันครับ ไม่ต้องใช้ก็ได้ ลบส่วนนี้ กับส่วนที่เกี่ยวข้องตามตำแหน่งที่ต่างๆ ออกไปได้เลยครับ
อยากรู้ว่าอัพเป็น version อะไรถึงหายครับ อยากให้ระบุไว้หน่อย เผื่อ ใช้อ้างอิง version ที่ เสถียรที่สุด
Arduino 1.8.7
Json 5.13.3
WifiManager อัพเดทเป็นเวอร์ชั่นล่าสุด 2.0.3 alpha ค่ะ
ถ้าอยากให้แจ้งเตือนว่าแต่ละวันใช้ไปกี่ยูนิตต้องทำยังไงหรอคะ