Cirkit Designer Logo
Cirkit Designer
Your all-in-one circuit design IDE
Home / 
Project Documentation

ESP32-Based Smart Voltage Monitoring and Relay Control System with Solar Integration

Image of ESP32-Based Smart Voltage Monitoring and Relay Control System with Solar Integration

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