IoT Water Level Sensor Using ESP8266 Nodemcu, TOF10120, and Blynk

(Last Updated On: April 4, 2021)

IoT Water Level Sensor

IoT Water Level Sensor Description:

IoT Water Level Sensor- In this article you will learn how to design your own IoT Water Level Sensor using TOF10120 Rangefinder or Distance Sensor or Time of flight Sensor, Nodemcu ESP8266 Wifi Module, and Blynk application. I have been working on water tank level indicator based projects for quite a long time. I have already designed two water tank level indicators.

Water Level Sensor using Arduino & Ultrasonic Sensor:

IoT Water Level Sensor

This water level monitoring system is based on the Arduino Uno board, Ultrasonic Sensor, and some LEDs to display the percentage of water. For the beginners this is the simplest and easiest project to start with.

IoT Water Level Sensor Using Arduino, Nodemcu ESP8266, and Ultrasonic Sensor:

IoT Water Level Sensor

I modified my previous water tank level indicator and converted it into an IoT water tank level sensor. You can compare the above two images. With the help of this project, I was able to see the percentage of water via LEDs and I was also able to monitor the water level from anywhere around the world using my cell phone.

Arduino Hydroponics System for Plants:

IoT Water Level Sensor

I also used the same TOF10120 Laser distance sensor in my Hydroponics system for monitoring the water level.

The water level monitoring system that we are going to make in this project is also based on IoT Water level monitoring system, but this one is more reliable, low-cost, and easy to build. In this project, I replaced the Ultrasonic Sensor with the TOF10120 Time-of-flight Rangefinder or Distance sensor for measuring the Water level. The TOF10120 can be easily waterproofed. Moreover, the previous version of the IoT Water level Sensor was more complicated as I used the Arduino and Nodemcu ESP8266 together. We can make the same water level sensor using only the Nodemcu ESP8266 Wifi Module.

The IoT Water Level Sensor project that you are going to learn today is the smartest water level monitoring system because you get the actual distance in mm “millimeters” and the water level inside the tank in percentage. Moreover, when the Water Tank is empty you will also get the notification on your cell phone.

IoT Water Level Sensor

The water tank empty notification part is really important, it has to be in a smart way, you don’t want to send too many notifications to annoy the user. I used a timer to control the notification messages. The time in minutes can be adjusted as per the user ease. For the demonstration purposes, I started with two minutes. So, when the Water tank is empty the ESP8266 will send the notification after every two minutes. Another feature that makes this water level Sensor the smartest IoT water level sensor is that you get notifications even when the water monitoring App is not active “running in the background”. In the image below you can see clearly, I was talking to my friend Paul Walsh when I got the water tank empty notification.

IoT Water Level Sensor

You can also check the Water level at any time using the cell phone application designed in Blynk.

IoT Water Level Sensor

As this project is based on the IoT “internet of things” based project, so your Nodemcu ESP8266 needs to be connected with the Wifi at all times otherwise you won’t be able to monitor the water level inside the tank. After all this explanation, I am sure 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!!!

Amazon Purchase Links:

Nodemcu ESP8266 WiFi Module:

tof10120 laser range sensor

Other Tools and Components:

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 Laser Distance Sensor:

IoT Water Level Sensor

TOF10120 range sensor provides accurate and repeatable long-range distance measurement for high-speed autofocus (AF). The innovative time-of-flight technology allows performance independent of object reflectance.

TOF10120’s time-of-flight sensing technology is realized by Sharp’s original SPAD (Single Photon Avalanche Diodes ) using a low-cost standard CMOS process. It enables accurate ranging results, higher immunity to ambient light, and better robustness to cover-glass optical cross-talk by special optical package design.

TOF10120 Features:

・940nm laser classified as class 1 under operation condition by IEC 60825-1:2014-3rd edition

・Small ceramic package(20×13.2×2.0mm)

・Long range absolute range measurement up to 1.8m within 5% accuracy at indoor.

・Reported range is independent of the target reflectance

・Operates in high infrared ambient light levels

・Advanced optical cross-talk compensation

・High speed ranging MAX 30ms

・Standard solder reflow compatible

・No additional optics

・Single power supply

・Txd interface for device control and data transfer

・Lead-free, RoHS compliant

TOF10120 Applications:

・High-speed AF

・Continuous AF for video

・User detection for Personal Computers/Laptops/Tablets

・Robotics (obstacle detection)

・Contactless Switch

