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

ESP32-Based Ultrasonic Liquid Level Indicator with I2C LCD Display

View and Edit Project In Cirkit DesignerImage of ESP32-Based Ultrasonic Liquid Level Indicator with I2C LCD Display

Circuit Documentation

Summary

This circuit is designed to monitor the level of a tank using an ultrasonic sensor (HC-SR04) and display the information on an I2C LCD screen. It includes user input through pushbuttons to set and calibrate the system. The ESP32 microcontroller is used to process the sensor data, control the LCD, and manage the system's state. A relay is included to control an external device based on the tank level, and a transistor is used to drive the relay. Protection diodes are in place to prevent reverse current flow. The circuit also features resistors for current limiting and pull-up/down configurations.

Component List

Microcontroller

Display

Sensor

Transistor

Diode

Switches

Resistors

Relay

Connectors

Wiring Details

ESP 32 DEVKIT V1 (30 pins)

I2C LCD 16x2 Screen

HC-SR04 Ultrasonic Sensor

BC547 Transistor

1N4007 Rectifier Diode

Pushbutton

Resistor (1k Ohms)

Resistor (10k Ohms)

12V Relay

Terminal PCB 2 Pin

Documented Code

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#include "EEPROM.h"
// Set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27, 16, 2);
long duration, inches;
int lvl,m,sm,fulllvl,lowlvl,lowset,mode,dly,inch;
bool st,out;
void setup()
{
    pinMode(2, INPUT);
    pinMode(4, OUTPUT);  
    pinMode(15, OUTPUT);    
    pinMode(34, INPUT);
    pinMode(35, INPUT);
   Serial.begin(9600);
  EEPROM.begin(4);
   //-----------
	// initialize the LCD
	lcd.begin();

	// Turn on the blacklight and print a message.
	lcd.backlight();
	lcd.print("TANK LEVEL: 100%");
  lcd.setCursor(0, 1);
  lcd.print("MODE:A   OUT:OFF");
    mode=EEPROM.read(0);  
    lowset=EEPROM.read(1);
    fulllvl=EEPROM.read(2);
    lowlvl=EEPROM.read(3);
    if(mode>1)mode=0; 
    if(lowset<10)lowset=10;
    if(lowset>90)lowset=10; 
    if(fulllvl>100)lowlvl=0;
    if(lowlvl>120)lowlvl=1; 

 
}

void loop()
{
  dly++;
	digitalWrite(4, LOW);
   delayMicroseconds(2);
   digitalWrite(4, HIGH);
   delayMicroseconds(10);
   digitalWrite(4, LOW);
   duration = pulseIn(2, HIGH);
   inches = microsecondsToInches(duration);
 inch=inches-fulllvl;
   lvl=(((lowlvl-inch))*100)/(lowlvl);
   if(lvl<0)lvl=0;
if(lvl>100)lvl=100;   
//----------------------------------
if( digitalRead(35)&digitalRead(34))st=0;
   if( !digitalRead(34)&!st){
     st=1;
    if(m==0){m=1;
lcd.clear();    
    lcd.setCursor(0, 0);
lcd.print("      MODE      ");}  
else if(m==2|m==1){
  lcd.setCursor(0, 1);
  lcd.print("               "); 
  if(sm==0){sm=1;

  }
else  if(sm==1){sm=0;
  if(m==1) EEPROM.write(0, mode);
 else EEPROM.write(1, lowset);
EEPROM.commit();   



  
  }

  

}
     else if(m==3){
fulllvl=inches;
 lcd.setCursor(7, 1);
  lcd.print(fulllvl);  
EEPROM.write(2, fulllvl);
EEPROM.commit();  
delay(1000); 
lcd.setCursor(0, 1);
  lcd.print("               ");  
    } 
       
    else if(m==4){
lowlvl=inch;
if(lowlvl<1)lowlvl=1;
 lcd.setCursor(7, 1);
  lcd.print(lowlvl);  
EEPROM.write(3, lowlvl);
EEPROM.commit();  
delay(1000); 
lcd.setCursor(0, 1);
  lcd.print("               ");  
    }
    else if(m==5){
      m=0;
    
lcd.setCursor(0, 0);      
	lcd.print("TANK LEVEL: 100%");
  lcd.setCursor(0, 1);
  lcd.print("MODE:A   OUT:OFF");      
      }

   }
 if( !digitalRead(35)&!st){
   st=1;
if(m==0){
 if(mode