Publishing MQTT messages from a NodeMCU – Soil Moisture Sensor


In this article I’d like to share the experience of building a soil moisture sensor built on NodeMCU which publishes MQTT messages (payload) to a cloud service.

This article is also a soft launch of a preview of service. We use it for our DIY projects to register json payload and visualise it is a very simple way. This allows us to “debug” our sensors. If you wish to get access to let us know by sending an email to We will provide you with the user account and instruct on how to start your project.
DISCLAIMER: We are not responsible for any data privacy or availability of the service at the moment.

Now back to the “experience” …

The set up

The sensor is mounted on the flower pot
Moisture Sensor Mounted on a pot

Every 10 minutes is sends MQTT payload to sensors list sensor records

I can check the sensor data records using the telegram bot telegram bot

This is how the components look like
NodeMCU pins on a breadboard

Moisture Sensor Pins connection

Moisture Sensor in a box

The code

I assume you have a nodeMCU with the firmware burnt like explained in the post earlier. The firmware version that is used in this example is the following: nodemcu_float_0.9.6-dev_20150704.bin

This is the code for init.lua and moisturesensor.lua .
As a best practice, I don’t put the main code to int.lua file so that I can play with the NodeMCU module when the main code has some loops or timers. Before going to “production” I just put dofile("moisture sensor.lua") to init.lua to make sure the main code runs when the device is powered.



To configure the code for your project you need to specify the following:

  • {WIFI_SSID}, {WIFI_PASS} – the name of your WiFi access point and a password to it;
  • {INTERVAL} – the interval in milliseconds for the timer. The code will send MQTT messages every {INTERVAL} milliseconds;
  • {MQTT_CLIENTID} – any unique string to identify the MQTT client;
  • { USERNAME}, { PASSWORD} – the MQTT server username and a password;
  • {SENSOR_APIKEY} – the sensor apikey on Feel free to modify the topic to any other when not using;
  • {MQTT_PORT} – a port of MQTT service.

The code above explained …

Configuring the NodeMCU as a WiFi station trying to connect to WIFI_SSID access point using WIFI_PASS password.

Every 1 second we check that the IP is provided by access point DHCP. When given we create the MQTT client and connect to MQTT server.

In the following code the call back function register_main_timer() is provided for the case when connected successfully to MQTT server:

In the following part tmr.ALARM_AUTO means that timer doesn’t stop when once triggered. send_moisture_mqtt is called when timer is triggered.

And at last, we read the analogue input on NodeMCU to which a moisture sensor is attached. The MQTT json message is published to a defined topic with QoS = 1.

Referenced articles and documentation:
Official NodeMCU documentation on MQTT Module
Official NodeMCU documentation on Wifi Module
Official NodeMCU documentation on Timer Module
Lua – Strings Tutorial

Facebook Comments

Leave a Reply

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