・White goods (hand detection in automatic Faucets, refrigerator etc.)

TOF10120 Recommended Operating Conditions:

IoT Water Level Sensor

As per the datasheet the recommended ranging range of the TOF10120 is between 100 and 1800 the unit is in mm (millimeters). The TOF10120 Laser Range Sensor Module can be easily powered up using 3 to 5 volts. Due to this wide range of input voltages, the TOF10120 can be easily used with 5V and 3.3V compatible controller boards like Arduino boards, ESP8266, and ESP32, etc. The current consumption of the TOF10120 is 35mA. The ideal temperature range of the TOF10120 is from -20 to +70 Centigrade. Due to this wide temperature range, this module can be used in extreme weather conditions indoor and outdoor.

TOF10120 Ranging Conditions:

As per the datasheet the recommended ranging range of the TOF10120 is between 100 and 1800 the unit is in mm (millimeters). The TOF10120 Laser Range Sensor Module can be easily powered up using 3 to 5 volts. Due to this wide range of input voltages, the TOF10120 can be easily used with 5V and 3.3V compatible controller boards like Arduino boards, ESP8266, and ESP32, etc. The current consumption of the TOF10120 is 35mA. The ideal temperature range of the TOF10120 is from -20 to +70 Centigrade. Due to this wide temperature range, this module can be used in extreme weather conditions indoor and outdoor.

TOF10120 Ranging Conditions:

IoT Water Level Sensor

The range accuracy change as per the above conditions which depend on the Target Reflection and environment.

TOF10120 Pin Description:

IoT Water Level Sensor

From the signal names of the TOF10120, it’s quite clear that this RangeFinder supports both the UART and the I2C communication. Pin number1 is the ground. Pin number2 is the VDD. Pin number3 is the RXD. Pin number4 is the TXD. Pin number 5 is the SDA and finally pin number6 is the SCL. Out of the 6 pins of the TOF10120 I will use only 4 pins. GND, VDD, SDA, and SCL.

I have a very detailed tutorial on “TOF10120 Laser Rangerfinder + Arduino + Oled Display”. In this article, I have explained each and every detail. So, if this is your first time using the TOF10120 Laser sensor, then I highly recommend reading this article.

As explained earlier we will be using only the SDA and SCL pins of the TOF10120 Laser Distance sensor. So, for this, you should know about the Nodemcu ESP8266 Pinout.

IoT Water Level Sensor

The I2C pins in Nodemcu ESP8266 are D1 and D2. D1 which is the GPIO5 is the SCL and the D2 which is the GPIO4 is the SDA. Besides this, you will also need to learn about how to program the Nodemcu ESP8266 using the Arduino IDE. For this, you will need to install the Nodemcu ESP8266 board. Make sure the latest version of the Arduino IDE is installed on your computer. Currently, I am using the Arduino IDE version 1.8.10. Copy the following URL Link

Nodemcu ESP8266 URL Link:


Open your Arduino IDE


Click on the preferences and paste the URL link given above.

IoT Water Level Sensor

You can see I pasted this link in the Additional Boards Manager URLs box. You are all set and now you can click on the OK button.


While your Arduino IDE is still opened. Click on the Tools Menu > Board > Boards Manager. Click on the Boards Manager.

IoT Water Level Sensor

The board manager will open, and will automatically download the index.

IoT Water Level Sensor


This download process may take some time depending on the speed of your internet connection. So, set back and wait for the download process to complete. When the download process is completed then in the search box type “nodemcu esp8266”. Currently, you can see my esp8266 board is installed. So, you will see the install button, click on the install button and wait.

IoT Water Level Sensor


After your Nodemcu ESP8266 board has been installed. The final step is to close the boards Manager window. Now you will need to restart the Arduino IDE so that the Arduino IDE can properly load all the boards.


This is the final step to confirm if the Nodemcu ESP8266 board is installed.

IoT Water Level Sensor

Click on the tools menu > boards, scroll down and find the Nodemcu as you can see in the image above. If you can see the same then you are all set. We are done with the hard part. Now let’s take a look at the circuit diagram.

IoT Water Level Sensor Circuit Diagram:

IoT Water Level Sensor

