ESP32

ESP32 with TOF10120 Laser Rangefinder distance sensor, IoT water Level Monitoring

ESP32 with TOF10120 Sensor:

ESP32 with TOF10120 Laser Rangefinder distance sensor, IoT water Level Monitoring- 

The TOF10120 Laser Rangefinder or Distance sensor is such a beautiful piece of hardware. I have been using this ToF Distance sensor with Arduino and Nodemcu ESP8266 WiFi module in different projects for measuring the distance. Recently I used it in a Car parking system to help the driver safely park the Car. I also used it with the Nodemcu ESP8266 and Blynk application for monitoring the Water level from anywhere in the World. If you have never used the TOF10120 Laser distance sensor then I highly recommend watch my getting started tutorial. Anyways, 3 months back I designed an Arduino based Hydroponics system using pH Senor, EC Sensor or TDS sensor, DS18b20 One-Wire digital Temperature sensor, Oled display module, and TOF10120 Laser distance sensor. This project was really appreciated and since then I am getting lots of comments and emails from boys and girls requesting if I can make the same Hydroponics system using the ESP32 WiFi + Bluetooth module. They actually want to see the IoT version of the same Hydroponics system.

You can also ready my article on IoT based Water level monitoring and automatic water pump control system using the ESP32 WiFi + Bluetooth Module, Waterproof Ultrasonic Sensor, and the New Blynk V2.0 more…


As usual, before I am going to make the complete IoT based Hydroponics project, first I will start with the very basics, I will individually connect each sensor with the ESP32 and then in the end we will make the complete IoT based Hydroponics System. So, in this article, we will only use the TOF10120 Laser Rangefinder sensor with the ESP32 WiFi + Bluetooth Module.

One more thing that I would like to talk about is to avoid any confusion. I am going to use this development board in this series of videos. This is the same board I used in my IoT-based Home automation system. I have already explained each and every detail, the circuit diagram, and the making. So, if you want to make the same ESP32 development board then watch my tutorial. If in case you don’t need these relays then you can simply start with the ESP32 module.

If you have used the TOF Sensor then you should have noticed the distance values really fluctuate, I have fixed this issue which I will explain in a minute. I have written two codes for you guys one is without internet support, it’s like using ESP32 as the Arduino board. In Example1 what exactly I am is, I am simply reading the distance values and sending it to the Serial monitor.

ESP32 with TOF10120

You can see the values are pretty constant and this is after applying the averaging technique and I also used a timer to check for any valid change, if the value changes and remain the same for at least 4 seconds then the value is updated otherwise the timer is reset. This is how I get rid of the fluctuations. Now, you can use some if conditions to control some LEDs or Buzzer, or a relay. Now it’s totally up to you for what purpose you are going to use it. You can also let me know in a comment, and by the way, don’t forget to Like and Subscribe.

ESP32 with TOF10120

In this next example, I modified the code and converted it into an IoT-based Water level Monitoring System. I designed it for a 600mm water tank and the water level is in percentage. You can change the limits as per your requirement. Now you have got the idea of what you are going to learn after reading this article. Without any further delay, let’s get started!!!

Note: this old version of the Blynk app is no more functional. For the blynk mobile App setup and Blynk.cloud dashboard setup ready my article on the New Blynk V2.0. In this article I have explained how to migrate your projects from Blynk 1.0 to the new Blynk V2.0. You can also watch the video.


Amazon Links:

tof10120 laser range sensor

ESP32 WiFi + Bluetooth Module(Recommended)

LM7805 Voltage Regulator:

470uf capacitor:

330-ohm resistor:

DC Female Power Jack:

Female Headers:

Male Headers:

12V SPDT Relay:

Other Tools and Components:

Top Arduino Sensors:

Super Starter kit for Beginners

Digital Oscilloscopes

Variable Supply

Digital Multimeter

Soldering iron kits

PCB small portable drill machines

*Please Note: These are affiliate links. I may make a commission if you buy the components through these links. I would appreciate your support in this way!

TOF10120 Sensor:

ESP32 with TOF10120

I have a very detailed getting started tutorial on the ToF10120 Laser Rangefinder distance sensor. In this tutorial, I have explained the pinout and technical specs and I have also explained how to use this TOF sensor with Arduino and display the values on the Oled display module. So, if you want to learn the very basic things then read my article on TOF10120 and Arduino.



ESP32 WiFi + Bluetooth Module:

ESP32 with TOF10120

