สำหรับ Post นี้ เป็นของจริงแล้วครับ แต่ต้องผ่านการทดสอบก่อนโดยผมจะนำมาแชร์ Project กัน เริ่มเลยนะครับ
Diagram การต่อสาย
ความต้องการของ Project (เพื่อป้องกันความผิดพลาดเรื่องของ Version และตรวจสอบย้อนหลังได้)
- Arduino IDE Version 1.8.7
- WiFiManager Version 0.14.0
- Blynk Version 0.5.4
- ArduinoJson Version 5.13.3
- uRTCLib By Naguissa Version 6.2.4
- New-LiquidCrystal-master Version 6.2.4
- PZEM-004T-v30-master
เอาเป็นว่า ข้อ 2 - 7 มีให้ Download ครับ - ESP8266Scheduler https://drive.google.com/file/d/1Rx-S8AXVycXHkHUely-kQKZ0nvagssS3/view?usp=sharing
ต่อไปมากล่าวถึงคุณลักษณะของ Proj นี้กันบ้าง ว่าทำอะไรได้บ้าง
0. Code ที่เขียนไว้คิดค่าไฟ และค่า Ft เป็นของการไฟฟ้าส่วนภูมิภาค
*** 1.2 อัตราปกติปริมาณการใช้พลังงานไฟฟ้าเกินกว่า 150 หน่วยต่อเดือน*** ส่วนของท่านใดที่ไม่ใช่แบบผมก็ประยุกต์จาก Project ผมได้ครับ
- ดูค่า พารามิเตอร์ ของ PZEM-004T-v30 ตามที่มันระบุไว้ได้ เช่น แรงดันไฟฟ้า กระแสไฟฟ้า ความถี่ไฟฟ้า วัตต์ กิโลวัตต์/ชั่วโมง (โดยค่านี้จะเก็บไว้ที่ตัว PZEM-004T-v30 เลย ไม่ต้องกลัวว่าไฟดับแล้ว ค่า กิโลวัตต์/ชั่วโมง จะหาย ถ้าต้องการ ให้ค่ามันเป็น 0 ก็ เขียน Code reset เอา ) ค่า Power Factor
- ดูค่าไฟเป็น เงิน บาท/เดือน ได้เลย แบบ Real time โดย + ค่าบริการและภาษี 7% แล้ว
- สามารถตั้งค่า ft /เดือน เอง ได้ โดย กดปุ่มที่ Ft/M ที่ Blynk เพื่อ Link เข้า Web ที่แสดงค่า Ft ในช่วงต่างของปี โดยการไฟฟ้า จะออกมาเป็นช่วง ๆ เช่น มกราคม – เมษายน 2563 ** Ft ขายปลีก = -11.60 สตางค์ ก็ = -0.116 บาท
Link : http://www.erc.or.th/ERCWeb2/Front/StaticPage/StaticPage.aspx?p=186&Tag=ค่าไฟฟ้าโดยอัตโนมัติ%2
Link นี้ผมทำไว้เพื่อสะดวกเวลาเปิดหน้า Web ด้วย Blynk ก็จะเห็นค่าตัวเลข ให้เราเอามาป้อนเพื่อกำหนดค่า Ft ได้ เลย เพราะโดยปกติการไฟฟ้า จะออกมาเป็นไฟล์ .PDF ทำให้ไม่สะดวกเป็นอย่างมาก
- ตรวจสอบค่าไฟฟ้าย้อนหลังได้ จากการไฟฟ้าส่วนภูมิภาค โดยกดปุ่ม Bill/M เพื่อ Link เข้า Web ที่แสดงเป็นการแสดงค่าใช้จ่าย ย้อนหลัง ประมาณ 6-7 เดือน โดยเราต้องป้อน หมายเลขผู้ใช้ไฟ้า และรหัสเครื่องวัด เข้าไป ระบบจึงจะแสดงกราฟออกมา
Link : https://www.pea.co.th/e-service/สอบถามประวัติการใช้ไฟ
5. ดูอัตราการคิดค่าไฟฟ้าได้ โดยกดปุ่ม Rate/M เพื่อ Link เข้า Web ที่แสดง อัตราค่าไฟฟ้า ประเภทที่ 1 บ้านอยู่อาศัย เพื่อสะดวกในการดูข้อมูล
Link : https://webcache.googleusercontent.com/search?q=cache:hrvodg5Q4EUJ:https://www.pea.co.th/Portals/0/Document/Rate2015Update.pdf+&cd=3&hl=th&ct=clnk&gl=th
*** หมายเหตุ เป็น web cache***
-
สามารถกำหนดค่า Ft จาก Blynk เข้าไปเก็บใน EEPROM ของ ESP8266 ได้ ดังนั้นจึงไม่ต้องกังวลว่า กรณี ESP8266 ไม่สามารถ เชื่อม WiFi Internet +Blynk Server ได้แล้ว เรายังสามารถดูค่าจริง จาก จอ LCD ได้ โดยมีข้อแม้ว่า ทุกครั้งที่มีการเปลี่ยนค่า Ft จะต้องมีการป้อนค่าจาก Blynk เสมอ
-
สามารถกำหนดค่า วันที่ ชั่วโมง นาที ในการตัดบิลค่าไฟฟ้า ประจำเดือน จาก Blynk เข้าไปเก็บใน EEPROM ของ ESP8266 ได้ ดังนั้นจึงไม่ต้องกังวลว่า กรณี ESP8266 ไม่สามารถ เชื่อม WiFi Internet +Blynk Server ได้แล้ว เรายังสามารถดูค่าจริง จาก จอ LCD ได้ โดยมีข้อแม้ว่า ทุกครั้งที่มีการเปลี่ยนค่า วันที่ ชั่วโมง นาที จะต้องมีการป้อนค่าจาก Blynk เสมอ และเมื่อถึงวันเวลาดังกล่าว ที่เรากำหนดไว้ ระบบจะทำการส่ง Email แจ้งค่าไฟมาให้เราในแต่ละเดือน พร้อมทั้ง Reset ค่า kWh ให้เราอัตโนมัติ
-
สามารถ Reset ค่า kWh โดย การกดปุ่มที่เครื่อง ค้างไว้ 5 วินาที หรือ กดปุ่ม Reset ค่า kWh จาก Blynk ก็ได้ หรือ Reset แบบ Auto ตามข้อที่ 7
-
มีกราฟแสดง ค่าที่เราสนใจ เช่น Watt kWh ค่าไฟฟ้า แรงดัน กระแส อันนี้ท่านที่เคยใช้งาน blynk ทำได้อยู่แล้ว
-
ดูค่า พารามิเตอร์ แบบ real time ทั้ง Online (ดูจาก Blynk) หรือ Offline (จอ LCD )ก็ได้
PZEM Project Qr CODE clone
พักก่อนครับ…19.02 03-03-2563
ต่อครับ 09.41 03-03-2563
Code Final ครับ (ใน Code ผมอธิบายการทำงานบางส่วนเอาไว้แล้ว)
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>
#include <FS.h>
#include <DNSServer.h>
#include <ArduinoJson.h>
#define BLYNK_MAX_SENDBYTES 1200
#include <BlynkSimpleEsp8266.h>
#include <EEPROM.h>
//------------------------------ การกำหนดค่าในส่วนของ Blynk ------------------------------------------------//
#define BLYNK_DEBUG
#define BLYNK_PRINT Serial
int blynkIsDownCount = 0;
char blynk_token[34] = "8dwBaSBOE8htLFrK37JPAYB1hm8TaQkU";//ใส่ Blynk_token ของเราที่ Blynk ส่งมาทาง Email ตอน Create Project ใหม่
BlynkTimer timer;
//---------------------------------- กำหนดหมายเลขของขาของ Node MCU ESP 8266 --------------------------------------------//
#define D0 16 // ใช้ไฟ LED สีฟ้า ของบอร์ด MCU ESP8266 ให้มีสัญญาณไฟกระพริบ ตาม Code ที่เขียน
#define D3 0 // ใช้เป็นปุ่มกด เพื่อเข้า AP Config ได้ตามความต้องการของผู้ใช้
//------------------------------------------------------------------------------------------------------------------------//
#include <Scheduler.h>
// ------------------------โหลดไลบารี่ของจอ LCD มาใช้งาน โดยแบบนี้จะสามารถ Create Characterได้ ---------------------------------//
#include <LCD.h> // บรรทัดที่ 1 และ 2 สามารถสลับบรรทัดกันได้
#include <Wire.h> // บรรทัดที่ 1 และ 2 สามารถสลับบรรทัดกันได้
#include <LiquidCrystal_I2C.h> //บรรทัดนี้ต้องอยู่ในบรรทัดที่ 3 เท่านั้น ถ้าไปอยู่บรรทัดที่ 1 และ 2 จะคอมไพล์ไม่ผ่าน
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); //// ตั้งค่า Address ของอุปกรณ์จอ LCD ที่มีการเชื่อมต่อแบบ I2C
//------------------------------------------------------------------------------------------------------------------------//
bool shouldSaveConfig = false;
//callback notifying us of the need to save config
void saveConfigCallback () {
Serial.println("Should save config");
shouldSaveConfig = true;
}
//------------------------------------------------------------------------------------------------------------------------//
//-------------สำหรับ Server local ที่แจกให้ เพิ่ม **** แค่ 2 บรรทัดนี้-------------- (ถ้าเป็น Blynk Server ปกติไม่ต้องใส่) ----------//
char server[] = "oasiskit.com";
int port = 8080;
//------------------------------------------------------------------------------------------------------------------------//
#include <PZEM004Tv30.h>
PZEM004Tv30 pzem(12, 13); // 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;
//ตัวแปรรับค่า ค่าไฟประเดือน
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 วินาที
//RTC Library
#include "Arduino.h"
#include "Wire.h"
#include "uRTCLib.h"
// uRTCLib rtc;
uRTCLib rtc(0x68);
//ชุดกำหนดการส่ง Email แค่ครั้งเดียว
int Email_status = 0;
int Email_status1 = 0;
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(6, 3);
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(0, 2);
lcd.print(" Day: ");
lcd.setCursor(10, 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(0, 2);
lcd.print(" Hour: ");
lcd.setCursor(10, 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_H2 ที่เป็น Float ลงใน Address 0
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(0, 0);
lcd.print(" Sync Auto Rst ");
lcd.setCursor(0, 1);
lcd.print(" By Minute ");
lcd.setCursor(0, 3);
lcd.print(" Minute: ");
lcd.setCursor(10, 3);
lcd.print(Rst_M, 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 Server
class Task_1 : public Task {
protected:
void setup() { }
void loop() {
//-----------------------------------------------------------------------------------------------------------//
if (Blynk.connected())
{
Blynk.run();
digitalWrite(D0, LOW);
} else {
digitalWrite(D0, LOW);
delay(200);
digitalWrite(D0, HIGH);
delay(100);
}
//-----------------------------------------------------------------------------------------------------------//
timer.run();//ให้เวลาของ Blynk ทำงาน
delay(500);
}
} Task_1_task;
//แสดงค่า ต่างๆ ของ PZEM ออกมา
class Task_2 : public Task {
protected:
void setup() { }
void loop() {
float voltage = pzem.voltage();
if (voltage != NAN) {
//Serial.print("Voltage: "); Serial.print(voltage); Serial.println("V");
lcd.setCursor(1, 0);
lcd.print(voltage, 0);
lcd.setCursor(4, 0);
lcd.print("Vac");
Blynk.virtualWrite(V1, voltage);
} else {
}
float current = pzem.current();
if (current != NAN) {
//Serial.print("Current: "); Serial.print(current); Serial.println("A");
lcd.setCursor(13, 0);
lcd.print(current, 2);
lcd.print(" A");
Blynk.virtualWrite(V2, current);
} else {
}
float power = pzem.power();
if (current != NAN) {
lcd.setCursor(0, 1);
lcd.print(power, 2);
lcd.setCursor(8, 1);
lcd.print("W");
Blynk.virtualWrite(V3, power);
} else {
}
float energy = pzem.energy();
if (current != NAN) {
lcd.setCursor(10, 1);
lcd.print(energy, 2);
lcd.print(" kWh");
Blynk.virtualWrite(V4, energy);
} else {
}
float frequency = pzem.frequency();
if (current != NAN) {
lcd.setCursor(8, 0);
lcd.print(frequency, 0);
lcd.setCursor(10, 0);
lcd.print("Hz");
Blynk.virtualWrite(V5, frequency);
} else {
}
float pf = pzem.pf();
if (current != NAN) {
Blynk.virtualWrite(V6, pf);
} else {
}
delay(4000);
}//loop
} Task_2_task;
//คิดค่าไฟฟ้า ตามการใช้งานที่บ้าน ของเรามากกว่า 150 หน่วย/เดือน ใครน้อยกว่านี้ก็คิดสูตรเอง
class Task_3 : public Task {
protected:
void setup() { }
void loop() {
float energy = pzem.energy();
// กดปุ่มที่หน้าเครื่อง 5 วินาที เพื่อ Reset kWh
if (digitalRead(D3) == LOW) {
delay(3000);
pzem.resetEnergy();
}
// กดปุ่มจาก Blynk 5 วินาที เพื่อ Reset kWh กดค้างจนกว่า LED จะดับ
if (Blynkreset_kWh == 1) {
led_rst_kWh.on();
delay(3000);
pzem.resetEnergy();
led_rst_kWh.off();
pzem.resetEnergy();
}
if (Blynkreset_kWh == 0) {
led_rst_kWh.off();
}
// Reset kWh แบบ Auto โดยการตั้งค่ามาจาก Blynk โดยเก็บไว้ใน EEPROM ของเครื่อง
// ส่ง Email 1 ครั้งเท่านั้น
if (Rst_D == rtc.day() && Rst_H == rtc.hour() && Rst_M == rtc.minute() && Email_status == 0) {
pzem.resetEnergy();
//Serial.println("reset kWh");มันจะ Reset ซ้ำ กันใน 1 นาทีนี้ และยกเลิกจนกว่าจะขึ้นนาทีใหม่
String body = String("ค่าไฟฟ้าประจำเดือนที่ ") + (rtc.month() - 1) + String(" เป็นจำนวนเงิน ") + Electric_bill + String(" บาท ระบบทำการ Reset kWh = 0 แล้ว ***ให้ตรวจสอบค่า Ft ประจำเดือนด้วย*** By PUYIOT");
Blynk.email("xxxxxxxxxx@gmail.com", "แจ้งค่าไฟฟ้าประจำเดือน ", body);
delay(500);
Email_status = 1;
Email_status1 = 0;
}
else if (Rst_D == rtc.day() && Rst_H == rtc.hour() && Rst_M == rtc.minute() && Email_status == 1) {
delay(10);
Email_status1 = 1;
}
if (Rst_M != rtc.minute() && Email_status1 == 1 ) {
delay(10);
Email_status = 0;
}
//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);
lcd.setCursor(0, 3);
lcd.print("B/M: ");
lcd.setCursor(5, 3);
lcd.print(Electric_bill , 2);
lcd.setCursor(12, 3);
//lcd.print("Bath");
Blynk.virtualWrite(V7, Electric_bill);
lcd.setCursor(13, 3);
lcd.print(Rst_D, 0);
//lcd.print("D");
lcd.setCursor(15, 3);
lcd.print(Rst_H, 0);
lcd.setCursor(17, 3);
lcd.print(":");
//lcd.print("H");
lcd.setCursor(18, 3);
lcd.print(Rst_M, 0);
delay(2000);
}//loop
} Task_3_task;
//แสดง dd:mm:yy hh:mm
class Task_4 : public Task {
protected:
void setup() { }
void loop() {
rtc.refresh();
int year_ = rtc.year() + 43; //+43 เพื่อให้ได้ปี พ.ศ. 63
lcd.setCursor(0, 2);
//เติม 0 กรณีเป็นเลข วัน เดือน ชม. นาที วินาที ตัวเดียว
if (rtc.day() < 10)
{
lcd.print("0");
lcd.print(rtc.day());
}
else lcd.print(rtc.day());
lcd.print('-');
if (rtc.month() < 10)
{
lcd.print("0");
lcd.print(rtc.month());
}
else lcd.print(rtc.month());
lcd.print('-');
lcd.print(year_);
lcd.setCursor(12, 2);
if (rtc.hour() < 10)
{
lcd.print("0");
lcd.print(rtc.hour());
}
else lcd.print(rtc.hour());
lcd.print(':');
if (rtc.minute() < 10)
{
lcd.print("0");
lcd.print(rtc.minute());
}
else lcd.print(rtc.minute());
lcd.print(':');
if (rtc.second() < 10)
{
lcd.print("0");
lcd.print(rtc.second());
}
else lcd.print(rtc.second());
delay(1000);
}
} Task_4_task;
//------------------------------------------------------------------------------------------------------------------------//
//********************************************* void setup **************************************************//
//------------------------------------------------------------------------------------------------------------------------//
void setup() {
//-------IO NODE MCU Esp8266-------//
pinMode(D0, OUTPUT); //กำหนดโหมดใช้งานให้กับขา D0 เป็นขา สัญญาณไฟ ในสภาวะต่างๆ
pinMode(D3, INPUT_PULLUP);//กำหนดโหมดใช้งานให้กับขา D3 เป็นขา กดปุ่ม ค้าง เพื่อตั้งค่า AP config
// ให้ LED ทั้งหมดดับก่อน
digitalWrite(D0, LOW);//ให้หลอด LED สีฟ้าดับก่อน
//-------------------------------//
Serial.begin(115200);
//-------------------------------//
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);
lcd.begin(20, 4);
lcd.clear();
#ifdef ARDUINO_ARCH_ESP8266
Wire.begin(4, 5); // GPIO4 = D2 and GPIO5 = D1 on ESP8266
#else
Wire.begin();
#endif
//rtc.set(0, 46, 11, 3, 3, 3, 20);//ใช้เฉพาะตั้งเวลา ถ้าจะตั้งก็ เอา // ออก เมื่อตั้งได้ตรงแล้วก็เอา // ใส่กลับไปเหมือนเดิม
// RTCLib::set(byte second, byte minute, byte hour, byte dayOfWeek, byte dayOfMonth, byte month, byte year)
//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"]);
} else {
Serial.println("failed to load json config");//แสดงข้อความใน Serial Monitor
}
}
}
} else {
Serial.println("failed to mount FS");//แสดงข้อความใน Serial Monitor
}
//end read
//************************** AP AUTO CONNECT ********************************************//
WiFiManagerParameter custom_blynk_token("blynk", "blynk token", blynk_token, 34);
//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_blynk_token);
for (int i = 5; i > -1; i--) { // นับเวลาถอยหลัง 5 วินาทีก่อนกดปุ่ม AP Config
digitalWrite(D0, HIGH);
delay(500);
digitalWrite(D0, LOW);
delay(500);
Serial.print (String(i) + " ");//แสดงข้อความใน Serial Monitor
}
if (digitalRead(D3) == LOW) {
digitalWrite(D0, LOW);
Serial.println("Button Pressed");//แสดงข้อความใน Serial Monitor
wifiManager.resetSettings();//ให้ล้างค่า SSID และ Password ที่เคยบันทึกไว้
// wifiManager.autoConnect(); ใช้สร้างชื่อแอคเซสพอยต์อันโนมัติจาก ESP + ChipID
if (!wifiManager.autoConnect("PUYIOT AP CONFIG")) {
Serial.println("failed to connect and hit timeout");//แสดงข้อความใน Serial Monitor
delay(3000);
//reset and try again, or maybe put it to deep sleep
ESP.reset();
delay(5000);
}
}
Serial.println("Connected.......OK!)");//แสดงข้อความใน Serial Monitor
strcpy(blynk_token, custom_blynk_token.getValue());
//save the custom parameters to FS
if (shouldSaveConfig) {
Serial.println("saving config");//แสดงข้อความใน Serial Monitor
DynamicJsonBuffer jsonBuffer;
JsonObject& json = jsonBuffer.createObject();
json["blynk_token"] = blynk_token;
File configFile = SPIFFS.open("/config.json", "w");
if (!configFile) {
Serial.println("failed to open config file for writing");//แสดงข้อความใน Serial Monitor
}
json.printTo(Serial);
json.printTo(configFile);
configFile.close();
//end save
}
//************************** จบ AP AUTO CONNECT *****************************************//
Serial.println("local ip"); //แสดงข้อความใน Serial Monitor
delay(100);
Serial.println(WiFi.localIP());//แสดงข้อความใน Serial Monitor
Serial.println("gateway");
delay(100);
Serial.println(WiFi.gatewayIP());
Serial.println("subnetMask");
delay(100);
Serial.println(WiFi.subnetMask());
Serial.println("SSID");
delay(100);
Serial.println(WiFi.SSID());
Serial.println("Password");
delay(100);
Serial.println(WiFi.psk());
// Blynk.config(blynk_token);////เริ่มการเชื่อมต่อ Blynk Server แบบปกติ
Blynk.config(blynk_token, server, port);
////เริ่มการเชื่อมต่อ Blynk Server*********สำหรับ Server local ที่แจกให้ เพิ่ม, server, port แค่นี้จบ
timer.setInterval(30000L, reconnecting); //Function reconnect
Scheduler.start(&Task_1_task);
Scheduler.start(&Task_2_task);
Scheduler.start(&Task_3_task);
Scheduler.start(&Task_4_task);
Scheduler.begin();
}
//------------------------------------------------------------------------------------------------------------------------//
//********************************************* จบ void setup **************************************************//
//------------------------------------------------------------------------------------------------------------------------//
//------------------------------------------------------------------------------------------------------------------------//
//********************************************* void Loop ***************************************************//
//------------------------------------------------------------------------------------------------------------------------//
void loop() {
}
//------------------------------------------------------------------------------------------------------------------------//
//********************************************* จบ void Loop **************************************************//
//------------------------------------------------------------------------------------------------------------------------//
//------------------------------------------------------------------------------------------------------------------------//
void reconnecting()
{
if (!Blynk.connected())
{
blynkIsDownCount++;
BLYNK_LOG("blynk server is down! %d times", blynkIsDownCount);
Blynk.connect(5000);
}
}
BLYNK_CONNECTED()
{
Blynk.syncAll();//ให้ซิงค์ข้อมูลทั้งหมดล่าสุดจาก Blynk Server
}
มุ่งหวังให้คนไทย พัฒนา และสร้างนวัตกรรม IOT ใหม่ หรือจากข้อมูลเดิมที่มีอยู่แล้ว นำมาใช้ให้เกิดประโยชน์สูงกับตัวเอง และสังคม และก้าวต่อไปยังการทำ Product ด้วยฝีมือคนไทย ขอให้มีความสุขกับการทำงานนะครับ