ESP32-Based Smart Voltage Monitoring and Relay Control System with Solar Integration
View and Edit Project In Cirkit Designer
Circuit Documentation
Summary of the Circuit
This circuit is designed to monitor voltage levels and control a series of relays based on the voltage readings and timing logic. It utilizes an Arduino Nano ESP32 as the central microcontroller to handle logic operations, WiFi connectivity, and timekeeping via NTP. The circuit includes voltage sensors (ZMPT101B modules) for monitoring power lines, relays for controlling loads, transistors as switches for the relays, zener diodes for voltage regulation, resistors for current limiting, and an OLED display for user feedback.
Component List
Microcontroller
- Arduino Nano ESP32: A compact microcontroller board based on the ESP32 chip, featuring WiFi connectivity and a variety of digital and analog I/O pins.
Sensors
- ZMPT101B: Voltage sensor modules used to measure the voltage of power lines.
Power Regulation
- LM2596 Step Down Module: A voltage regulator module used to step down the input voltage to a lower, regulated output voltage.
Actuators
- Relay: Electromechanical switches used to control the connection and disconnection of circuits by an electrical signal.
Transistors
- BC547 Transistor: NPN bipolar junction transistors used to control the relays.
Diodes
- Zener Diode: Diodes used to provide voltage regulation by limiting the voltage to a certain maximum threshold.
Resistors
- Resistor: Passive components used to limit current flow and divide voltages in the circuit.
Connectors
- 5 pin relimate connector: Connectors used for making detachable connections between wires and the circuit board.
- Terminal PCB 2 Pin: Connectors used for connecting external wires to the circuit board.
Display
- 0.96" OLED: A small display used for showing information such as voltage levels, time, and relay status.
Wiring Details
Arduino Nano ESP32
- Digital pins D2 to D7 are connected to resistors, which are then connected to the bases of BC547 transistors to control the relays.
- Analog pins A0 and A1 are connected to the output of ZMPT101B voltage sensors for voltage monitoring.
- Analog pins A4 and A5 are connected to the SDA and SCK pins of the OLED display for I2C communication.
- The GND pin is connected to the emitters of BC547 transistors, the GND of the OLED display, and the GND pins of ZMPT101B modules.
- The VIN pin is connected to the coils of the relays and the VCC of the OLED display.
ZMPT101B Voltage Sensor
- OUT pin connected to the Arduino's analog input pins (A0 and A1).
- GND pin connected to the Arduino's GND.
- VCC pin connected to a power source (regulated by the LM2596 module).
LM2596 Step Down Module
- OUT- connected to the GND of the Arduino and other components.
- OUT+ connected to the VCC of the OLED display and the VCC pins of ZMPT101B modules.
Relay
- Coil pins connected to the VIN of the Arduino and the cathodes of zener diodes.
- Common, NO (Normally Open), and NC (Normally Closed) pins connected to the terminal PCB 2 Pin and 5 pin relimate connectors.
BC547 Transistor
- Collector connected to the relay coil and the anode of zener diodes.
- Base connected to the Arduino's digital pins through resistors.
- Emitter connected to the Arduino's GND.
Zener Diode
- Cathode connected to the relay coil and the OUT+ of the LM2596 module.
- Anode connected to the collector of BC547 transistors.
Resistor
- One pin connected to the Arduino's digital pins.
- The other pin connected to the base of BC547 transistors.
5 pin relimate connector
- Various pins connected to the relay's Common, NO, NC, and Coil pins for external interfacing.
0.96" OLED
- GND connected to the Arduino's GND.
- VDD connected to the Arduino's VIN.
- SCK connected to the Arduino's A5.
- SDA connected to the Arduino's A4.
Terminal PCB 2 Pin
- Pin A and Pin B connected to the Common pins of the relays for external interfacing.
Documented Code
#include <Wire.h>
#include <EEPROM.h>
#include <WiFi.h>
#include <NTPClient.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// Function prototypes
void initializeRelays();
void checkVoltage();
void controlRelays();
void checkSolar();
void displayMessage(const char* message);
void updateOLED();
String getFormattedTime();
String getFormattedDate();
// Constants and variables
const int relayTransistorBase[] = {2, 3, 4, 5, 6, 7}; // Array of transistor base pin numbers
const int solarRelayIndex = 4; // Index of the solar relay
const int wapdaRelayIndex = 5; // Index of the WAPDA relay
const int numRelays = 6; // Number of relays
const unsigned long cycleDuration = 86400; // Cycle duration in seconds (24 hours)
const int safetyVoltageLow = 180; // Minimum safe operating voltage
const int safetyVoltageHigh = 260; // Maximum safe operating voltage
const int solarThreshold = 160; // Solar voltage threshold
const int voltagePin = A0; // Analog pin for safety voltage
const int solarPin = A1; // Analog pin for solar voltage
Adafruit_SSD1306 display(128, 64, &Wire, -1); // OLED display object
char ssid[] = "yourSSID"; // Network SSID
char pass[] = "yourPASSWORD"; // Network password
WiFiUDP ntpUDP; // UDP instance for NTP
NTPClient timeClient(ntpUDP, "pool.ntp.org", 0, 60000); // NTP client
unsigned long lastRelayChangeMillis = 0; // Time of the last relay change
unsigned long elapsedTime = 0; // Elapsed time for the current relay
unsigned long lastOLEDUpdateMillis = 0; // Time of the last OLED update
int currentRelay = 0; // Current relay index
bool solarDetected = false; // Solar power detection flag
void setup() {
Serial.begin(115200); // Start serial communication
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Initialize OLED display
display.clearDisplay(); // Clear the display
initializeRelays(); // Initialize relay transistor base pins
checkVoltage(); // Check initial voltage safety
updateOLED(); // Update OLED with initial state
WiFi.begin(ssid, pass); // Connect to WiFi
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
timeClient.begin(); // Start NTP client
}
void loop() {
checkVoltage(); // Check voltage and handle safety measures
checkSolar(); // Check solar power and handle relay control
controlRelays(); // Control relays based on timing and logic
if (millis() - lastOLEDUpdateMillis >= 5000) { // Update OLED every 5 seconds
updateOLED(); // Update OLED display with the current status
lastOLEDUpdateMillis = millis(); // Reset last OLED update time
}
delay(1000); // Add a delay of 1 second
}
// Initialize relay transistor pins (set as output and initially off)
void initializeRelays() {
for (int i = 0; i < numRelays; ++i) {
pinMode(relayTransistorBase[i], OUTPUT); // Set transistor base pin as output
digitalWrite(relayTransistorBase[i], LOW); // Initially turn off transistors (active-high)
}
}
// Check voltage safety
void checkVoltage() {
int voltage = analogRead(voltagePin); // Read safety voltage
if (voltage < safetyVoltageLow) {
displayMessage("Low Voltage Detected!"); // Display warning on OLED
Serial.println("Low voltage detected!"); // Log to Serial Monitor
for (int i = 0; i < numRelays; ++i) {
digitalWrite(relayTransistorBase[i], LOW); // Turn off all relays
}
} else if (voltage > safetyVoltageHigh) {
displayMessage("High Voltage Detected!"); // Display warning on OLED
Serial.println("High voltage detected!"); // Log to Serial Monitor
for (int i = 0; i < numRelays; ++i) {
digitalWrite(relayTransistorBase[i], LOW); // Turn off all relays
}
} else {
displayMessage("Normal Voltage"); // Display normal voltage status
}
}
// Check solar power and control relay
void checkSolar() {
int solarValue = analogRead(solarPin); // Read solar power value from analog pin
int solarVoltage = map(solarValue, 0, 1023, 0, 260); // Map to voltage range
if (solarVoltage < solarThreshold) {
digitalWrite(relayTrans