The type of the ESP32 WiFi + Bluetooth module I am using in the project, I have already explained it in very detail covering the technical specs, pinout, ESP32 board installation, and how to control an LED. So, if you have never used the ESP32 Module then you need to read this article “Getting started with ESP32 WiFi + Bluetooth Module”.

TOF10120 interfacing with ESP32, Circuit Diagram:

ESP32 with TOF10120

This is exactly the same circuit diagram I explained in my IoT based Home Automation system using ESP32 WiFi + Bluetooth module. The only modification is the addition of this TOF Sensor. The VCC and GND wires are connected with the 3.3V and Gnd pins of the ESP32 while the SCL and SDA wires of the TOF10120 Laser distance sensor are connected with the GPIO pins 22 and 21. 22 is the SCL and 21 is the SDA.


ESP32 Development Board:

ESP32 with TOF10120

I have already explained the designing and making of this low-cost ESP32 development board, in my IoT based Home automation project. I connected the TOF10120 with the ESP32 as per the circuit diagram. I have cut the UART wires and I am only using the i2c wires. For now, I am not using these relays. So, my interfacing is completed.

TOF10120 Sensor with ESP32, programming:

First of all, Download all the necessary libraries used in Example number1 and example number2. So, first, let’s start with an example number1.

ToF10120 ESP32 Code:

// ESP32 and TOF10120 Laser RangeFinder Distance Sensor
//download libraries
//https://www.electroniclinic.com/arduino-libraries-download-and-projects-they-are-used-in-project-codes/

#include<stdlib.h>
#include <SimpleTimer.h>
#include <Wire.h>


SimpleTimer timer1; // for TOF10120 Sensor
SimpleTimer timer2; // use to check if the distance value remains the same for 4 seconds
int secs = 0; 
float setSensorValue = 0; 
// for TOF10120 Laser Rangefinder Sensor

unsigned char ok_flag;
unsigned char fail_flag;
 
unsigned short lenth_val = 0;
unsigned char i2c_rx_buf[16];
unsigned char dirsend_flag=0;
 
int x_mm; // distance in millimeters
float f_value; 




void setup(){

  Serial.begin(9600);
  Wire.begin();


  timer1.setInterval(200L, TOF10120);
  timer2.setInterval(1000L, SensorTime);

}
void loop(){

  timer1.run(); // Initiates SimpleTimer
  timer2.run();
}



void TOF10120()
{
  
    for(int tof = 0; tof <=  9; tof++)
    {
      x_mm = x_mm + ReadDistance();
     
    }
       f_value = x_mm / 10;
       //Serial.print(f_value);
       //Serial.println(" mm");
       x_mm = 0;

     if ( (f_value < setSensorValue) || ( f_value > setSensorValue))
     {
      if ( secs == 4 )
      {
        setSensorValue = f_value; 
      }

     }

     if ( setSensorValue == f_value )
     {
      secs = 0;
     }
    
 Serial.print("Distance in mm: "); 
 Serial.println(setSensorValue);
}


int serial_putc( char c, struct __file * )
{
  Serial.write( c );
  return c;
}
 


void SensorRead(unsigned char addr,unsigned char* datbuf,unsigned char cnt) 
{
  unsigned short result=0;
  // step 1: instruct sensor to read echoes
  Wire.beginTransmission(82); // transmit to device #82 (0x52), you can also find this address using the i2c_scanner code, which is available on electroniclinic.com
  // the address specified in the datasheet is 164 (0xa4)
  // but i2c adressing uses the high 7 bits so it's 82
  Wire.write(byte(addr));      // sets distance data address (addr)
  Wire.endTransmission();      // stop transmitting
  // step 2: wait for readings to happen
  delay(1);                   // datasheet suggests at least 30uS
  // step 3: request reading from sensor
  Wire.requestFrom(82, cnt);    // request cnt bytes from slave device #82 (0x52)
  // step 5: receive reading from sensor
  if (cnt <= Wire.available()) { // if two bytes were received
    *datbuf++ = Wire.read();  // receive high byte (overwrites previous reading)
    *datbuf++ = Wire.read(); // receive low byte as lower 8 bits
  }
}
 
int ReadDistance(){
    SensorRead(0x00,i2c_rx_buf,2);
    lenth_val=i2c_rx_buf[0];
    lenth_val=lenth_val<<8;
    lenth_val|=i2c_rx_buf[1];
    delay(100); 
    return lenth_val;
}

