1 0
Read Time:4 Minute, 7 Second

As part of some home sensors I wanted to measure the water level in a water tank. Originally I used a PI and python to do this but this proved to not be great so I switched to use a NODE MCU dev board (ESP8266 chip) linked to an HC-SR04 sensor (HC-SR04p would be better) and have the data sent to a rest service.

The trigger and echo wires get attached to D1 and D2, the ground get attached to any GND on the board (brown wire in image) and the power gets connected to vIN (which is a 5v supply), If using the HC-SR04P then you can use the 3.3v supply (such as the one above the current ground wire)

NOTE: Strictly speaking there should be a resistor in line with the echo wire to lower it’s voltage down to 3.3v but I found that this did not seem to be needed for the NODE board (if the chip gets fried eventually then I will change this for a replacement)

The code for the chip firmware is below, this was adapted from another of my projects and C is not my main language so please bear in mind that there may be some redundant code, I may also need to review how often the chip connects to the wi-fi, this version assumes once at boot is enough.

#include "./esppl_functions.h"
#include <ESP8266WiFi.h>
#include <time.h>
#include <WiFiUdp.h>
#include <ESP8266HTTPClient.h>

#define TRIGGER 5
#define ECHO    4

char ssid[] = "mesh";  //  your network SSID (name)
char pass[] = "xxxxxxxxxxxx";       // your network password
char REST[] = "http://xxxxxxxx.azurewebsites.net/api/Water/";

char URL[200];

void setup() {
  Serial.begin (115200);
  pinMode(TRIGGER, OUTPUT);
  pinMode(ECHO, INPUT);
  timesetup();
}

void loop() {
  
  float duration, distance;

        digitalWrite(TRIGGER, LOW);  
        delayMicroseconds(2); 
        
        digitalWrite(TRIGGER, HIGH);
        delayMicroseconds(10); 
        
        digitalWrite(TRIGGER, LOW);
        duration = pulseIn(ECHO, HIGH);
        distance = (duration/2) / 29.1;
        Serial.print("********** Ultrasonic Distance: ");
        Serial.print(distance);
        Serial.println(" cm");

  char buffer [50];
  int n=sprintf (buffer, "%f", distance);
  Serial.print(buffer);
  Serial.println(" : ");
  

    int time = 0;
    memset(URL, 0, sizeof URL);
    strcat(URL, REST);
    strcat(URL, buffer);
    HTTPClient http;  //Declare an object of class HTTPClient
    http.begin(URL);  //Specify request destination
    int httpCode = http.GET();                                                                  //Send the request
 
    if (httpCode > 0) { //Check the returning code
        printf("%4d", httpCode);
        String payload = http.getString();   //Get the request response payload
        Serial.println(payload);                     //Print the response payload
      }
 
     http.end();   //Close connection          
     delay(60000);
     printf("\n ");
}


void timesetup()
{
  WiFi.mode(WIFI_STA);
  wifi_station_disconnect();
  wifi_set_opmode(STATION_MODE);
  wifi_promiscuous_enable(false);
  esppl_sniffing_enabled = false;
  // We start by connecting to a WiFi network
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, pass);  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}


void timeloop()
{
}
 

The basic premise is that every so often the chip will take a reading and then use the REST variable with the reading appended to call a HTTP site which will log the reading (it also sets the time of the reading from it’s server time rather than needing a clock chip added to the sensor)

For info

2026 update, the original chip eventually failed so I have replaced it with a new one, but this time using ESPHOME inside home assistant since I have since started to use that for devices like this. This is the home assistant code I use now. This has some advantages for me and also deals with an issue in the old solution where if the wi-fi was rebooting while the chip was (power cuts) then I needed to reboot the chip again later since it had no handling for these issues

esphome:
  name: "esp8266water2026"
  friendly_name: "esp8266water2026"

esp8266:
  board: esp01_1m

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "withheld"

ota:
  - platform: esphome
    password: "withheld"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "X Fallback Hotspot"
    password: "withheld"

captive_portal:
    
# HTTP client

# 192 - 203mm is full.
# 200mm of water (roughly)


sensor:
  - platform: ultrasonic
    id: tank_distance_raw
    trigger_pin: GPIO5
    echo_pin: GPIO4
    name: "ESP8266 Ultrasonic Distance raw"
    unit_of_measurement: "mm"
    accuracy_decimals: 2
    update_interval: 20s
    filters:
      - multiply: 1000
  - platform: copy
    source_id: tank_distance_raw
    id: tank_distance
    name: "ESP8266 Ultrasonic Distance"
    unit_of_measurement: "mm"
    accuracy_decimals: 2
    filters:
      - sliding_window_moving_average:
         window_size: 2
         send_every: 1
  - platform: template
    name: "Water Tank Level"
    unit_of_measurement: "%"
    lambda: |-
      float distance = id(tank_distance).state;

      float full = 203.0;   // measured full (IMPORTANT: use real value)
      float empty = 400.0;  // measured empty

      float pct = (empty - distance) / (empty - full) * 100.0;

      // Clamp between 0–100
      if (pct > 120.0) return 120.0;
      if (pct < 0.0) return 0.0;

      return roundf(pct * 100.0) / 100.0;


About Post Author

raymond

Been developing software for 40 plus years, started with Apple ]['s moved on to a variety of mainframes, PC's, Atari ST/Falcon, Psion's then onto more web related stuff (when there was an internet) and mobile apps (Xamarin.Forms) for IOS and Android.
Happy
Happy
0 %
Sad
Sad
0 %
Excited
Excited
0 %
Sleepy
Sleepy
0 %
Angry
Angry
0 %
Surprise
Surprise
0 %

Average Rating

5 Star
0%
4 Star
0%
3 Star
0%
2 Star
0%
1 Star
0%

Leave a Reply