The circuit diagram of the IoT Water Level Sensor is very easy. To power up the Nodemcu ESP8266, we will need a power supply. J1 is the DC female power jack and this is where we connect our 9V to 25V power supply. The LM7805 voltage regulator step-downs this voltage and outputs regulated 5 volts. To filter out the noise and voltage spikes two 470uF electrolyte decoupling capacitors are connected at the input and output sides of the regulator. An LED is also connected to the output of the regulator, which is used as an indicator. The output of the regulator is also connected with the Vin pin of the Nodemcu and don’t forget to connect the ground of the Nodemcu ESP8266 with the Ground of the regulator.

The TOF10120 power supply pins are connected with the Nodemcu 3.3V and GND pins. While the SCL and SDA wires of the TOF10120 are connected with the Nodemcu SCL and SDA pins. If you want to control a water pump then you can add a relay.

Now you have two options, you can make all the connections on the breadboard which is recommended for the initial testing and is not recommended for long-term use. For more solid connections you can use a Vero board or you can design your own PCB.

IoT Water Level Sensor

I have already designed a PCB for the Nodemcu ESP8266 so I will use this PCB for the final connections. I have been using this development board in almost all of my IoT based projects. I use this for testing my IoT based projects using Nodemcu ESP8266. Now, let’s make the Water Level Monitoring App using Blynk application.

Water Level Monitoring App:

Prior to the Nodemcu ESP8266 programming, I decided first to make the IoT water Level Sensor App in Blynk. This way I know exactly how many virtual pins I will need to use in the final code. And this also helps me in troubleshooting.

Make sure you have downloaded and installed the Blynk application.

  • First of all, open the blynk application.
  • Click on the new project and enter the project name as “RangeFinder”. If you want you can select any other name. Later you can modify the project name.
  • Click on the choose device and select Nodemcu.
  • Make sure the connection type is set to WIFI.
  • Finally, click on the create button, an authentication token will be sent on your email id, which later will be used in the Nodemcu programming.
  • Click anywhere on the screen and search for the Value Display Widget and add it to the screen.
  • Again click on the screen and this time search for the Level V widget and add it.
  • Again click on the screen and this time search for the notification widget and add it to the screen.
  • After adding all the required widgets, the next step is to do some settings.
  • Click on the first Value Display widget, set the name as distance in mm, select input type as the virtual pin V5.
  • Click on the Level V widget, set the name as water level, select the input type as the virtual pin V4 and in the range set the minimum value to 0 and maximum value to 100. As we will be displaying the percentage of water so it needs to be from 0 to 100. Our settings are done.

Your application should look something like this.

IoT Water Level Sensor

Our application is ready. Now we can start the programming. Before you start the programming, first of all, make sure you download all the necessary libraries.

IoT Water Level Sensor Nodemcu ESP8266 Programming:

IoT Water Level Monitoring Code Explanation:

First of all, I started off by adding the required libraries.


#include <ESP8266WiFi.h>

#include <BlynkSimpleEsp8266.h>

#include <SimpleTimer.h>

#include <Wire.h>

Next, I defined two timers timer1 and timer2. I will use timer1 to control the TOF10120 Laser Sensor and I will use the timer2 to count the number of seconds and minutes. So, timer2 will basically control the notification time. So, the basic concept it, when the water tank is empty the nodemcu will send a notification message as per the predefined time.

SimpleTimer timer1; // for TOF10120 Sensor

SimpleTimer timer2; // for counting seconds and minutes

Next, I added the authentication token which I received in email while making the blynk application. Finally, I added the wifi credentials.

char auth[] = “zHWsk68_H003ELXhgWoB5-Jbtq_lygaR”;

/* WiFi credentials */

char ssid[] = “AndroidAP7DF8”; // name of the wifi router

char pass[] = “electroniclinic”; // password

// for TOF10120 Laser Rangefinder Sensor

The instruction below are used with tof10120 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;

next I defined some variables for storing the distance information in mm and inches. The variable Sensor_actual_value is used to store the actual distance in mm, this value isn’t going to be mapped.

int x_mm; // distance in millimeters

int Sensor_actual_value;

float y_inches; // distance in inches

The following variables I defined for storing the seconds, minutes, and hours.

int secs;

int minutes;

int hours;

in the void setup() function I activated the serial communication and selected the standard baud rate of 9600. You can change this baud rate as per your needs. I also activated the Wire.begin() and the Blynk.begin(). Blynk.begin() function takes three arguments as the input the authorization, ssid, and password which we already defined in the beginning. Enter the correct credentials otherwise, your blynk app won’t connect.  The next two lines of codes control the two user-defined functions TOF10120() and Time_check().

timer1.setInterval(1000L, TOF10120);