void SensorTime()
{
  secs = secs + 1; 
  if ( secs == 5 )
  {
    secs = 0; 
  }
 // Serial.println(secs);
  
}


ToF10120 ESP32 Code, Explanation:

I started off by including the necessary libraries, the download link I have already shared above.

#include<stdlib.h>

#include <SimpleTimer.h>

#include <Wire.h>

Next, I created two timers, timer1 and timer2.

SimpleTimer timer1; // for TOF10120 Sensor

SimpleTimer timer2; // use to check if the distance value remains the same for 4 seconds

Next, I defined a variable for counting the secs and some other variables which I have explained in my previous articles and videos.

int secs = 0;

float setSensorValue = 0;

// for TOF10120 Laser Rangefinder Sensor




unsigned char ok_flag;

unsigned char fail_flag;




unsigned short lenth_val = 0;

unsigned char i2c_rx_buf[16];

unsigned char dirsend_flag=0;




int x_mm; // distance in millimeters

float f_value;


Inside the setup() function, I activated the serial communication, activated the wire, and also added the functions TOF10120 and SensorTime with timer1 and timer2. So, basically, we are using these two timers to control these two functions.

void setup(){




Serial.begin(9600);

Wire.begin();

timer1.setInterval(200L, TOF10120);

timer2.setInterval(1000L, SensorTime);




}

Inside the loop() function, which executes repeatedly, we added the timer1.run() and timer2.run() functions to run both the timers.

void loop(){




timer1.run(); // Initiates SimpleTimer

timer2.run();

}

TOF10120() function is a user-defined function and it is used to measure the distance. I am using a for a loop to take 10 samples and then I take the average, finally, I use if condition to check if the value change is valid or not. The code remains exactly the same. The SensorTime() function is used to count the seconds.

void TOF10120()

{




for(int tof = 0; tof <=  9; tof++)

{

x_mm = x_mm + ReadDistance();




}

f_value = x_mm / 10;

//Serial.print(f_value);

//Serial.println(" mm");

x_mm = 0;




if ( (f_value < setSensorValue) || ( f_value > setSensorValue))

{

if ( secs == 4 )

{

setSensorValue = f_value;

}




}




if ( setSensorValue == f_value )

{

secs = 0;

}




Serial.print("Distance in mm: ");

Serial.println(setSensorValue);

}







int serial_putc( char c, struct __file * )

{

Serial.write( c );

return c;

}










void SensorRead(unsigned char addr,unsigned char* datbuf,unsigned char cnt)

{

unsigned short result=0;

// step 1: instruct sensor to read echoes

Wire.beginTransmission(82); // transmit to device #82 (0x52), you can also find this address using the i2c_scanner code, which is available on electroniclinic.com

// the address specified in the datasheet is 164 (0xa4)

// but i2c adressing uses the high 7 bits so it's 82

Wire.write(byte(addr));      // sets distance data address (addr)

Wire.endTransmission();      // stop transmitting

// step 2: wait for readings to happen

delay(1);                   // datasheet suggests at least 30uS

// step 3: request reading from sensor

Wire.requestFrom(82, cnt);    // request cnt bytes from slave device #82 (0x52)

// step 5: receive reading from sensor

if (cnt <= Wire.available()) { // if two bytes were received

*datbuf++ = Wire.read();  // receive high byte (overwrites previous reading)

*datbuf++ = Wire.read(); // receive low byte as lower 8 bits

}

}




int ReadDistance(){

SensorRead(0x00,i2c_rx_buf,2);

lenth_val=i2c_rx_buf[0];

lenth_val=lenth_val<<8;

lenth_val|=i2c_rx_buf[1];

delay(100);

return lenth_val;

}




void SensorTime()

{

secs = secs + 1;

if ( secs == 5 )

{

secs = 0;

}

// Serial.println(secs);




}

Blynk Application Designing:

For the next example, you will need to make the Blynk application, I have explained each and every step in the video, link to the video tutorial is given in the decription.

ESP32 IoT based Water level monitoring Code:

// IoT Water Level Monitoring Using ESP32 WiFi + Bluetooth Module and TOF10120 Laser Distance Sensor
//download libraries
//https://www.electroniclinic.com/arduino-libraries-download-and-projects-they-are-used-in-project-codes/

#include<stdlib.h>
#define BLYNK_PRINT Serial
#include <BlynkSimpleEsp32.h>
#include <SimpleTimer.h>
#include <Wire.h>


