pleasedontcode

# AC Monitoring rev_01

Jan 14th, 2026
28
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Arduino 11.75 KB | None | 0 0
  1. /********* Pleasedontcode.com **********
  2.  
  3.     Pleasedontcode thanks you for automatic code generation! Enjoy your code!
  4.  
  5.     - Terms and Conditions:
  6.     You have a non-exclusive, revocable, worldwide, royalty-free license
  7.     for personal and commercial use. Attribution is optional; modifications
  8.     are allowed, but you're responsible for code maintenance. We're not
  9.     liable for any loss or damage. For full terms,
  10.     please visit pleasedontcode.com/termsandconditions.
  11.  
  12.     - Project: # AC Monitoring
  13.     - Source Code NOT compiled for: ESP32 DevKit V1
  14.     - Source Code created on: 2026-01-14 18:20:41
  15.  
  16. ********* Pleasedontcode.com **********/
  17.  
  18. /****** SYSTEM REQUIREMENTS *****/
  19. /****** SYSTEM REQUIREMENT 1 *****/
  20.     /* Monitor AC voltage, current, and power consumption */
  21.     /* in real-time using PZEM-004T-v30 energy meter */
  22.     /* module with ESP32 DevKit V1 for IoT energy */
  23.     /* tracking applications. */
  24. /****** END SYSTEM REQUIREMENTS *****/
  25.  
  26.  
  27. /****** DEFINITION OF LIBRARIES *****/
  28. #include <PZEM004Tv30.h>    // https://github.com/mandulaj/PZEM-004T-v30
  29.  
  30. /****** HARDWARE CONFIGURATION *****/
  31. // PZEM-004T-v30 Serial Communication Pins (ESP32 Serial2)
  32. #define PZEM_RX_PIN 16      // GPIO16 - Receive pin for PZEM module
  33. #define PZEM_TX_PIN 17      // GPIO17 - Transmit pin for PZEM module
  34. #define PZEM_ADDR 0xF8      // Default PZEM module address (0xF8)
  35. #define PZEM_BAUD 9600      // Baud rate for PZEM communication
  36.  
  37. // Serial Communication for Debug Output
  38. #define DEBUG_BAUD 115200   // Baud rate for Serial Monitor output
  39.  
  40. // Timing Configuration
  41. #define READING_INTERVAL 2000    // Interval to read PZEM data (milliseconds)
  42. #define SERIAL_PRINT_INTERVAL 2000  // Interval to print data to Serial (milliseconds)
  43.  
  44. /****** SENSOR THRESHOLDS AND LIMITS *****/
  45. // Over/Under Voltage Detection
  46. #define VOLTAGE_THRESHOLD_HIGH 260  // Over-voltage threshold (V)
  47. #define VOLTAGE_THRESHOLD_LOW 180   // Under-voltage threshold (V)
  48. #define VOLTAGE_MIN_ACTIVE 5.0      // Minimum voltage to consider mains present (V)
  49.  
  50. // Over-Current Detection
  51. #define CURRENT_THRESHOLD_HIGH 25   // Over-current threshold (A)
  52.  
  53. // Power Measurement
  54. #define POWER_INVALID_THRESHOLD 350 // Invalid voltage threshold for safety (V)
  55.  
  56. /****** FUNCTION PROTOTYPES *****/
  57. void setup(void);
  58. void loop(void);
  59. void initializeSerialCommunication(void);
  60. void initializePZEMModule(void);
  61. void readPZEMData(void);
  62. void displayEnergyMetrics(void);
  63. void checkAlarmConditions(void);
  64. void handleOverVoltageAlarm(void);
  65. void handleUnderVoltageAlarm(void);
  66. void handleOverCurrentAlarm(void);
  67. void checkMainsPresence(void);
  68.  
  69. /****** DEFINITION OF PZEM CLASS INSTANCES *****/
  70. // Create PZEM004Tv30 instance for ESP32 with hardware Serial2
  71. PZEM004Tv30 pzem(Serial2, PZEM_RX_PIN, PZEM_TX_PIN, PZEM_ADDR);
  72.  
  73. /****** GLOBAL VARIABLES FOR SENSOR DATA *****/
  74. // Voltage measurement (V)
  75. float voltage = 0.0;
  76.  
  77. // Current measurement (A)
  78. float current = 0.0;
  79.  
  80. // Power measurement (W)
  81. float power = 0.0;
  82.  
  83. // Energy measurement (kWh)
  84. float energy = 0.0;
  85.  
  86. // Frequency measurement (Hz)
  87. float frequency = 0.0;
  88.  
  89. // Power Factor (0.00 to 1.00)
  90. float powerFactor = 0.0;
  91.  
  92. /****** GLOBAL VARIABLES FOR STATE MANAGEMENT *****/
  93. // Tracks if over-voltage alarm has been reported
  94. bool alarmOverVoltageActive = false;
  95.  
  96. // Tracks if under-voltage alarm has been reported
  97. bool alarmUnderVoltageActive = false;
  98.  
  99. // Tracks if over-current alarm has been reported
  100. bool alarmOverCurrentActive = false;
  101.  
  102. // Tracks whether mains is detected (voltage present)
  103. bool mainsPresent = false;
  104.  
  105. // Previous mains state for edge detection
  106. bool previousMainsState = false;
  107.  
  108. /****** GLOBAL VARIABLES FOR TIMING *****/
  109. // Timestamp of last PZEM data reading
  110. unsigned long lastReadTime = 0;
  111.  
  112. // Timestamp of last serial print
  113. unsigned long lastPrintTime = 0;
  114.  
  115. /****** SETUP FUNCTION *****/
  116. void setup(void)
  117. {
  118.     // Initialize serial communication for debug output
  119.     initializeSerialCommunication();
  120.    
  121.     // Initialize PZEM-004T-v30 module
  122.     initializePZEMModule();
  123.    
  124.     // Print startup message
  125.     Serial.println("\n=====================================");
  126.     Serial.println("   PZEM-004T-v30 Energy Monitor");
  127.     Serial.println("   ESP32 DevKit V1");
  128.     Serial.println("   Real-time AC Energy Tracking");
  129.     Serial.println("=====================================\n");
  130.    
  131.     // Initialize timing variables
  132.     lastReadTime = millis();
  133.     lastPrintTime = millis();
  134. }
  135.  
  136. /****** MAIN LOOP FUNCTION *****/
  137. void loop(void)
  138. {
  139.     unsigned long currentTime = millis();
  140.    
  141.     // Read PZEM sensor data at specified interval
  142.     if (currentTime - lastReadTime >= READING_INTERVAL)
  143.     {
  144.         readPZEMData();
  145.         checkMainsPresence();
  146.         checkAlarmConditions();
  147.         lastReadTime = currentTime;
  148.     }
  149.    
  150.     // Display energy metrics at specified interval
  151.     if (currentTime - lastPrintTime >= SERIAL_PRINT_INTERVAL)
  152.     {
  153.         displayEnergyMetrics();
  154.         lastPrintTime = currentTime;
  155.     }
  156. }
  157.  
  158. /****** FUNCTION IMPLEMENTATIONS *****/
  159.  
  160. // Initialize Serial communication for debug output to Serial Monitor
  161. void initializeSerialCommunication(void)
  162. {
  163.     // Configure Serial0 for debug output at 115200 baud
  164.     Serial.begin(DEBUG_BAUD);
  165.    
  166.     // Brief delay to stabilize serial connection
  167.     delay(1000);
  168. }
  169.  
  170. // Initialize PZEM-004T-v30 module with hardware Serial2
  171. void initializePZEMModule(void)
  172. {
  173.     Serial.println("Initializing PZEM-004T-v30 Energy Meter Module...");
  174.     Serial.print("RX Pin: GPIO");
  175.     Serial.print(PZEM_RX_PIN);
  176.     Serial.print(" | TX Pin: GPIO");
  177.     Serial.println(PZEM_TX_PIN);
  178.     Serial.print("Module Address: 0x");
  179.     Serial.print(PZEM_ADDR, HEX);
  180.     Serial.print(" | Baud Rate: ");
  181.     Serial.print(PZEM_BAUD);
  182.     Serial.println(" bps");
  183.     Serial.println("Waiting for first data reading...\n");
  184.    
  185.     // Delay to allow module initialization
  186.     delay(2000);
  187. }
  188.  
  189. // Read all measurements from PZEM-004T-v30 module
  190. void readPZEMData(void)
  191. {
  192.     // Read voltage from PZEM module (V)
  193.     voltage = pzem.voltage();
  194.    
  195.     // Read current from PZEM module (A)
  196.     current = pzem.current();
  197.    
  198.     // Read active power from PZEM module (W)
  199.     power = pzem.power();
  200.    
  201.     // Read accumulated energy from PZEM module (kWh)
  202.     energy = pzem.energy();
  203.    
  204.     // Read mains frequency from PZEM module (Hz)
  205.     frequency = pzem.frequency();
  206.    
  207.     // Read power factor from PZEM module (0.00 to 1.00)
  208.     powerFactor = pzem.pf();
  209. }
  210.  
  211. // Display all energy metrics to Serial Monitor
  212. void displayEnergyMetrics(void)
  213. {
  214.     Serial.println("========== ENERGY MONITORING DATA ==========");
  215.    
  216.     // Display voltage reading with validation
  217.     Serial.print("Voltage: ");
  218.     if (isnan(voltage))
  219.     {
  220.         Serial.println("ERROR (NaN)");
  221.     }
  222.     else
  223.     {
  224.         Serial.print(voltage, 2);
  225.         Serial.println(" V");
  226.     }
  227.    
  228.     // Display current reading with validation
  229.     Serial.print("Current: ");
  230.     if (isnan(current))
  231.     {
  232.         Serial.println("ERROR (NaN)");
  233.     }
  234.     else
  235.     {
  236.         Serial.print(current, 2);
  237.         Serial.println(" A");
  238.     }
  239.    
  240.     // Display power reading with validation
  241.     Serial.print("Power: ");
  242.     if (isnan(power))
  243.     {
  244.         Serial.println("ERROR (NaN)");
  245.     }
  246.     else
  247.     {
  248.         Serial.print(power, 2);
  249.         Serial.println(" W");
  250.     }
  251.    
  252.     // Display energy reading with validation
  253.     Serial.print("Energy: ");
  254.     if (isnan(energy))
  255.     {
  256.         Serial.println("ERROR (NaN)");
  257.     }
  258.     else
  259.     {
  260.         Serial.print(energy, 3);
  261.         Serial.println(" kWh");
  262.     }
  263.    
  264.     // Display frequency reading with validation
  265.     Serial.print("Frequency: ");
  266.     if (isnan(frequency))
  267.     {
  268.         Serial.println("ERROR (NaN)");
  269.     }
  270.     else
  271.     {
  272.         Serial.print(frequency, 1);
  273.         Serial.println(" Hz");
  274.     }
  275.    
  276.     // Display power factor reading with validation
  277.     Serial.print("Power Factor: ");
  278.     if (isnan(powerFactor))
  279.     {
  280.         Serial.println("ERROR (NaN)");
  281.     }
  282.     else
  283.     {
  284.         Serial.print(powerFactor, 2);
  285.         Serial.println("");
  286.     }
  287.    
  288.     // Display mains presence status
  289.     Serial.print("Mains Status: ");
  290.     if (mainsPresent)
  291.     {
  292.         Serial.println("PRESENT");
  293.     }
  294.     else
  295.     {
  296.         Serial.println("ABSENT");
  297.     }
  298.    
  299.     // Display alarm status indicators
  300.     Serial.print("Alarms: ");
  301.     if (alarmOverVoltageActive || alarmUnderVoltageActive || alarmOverCurrentActive)
  302.     {
  303.         if (alarmOverVoltageActive)
  304.         {
  305.             Serial.print("[OVER-VOLTAGE] ");
  306.         }
  307.         if (alarmUnderVoltageActive)
  308.         {
  309.             Serial.print("[UNDER-VOLTAGE] ");
  310.         }
  311.         if (alarmOverCurrentActive)
  312.         {
  313.             Serial.print("[OVER-CURRENT] ");
  314.         }
  315.         Serial.println("");
  316.     }
  317.     else
  318.     {
  319.         Serial.println("NONE");
  320.     }
  321.    
  322.     Serial.println("==========================================\n");
  323. }
  324.  
  325. // Check all alarm conditions and update alarm states
  326. void checkAlarmConditions(void)
  327. {
  328.     // Only check alarms if mains is present and voltage is valid
  329.     if (!mainsPresent || isnan(voltage) || voltage > POWER_INVALID_THRESHOLD)
  330.     {
  331.         return;
  332.     }
  333.    
  334.     // Check over-voltage condition
  335.     if (voltage > VOLTAGE_THRESHOLD_HIGH && !alarmOverVoltageActive)
  336.     {
  337.         handleOverVoltageAlarm();
  338.     }
  339.     else if (voltage <= VOLTAGE_THRESHOLD_HIGH)
  340.     {
  341.         alarmOverVoltageActive = false;
  342.     }
  343.    
  344.     // Check under-voltage condition
  345.     if (voltage < VOLTAGE_THRESHOLD_LOW && !alarmUnderVoltageActive)
  346.     {
  347.         handleUnderVoltageAlarm();
  348.     }
  349.     else if (voltage >= VOLTAGE_THRESHOLD_LOW)
  350.     {
  351.         alarmUnderVoltageActive = false;
  352.     }
  353.    
  354.     // Check over-current condition
  355.     if (!isnan(current) && current > CURRENT_THRESHOLD_HIGH && !alarmOverCurrentActive)
  356.     {
  357.         handleOverCurrentAlarm();
  358.     }
  359.     else if (isnan(current) || current <= CURRENT_THRESHOLD_HIGH)
  360.     {
  361.         alarmOverCurrentActive = false;
  362.     }
  363. }
  364.  
  365. // Handle over-voltage alarm (voltage exceeds 260V)
  366. void handleOverVoltageAlarm(void)
  367. {
  368.     alarmOverVoltageActive = true;
  369.     Serial.println("\n!!! ALARM: OVER-VOLTAGE !!!");
  370.     Serial.print("Voltage Reading: ");
  371.     Serial.print(voltage, 2);
  372.     Serial.println(" V (Threshold: 260V)");
  373.     Serial.println("Risk: Potential equipment damage");
  374.     Serial.println("Action: Check mains supply quality\n");
  375. }
  376.  
  377. // Handle under-voltage alarm (voltage drops below 180V)
  378. void handleUnderVoltageAlarm(void)
  379. {
  380.     alarmUnderVoltageActive = true;
  381.     Serial.println("\n!!! ALARM: UNDER-VOLTAGE !!!");
  382.     Serial.print("Voltage Reading: ");
  383.     Serial.print(voltage, 2);
  384.     Serial.println(" V (Threshold: 180V)");
  385.     Serial.println("Risk: Equipment may malfunction");
  386.     Serial.println("Action: Check mains supply stability\n");
  387. }
  388.  
  389. // Handle over-current alarm (current exceeds 25A)
  390. void handleOverCurrentAlarm(void)
  391. {
  392.     alarmOverCurrentActive = true;
  393.     Serial.println("\n!!! ALARM: OVER-CURRENT !!!");
  394.     Serial.print("Current Reading: ");
  395.     Serial.print(current, 2);
  396.     Serial.println(" A (Threshold: 25A)");
  397.     Serial.println("Risk: Potential short circuit or overload");
  398.     Serial.println("Action: Check connected load and wiring\n");
  399. }
  400.  
  401. // Check and update mains presence status based on voltage
  402. void checkMainsPresence(void)
  403. {
  404.     // Determine if mains is present based on minimum voltage threshold
  405.     if (!isnan(voltage) && voltage >= VOLTAGE_MIN_ACTIVE)
  406.     {
  407.         mainsPresent = true;
  408.     }
  409.     else
  410.     {
  411.         mainsPresent = false;
  412.     }
  413.    
  414.     // Detect mains state transition
  415.     if (mainsPresent != previousMainsState)
  416.     {
  417.         if (mainsPresent)
  418.         {
  419.             Serial.println("\n+++ MAINS DETECTED +++\n");
  420.         }
  421.         else
  422.         {
  423.             Serial.println("\n--- MAINS LOST ---\n");
  424.             // Clear all alarms when mains is lost
  425.             alarmOverVoltageActive = false;
  426.             alarmUnderVoltageActive = false;
  427.             alarmOverCurrentActive = false;
  428.         }
  429.         previousMainsState = mainsPresent;
  430.     }
  431. }
  432.  
  433. /* END CODE */
  434.  
Advertisement
Add Comment
Please, Sign In to add comment