Cirkit Designer LogoCirkit DesignerYour all-in-one circuit design IDE Launch Cirkit Designer App

ESP32-Based Smart Water Level Controller with Ultrasonic Sensor and OLED Display

View and Edit Project In Cirkit DesignerImage of ESP32-Based Smart Water Level Controller with Ultrasonic Sensor and OLED Display

Circuit Documentation

Summary

This circuit is designed to monitor water levels using an ultrasonic sensor and control a water pump via a relay. The water level is displayed on an OLED screen, and the pump is activated or deactivated based on the water level. The circuit is powered by a 18650 Li-ion battery pack and regulated to 5V using a 7805 voltage regulator.

Component List

  1. 1 Channel Relay 5V

    • Pins: VCC, GND, IN, NC, COM, NO
    • Description: A relay module used to control the water pump.
    • Purpose: To switch the water pump on and off based on the water level.
  2. 5V Mini Water Pump

    • Pins: Positive pin, Negative pin
    • Description: A small water pump.
    • Purpose: To pump water when the water level is low.
  3. Diode

    • Pins: Cathode, Anode
    • Description: A diode used for protection.
    • Purpose: To prevent backflow of current.
  4. 7805 Voltage Regulator

    • Pins: Vin, Gnd, Vout
    • Description: A voltage regulator to provide a stable 5V output.
    • Purpose: To regulate the voltage from the battery to 5V.
  5. Resistor (1k Ohms)

    • Pins: Pin1, Pin2
    • Description: A resistor with a resistance of 1k Ohms.
    • Purpose: Used in the circuit for current limiting and voltage division.
  6. HC-SR04 Ultrasonic Sensor

    • Pins: VCC, TRIG, ECHO, GND
    • Description: An ultrasonic sensor to measure distance.
    • Purpose: To measure the water level.
  7. 18650 Li-ion Battery x 2

    • Pins: +, -
    • Description: A battery pack consisting of two 18650 Li-ion batteries.
    • Purpose: To power the circuit.
  8. ESP32

    • Pins: EN, VP, VN, D34, D35, D32, D33, D25, D26, D27, D14, D12, D13, GND, VIN, 3V3, D15, D2, D4, RX2, TX2, D5, D18, D19, D21, RX0, TX0, D22, D23, BOOT
    • Description: A microcontroller with Wi-Fi and Bluetooth capabilities.
    • Purpose: To control the circuit and process sensor data.
  9. OLED 1.3" Display

    • Pins: GND, VCC, SCL, SDA
    • Description: An OLED display to show the water level.
    • Purpose: To display the water level and other information.
  10. NPN Transistor (CBE)

    • Pins: Collector, Base, Emitter
    • Description: A transistor used for switching.
    • Purpose: To control the relay.

Wiring Details

1 Channel Relay 5V

5V Mini Water Pump

Diode (1)

Diode (2)

7805 Voltage Regulator

Resistor (1)

Resistor (2)

HC-SR04 Ultrasonic Sensor

18650 Li-ion Battery x 2

ESP32

OLED 1.3" Display

NPN Transistor (CBE)

Documented Code

#include <Adafruit_GFX.h>
#include <Adafruit_SH110X.h>
#include <Wire.h>

// Define OLED display size
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SH1106G display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire);

// Ultrasonic sensor pins
#define TRIG_PIN 25          // GPIO pin connected to the TRIG of ultrasonic sensor
#define ECHO_PIN 26          // GPIO pin connected to the ECHO of ultrasonic sensor

// Relay pin
#define RELAY_PIN 27         // GPIO pin connected to the relay

// Function to calculate distance
float getDistance() {
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);

  long duration = pulseIn(ECHO_PIN, HIGH);
  float distance = (duration * 0.0343) / 2; // Convert to cm
  if (distance > 50) distance = 50; // Cap at 50 cm (maximum for 180°)
  if (distance < 0) distance = 0;  // Cap at 0 cm
  return distance;
}

// Function to draw the gauge
void drawGauge(float distance) {
  display.clearDisplay();

  int gaugeCenterY = 52; // Gauge center Y position

  // Draw static gauge (semi-circle arc)
  display.drawCircle(64, gaugeCenterY, 40, SH110X_WHITE); // Outer arc
  display.drawCircle(64, gaugeCenterY, 38, SH110X_WHITE); // Inner arc

  display.setCursor(10, 54);
  display.print("0"); // Minimum value of the gauge

  display.setCursor(110, 54);
  display.print("100"); // Maximum value of the gauge

  // Reverse the mapping of distance (0 cm -> 100%, 50 cm -> 0%)
  int angle = map(distance, 0, 50, 0, 180);
  float radians = angle * PI / 180;

  // Calculate pointer coordinates
  int x2 = 64 + 35 * cos(radians);
  int y2 = gaugeCenterY - 35 * sin(radians);

  // Draw pointer
  display.drawLine(64, gaugeCenterY, x2, y2, SH110X_WHITE);

  // Display "Water Level:" and percentage value on the same line
  display.setTextSize(1);
  display.setTextColor(SH110X_WHITE);
  display.setCursor(10, 2);
  display.print("Water Level: ");

  // Reverse logic: 0 cm -> 100%, 50 cm -> 0%
  int percentage = map(distance, 0, 50, 100, 0);
  display.print(percentage);
  display.print("%");

  display.display();
}

void setup() {
  Serial.begin(115200);

  // Initialize OLED display
  if (!display.begin(0x3C)) {
    Serial.println(F("SH