I thought it would be a good experiment to install a few sensors in my neighborhood monitoring the water level in several streams. As i live near the sea, i expect them to show the tide coming in, and also showing higher water levels during rainy days. So far i have installed sensors at 2 different locations, and this is a typical curve, showing a high tide coming in for a few hours.

This 2 week graph shows the effect of heavy rains on 23 March raising the base level with around 10cm from 24 March, with a similar pattern on 28 March.


The sensor node consists of:

  • a custom PCB with mainly through-hole components for manual soldering
  • an ESP32 -WROOM as microcontroller
  • an Ai-Thinker Ra-01H LoRa radio module (based on SX1276)
  • a V71 JSN-SR04T ultrasound sensor and module
  • a pair of 18650 Li-ion cells with a TP4056 charger/protection module
  • a custom 3D printed box (my first ever design, SLA printed by JLC)

I chose the ESP32 for microcontroller because it has plenty of memory, and the LoRaWAN stack is quite large. I had started with an Arduino UNO but ran into memory limits compiling a simple library example of the excellent MCCI Arduino LoRaWAN library. Also, the ESP32’s WiFi allows me to do OTA firmware updates, more on that later. I did not include a USB/TTL converter on the PCB; i upload the initial firmware using a 4 pin header (3V3, RX, TX, GND) and the 2 push buttons (GPIO0 and RESET). For voltage regulator, i’m using an MCP1826 3.3V LDO which is overkill (1A) but that’s what i had in stock. I should probably use a 3V LDO to squeeze some more range out of the Li-ion cells.

The Ra-01H LoRa module has an SPI interface, and easy mounting hole for a spiral antenna. It is available in 803-930MHz version, which matches the Hong Kong LoRaWAN frequency plan of 923-925MHz.

The JSN-SR04T waterproof ultrasound sensor and module (aliexpress link, not my source) works on 3-5.5V, has a range of up to 6m, and a UART interface (serial) which sends us a distance value, rather than having to calculate the distance based on a timed pulse as is the case with cheaper sensors like the HC-SR04 often used with Arduino. The sensor draws max 8mA so to reduce its power consumption, i connected its VCC to a GPIO pin to switch it on/off when needed. The module has 3 modes: (1) trigger/echo pulse as other cheap sensors (2) Serial output with continuous readings (3) Serial output on demand. I had to solder a 120K resistor to the module in order to activate mode (3). The cable from the board to the sensor is quite long (2m), i tried to cut and shorten it but for some reason that did not work so i have to stuff the entire cable into the box.

I installed 2 of these (blue box) at locations where there happen to be government sensors as well (red box). In the first location, there is a wired government sensor, and i attached my box to a pipe with zip ties.

In the second location, there is a government LoRaWAN sensor (DecentLab), and i mounted my sensor on a bracket attached to the stone wall.


These sensor nodes transmit a data packet (LoRaWAN uplink) every 10 minutes, with a payload of 4 bytes: a 16-bit integer for the battery level in mV, and a 16-bit integer for the distance in mm. They are configured as devices on the public The Things Network and their transmissions are captured by the TTN LoRaWAN gateway installed on my roof. In the TTN console, i can configure these devices and see the data coming in, as in the below screenshot. I have defined a payload formatter that extracts the battery level and distance from the 4-byte payload into a JSON.

To store and visualise the data, i like using ThingsBoard.io, a powerful open-source IoT platform. I am running this on an Ubuntu server in the Alibaba cloud. TTN has an MQTT integration that allows an MQTT client to subscribe to uplink messages. I have a python script running on my cloud server that subscribes to these device uplink messages from the TTN MQTT server, and then publishes the JSON with some additional LoRaWAN metadata to ThingsBoard.

Below is an example of a dashboard showing recent data points, including the LoRaWAN frame counter (you can see that some packets are lost), the frequency of the transmission, its RSSI, Spreading Factor (SF), Signal-to-Noise-Ratio (SNR), and airtime (the duration of the actual transmission). The devices are using ADR (adaptive data rate), and because this one is relatively close to the gateway, it moves to SF7 which means the shortest possible airtime, so less power consumption. The other device is at SF9, with 3 times longer airtime (0.165s).

I’m really curious to see how long these devices can run on a pair of 18650 Li-ion cells. The 18650 i am using are not new, they are harvested from laptop battery packs, but i did test their capacity and they are around 4000mAh for each pair. To be continued.

LoRaWAN river level sensors

One thought on “LoRaWAN river level sensors

Leave a Reply

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