timer2.setInterval(1000L, Time_check);

void setup(){



Blynk.begin(auth, ssid, pass);

timer1.setInterval(1000L, TOF10120);

timer2.setInterval(1000L, Time_check);


The code inside the void loop() function is neat and clean. We simple run the two timers and the Blynk.

void loop(){; // Initiates SimpleTimer;;


Maximum of the code given below, I have already explained in my previous tutorials.

void TOF10120()


x_mm = ReadDistance();

Sensor_actual_value = x_mm;

x_mm = map(x_mm, 0,600,100,0);


Serial.print(” mm”);



// 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

// 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++ =;  // receive high byte (overwrites previous reading)

*datbuf++ =; // receive low byte as lower 8 bits




int ReadDistance(){






return lenth_val;


This function is the new addition. The Time_check() function is a user-defined function. This function is called after every 1 second to count the seconds and minutes. When the minutes are equal to 2 it simply checks the water tank if the water level is reduced it will send the notification message.

There is also another condition that checks if the water tank is half-filled or full to its maximum capacity then it resets the seconds and minutes.

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;





So, that’s all about the IoT Water Level Sensor using TOF10120 and Nodemcu ESP8266. The demonstration images I have already shared above. Still, if you have any questions, let me know in a comment.

Watch Video Tutorial:



Recommended For You

About the Author: 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...


  1. Hi Fahad,
    Very nice project, I just ordered the TOF10120 and I have ESP8266 D1 mini. I am new at this so any help wouldbe great. First, I cannot find the library files BlynkSimpleEsp8266.h; SimpleTimer.h and Wire.h I loaded what I think is similar. When I verify the file I get these errors:

    In file included from C:\Users\Alberto\Documents\Arduino\libraries\Blynk\src/Blynk/BlynkApi.h:37:0,

    C:\Users\Alberto\Documents\Arduino\libraries\Blynk\src/Blynk/BlynkTimer.h:36:21: error: redefinition of ‘class BlynkTimer’

    #define SimpleTimer BlynkTimer

    C:\Users\Alberto\Documents\Arduino\libraries\SimpleTimer/SimpleTimer.h:10:7: note: in expansion of macro ‘SimpleTimer’

    class SimpleTimer {

    C:\Users\Alberto\Documents\Arduino\libraries\Blynk\src/Blynk/BlynkTimer.h:36:21: error: previous definition of ‘class BlynkTimer’

    #define SimpleTimer BlynkTimer

    C:\Users\Alberto\Documents\Arduino\libraries\Blynk\src/Blynk/BlynkTimer.h:41:7: note: in expansion of macro ‘SimpleTimer’

    class SimpleTimer {

    C:\Users\Alberto\Documents\Arduino\sketch_apr07b\Level.ino: In function ‘void setup()’:

    Level:40:6: error: redefinition of ‘void setup()’

    void setup(){

    sketch_apr07b:1:6: error: ‘void setup()’ previously defined here

    void setup() {

    C:\Users\Alberto\Documents\Arduino\sketch_apr07b\Level.ino: In function ‘void loop()’:

    Level:49:6: error: redefinition of ‘void loop()’

    void loop(){

    sketch_apr07b:6:6: error: ‘void loop()’ previously defined here

    void loop() {

    In file included from C:\Users\Alberto\Documents\Arduino\sketch_apr07b\Level.ino:9:0:

    C:\Users\Alberto\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.4\libraries\Wire/Wire.h: In function ‘void SensorRead(unsigned char, unsigned char*, unsigned char)’:

    C:\Users\Alberto\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.4\libraries\Wire/Wire.h:70:13: note: candidate 1: uint8_t TwoWire::requestFrom(int, int)

    C:\Users\Alberto\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.4\libraries\Wire/Wire.h:68:13: note: candidate 2: uint8_t TwoWire::requestFrom(uint8_t, uint8_t)

    exit status 1

    redefinition of ‘void setup()’

    This report would have more information with
    “Show verbose output during compilation”
    option enabled in File -> Preferences.

    Arduino: 1.8.13 (Windows Store (Windows 10), Board: “LOLIN(WEMOS) D1 R2 & mini, 80 MHz, Flash, Legacy (new can return nullptr), All SSL ciphers (most compatible), 4MB (FS:2MB OTA:~1019KB), v2 Lower Memory, Disabled, None, Only Sketch, 921600”

    Again any help will be great!

Leave a Reply