/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
#define BLYNK_TEMPLATE_ID "TMPL6IUcBQsZM"
#define BLYNK_TEMPLATE_NAME "Power monitor"
#define BLYNK_AUTH_TOKEN "WD-xAKuudBF6rwLhK5T23JMBvoyGtMi-"
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
#include <PZEM004Tv30.h>
/********************************
****** WiFi Credentials *********
********************************/
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "Wokwi-GUEST";
char pass[] = "";
#define DEBUG 1 // Set Debug level 0-1 to prints result on serial monitor (Set it to 0 when you don't need serial prints)
#if DEBUG == 1
#define debug(x) Serial.print(x)
#define debugln(x) Serial.println(x)
#else
#define debug(x)
#define debugln(x)
#endif
BlynkTimer timer;
// Defining Virtual pins for each reading
#define voltage_virtual_pin V0 // Virtual pin for voltage
#define current_virtual_pin V1 // Virtual pin for Current
#define power_virtual_pin V2 // Virtual pin for Power
#define energy_virtual_pin V3 // Virtual pin for Energy
#define frequency_virtual_pin V4 // Virtual pin for Frequency
#define pf_virtual_pin V5 // Virtual pin for Power factor
#define wire1LED_virtual_pin V6 // Virtual pin for LED to indicate Wire 1 status
#define wire2LED_virtual_pin V7 // Virtual pin for LED to indicate Wire 2 status
#define electo_virtual_pin V8 // Electromagnet virtual pin
bool wire1InContact = true; // Flag to change if wire 1 was cut
bool wire2InContact = true; // Flag to change if wire 2 was cut
bool electroUnlocked = false; // Flag to be set when electro magnet was unlocked
unsigned long unlockTime = 0; // Variable to hold unlock time when electro magnet was unlocked
unsigned long totalUnlockTime = 1000; // Total Signal duration for electro magent unlock in milliseconds
WidgetLED ledWire1(wire1LED_virtual_pin); // Creating an LED widget for wire 1
WidgetLED ledWire2(wire2LED_virtual_pin); // Creating an LED widget for wire 1
bool relayLogic = false; // Relay working logic you can set it to true/false
// Defining Wire Pins and relay pins for siren, light and electromagnet
const byte sirenRelay = 15; // Siren Relay pin on esp32
const byte lightRelay = 2; // Light Relay pin on esp32
const byte electroRelay = 4; // Electromagnet relay pin
const byte wire1Pin = 18; // Wire 1 pin needs to be in loop with Ground
const byte wire2Pin = 19; // Wire 2 pin needs to be in loop with Ground
PZEM004Tv30 pzem(Serial2, 16, 17);
// This function will be called when you press the open electromagnet button
BLYNK_WRITE(electo_virtual_pin) {
int pinValue = param.asInt(); // assigning incoming value from pin V1 to a variable
digitalWrite(electroRelay, relayLogic); // Unlock Electromagnet
unlockTime = millis(); // Note current time when electro magnet was unlocked
electroUnlocked = true; // Set the electromagnet unlock flag
}
void resetElectroMagnet() {
if ((millis() - unlockTime) > totalUnlockTime && electroUnlocked) {
electroUnlocked = false; // Reset the flag
digitalWrite(electroRelay, !relayLogic); // Reset Electromagnet relay signal
Blynk.virtualWrite(electo_virtual_pin, 0); // Reset Button state
}
}
void checkWireCut() {
if (digitalRead(wire1Pin) == HIGH && wire1InContact) { // Check if wire 1 signal get's high
debugln("Wire 1 Cut");
wire1InContact = false; // Reset wire 1 in contact flag to indicate wire cut
ledWire1.off(); // Turn on Wire 1 led ON
digitalWrite(sirenRelay, relayLogic); // Turn on siren
digitalWrite(lightRelay, relayLogic); // Turn on Light
}
if (digitalRead(wire2Pin) == HIGH && wire2InContact) { // Check if wire 2 signal get's high
debugln("Wire 2 Cut");
wire2InContact = false; // Reset wire 2 in contact flag to indicate wire cut
ledWire2.off(); // Turn on Wire 2 led ON
digitalWrite(sirenRelay, relayLogic); // Turn on siren
digitalWrite(lightRelay, relayLogic); // Turn on Light
}
}
// This function sends Arduino's up time every second to Virtual Pin (5)
void readSendPower() { // Read and send power values
// 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();
// Check if the data is valid
if (isnan(voltage)) {
voltage = 0; // Set voltage to 0
}
if (isnan(current)) {
current = 0; // Set current to 0
}
if (isnan(power)) {
power = 0; // Set power to 0
}
if (isnan(energy)) {
energy = 0; // Set energy to 0
}
if (isnan(frequency)) {
frequency = 0; // Set frequency to 0
}
if (isnan(pf)) {
pf = 0; // Set power factor to 0
}
// Print the values to the Serial console if debug is enabled
debug("Voltage: ");
debug(voltage);
debugln("V");
debug("Current: ");
debug(current);
debugln("A");
debug("Power: ");
debug(power);
debugln("W");
debug("Energy: ");
debug(energy);
debugln("kWh");
debug("Frequency: ");
debug(frequency);
debugln("Hz");
debug("PF: ");
debugln(pf);
debugln();
// You can send any value at any time.
// Please don't send more that 10 values per second.
Blynk.virtualWrite(voltage_virtual_pin, voltage);
Blynk.virtualWrite(current_virtual_pin, current);
Blynk.virtualWrite(power_virtual_pin, power);
Blynk.virtualWrite(energy_virtual_pin, energy);
Blynk.virtualWrite(frequency_virtual_pin, frequency);
Blynk.virtualWrite(pf_virtual_pin, pf);
}
BLYNK_CONNECTED() {
// Synchronize time on connection
ledWire1.on(); // Turn on Wire 2 led ON
ledWire2.on(); // Turn on Wire 2 led ON
Blynk.virtualWrite(electo_virtual_pin, 0); // Reset Button state
}
void setup() {
/* Debugging serial */
Serial.begin(115200);
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
// Initially set relay pins as output and turn them off
pinMode(sirenRelay, OUTPUT); // Set pin as output
pinMode(lightRelay, OUTPUT); // Set pin as output
pinMode(electroRelay, OUTPUT); // Set pin as output
digitalWrite(sirenRelay, !relayLogic); // Initially turn off relay
digitalWrite(lightRelay, !relayLogic); // Initially turn off relay
digitalWrite(electroRelay, !relayLogic); // Initially turn off relay
// Set wire pins as input with pull up
pinMode(wire1Pin, INPUT_PULLUP); // Set wire pin as input with pull up
pinMode(wire2Pin, INPUT_PULLUP); // Set wire pin as input with pull up
// pzem.resetEnergy(); // Uncomment this line to reset energy consumption
// Setup a function to be called every second
timer.setInterval(2000L, readSendPower); // Call Read Energy Meter Every 2 second
timer.setInterval(200L, checkWireCut); // Call Check for Wire Cut
timer.setInterval(1000L, resetElectroMagnet); // Check for electromagnet to rest it back if unlocked
}
void loop() {
Blynk.run();
timer.run();
}