SimpleTimer timer1; // for TOF10120 Sensor
SimpleTimer timer2; // for counting seconds and minutes

char auth[] = "YoX0h2rIJkZCOoQAvY4un4OZQ8Dw_0WZ";
/* WiFi credentials */
char ssid[] = "AndroidAP7DF8";
char pass[] = "jamshaid4";



// for TOF10120 Laser Rangefinder Sensor

unsigned char ok_flag;
unsigned char fail_flag;
 
unsigned short lenth_val = 0;
unsigned char i2c_rx_buf[16];
unsigned char dirsend_flag=0;
 
int x_mm; // distance in millimeters
int Sensor_actual_value; 
float y_inches; // distance in inches

int secs; 
int minutes;
int hours;


void setup(){

  Serial.begin(9600);
  Wire.begin();
  Blynk.begin(auth, ssid, pass);

  timer1.setInterval(1000L, TOF10120);
  timer2.setInterval(1000L, Time_check);
}
void loop(){

  timer1.run(); // Initiates SimpleTimer
  timer2.run();
  Blynk.run();
  
}



void TOF10120()
{
     x_mm = ReadDistance();
      Sensor_actual_value = x_mm;
x_mm = map(x_mm, 0,600,100,0);
   Serial.println(x_mm);
   Serial.print(" mm");
   Blynk.virtualWrite(V2,x_mm);
   Blynk.virtualWrite(V3,Sensor_actual_value);
   // You can convert millimeters to inches in one of two ways: divide the number of millimeters by 25.4, or multiply the number of millimeters by 0.0394
  // y_inches = x_mm * 0.0394;
  // Serial.print(y_inches); 
  // Serial.println(" inches");
  // Blynk.virtualWrite(V4,y_inches);
 
}


int serial_putc( char c, struct __file * )
{
  Serial.write( c );
  return c;
}
 


void SensorRead(unsigned char addr,unsigned char* datbuf,unsigned char cnt) 
{
  unsigned short result=0;
  // step 1: instruct sensor to read echoes
  Wire.beginTransmission(82); // transmit to device #82 (0x52), you can also find this address using the i2c_scanner code, which is available on electroniclinic.com
  // the address specified in the datasheet is 164 (0xa4)
  // but i2c adressing uses the high 7 bits so it's 82
  Wire.write(byte(addr));      // sets distance data address (addr)
  Wire.endTransmission();      // stop transmitting
  // step 2: wait for readings to happen
  delay(1);                   // datasheet suggests at least 30uS
  // step 3: request reading from sensor
  Wire.requestFrom(82, cnt);    // request cnt bytes from slave device #82 (0x52)
  // step 5: receive reading from sensor
  if (cnt <= Wire.available()) { // if two bytes were received
    *datbuf++ = Wire.read();  // receive high byte (overwrites previous reading)
    *datbuf++ = Wire.read(); // receive low byte as lower 8 bits
  }
}
 
int ReadDistance(){
    SensorRead(0x00,i2c_rx_buf,2);
    lenth_val=i2c_rx_buf[0];
    lenth_val=lenth_val<<8;
    lenth_val|=i2c_rx_buf[1];
    delay(300); 
    return lenth_val;
}

void Time_check()
{
  secs = secs + 1;
  if ( secs >= 59 )
  {
    minutes = minutes + 1;
    secs =0;
    if(minutes == 2) // notification message is sent after every 2 minutes, change this number as per your requirement
    {
      if ( Sensor_actual_value >= 500) // if the tank is almost empty
      {
        Blynk.notify("Tank is empty"); 
        secs = 0;
        minutes = 0; 
      }

          if ( Sensor_actual_value <= 300) // if half filled or the tank is full
      {
       secs = 0;
        minutes = 0; 
      }
    }
  }

 
}

This is the modified version of the code, I used in the example number1. I added the necessary libraries, defined two timers, and added the authentication token and WiFi credentials. The maximum of the code remains exactly the same, I added virtual pins in the code, basically through these virtual pins we are sending data to the Blynk application.

For the step-by-step explanation, watch the video tutorial given below. Don’t forget to like, share, and subscribe.


Watch Video Tutorial:

Engr Fahad

My name is Shahzada Fahad and I am an Electrical Engineer. I have been doing Job in UAE as a site engineer in an Electrical Construction Company. Currently, I am running my own YouTube channel "Electronic Clinic", and managing this Website. My Hobbies are * Watching Movies * Music * Martial Arts * Photography * Travelling * Make Sketches and so on...

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button