Electronic Circuits and Tutorials
Tutorials
Dictionaries
Projects
Facebook
Discover
Home > Engineering Projects > WiFi Analog and Digital Signal Sensor with MQTT protocol
Electronics Educational Practical
Engineering Projects

WiFi Analog and Digital Signal Sensor
with MQTT protocol

Author: Horacio Bouzas   Email: [email protected]

The brain: ESP8266 MCU

I have been working on a water level sensor for the rain barrels I have installed at home. The rain barrels feed drip lines into a vegetable garden. I wanted to track water levels through time, activate a pump at watering times, fill the barrel if it gets too empty. I thought again of using the ESP8266 Wifi microcontroller, but since I needed an Analog to digital converter I opted for the ESP8266 ESP-12 version (figure 1a).

Analog Digital Sensor Module ESP8266 MCU

Lets look at the ESP8266 principles first to refresh our minds.

The ESP8266 ESP-12 is a very small WIFI enabled microcontroller. It can be programmed in C by flashing it with the manufacturer’s (Espressif) software development kit (SDK). But it can also be programmed in LUA using the NodeMCU SDK (open source, just Google it or go to GitHub). LUA is a scripting language used widely in the gaming industry and I picked it to program the ESP8266 because of being compact, very high level and allowed rapid prototyping. The ESP8266 acts as an access point and/or a WIFI station, so once it is configured it acquires an IP address and then you can communicate with it via a web browser or a TCP connection (phone, tablet, computer, etc).

The ESP-12 has 9 GPIOs and an Analog Digital Converter (ADC). For this project we will only use the ADC and one GPIO.

There is plenty of material out there to get anyone going with this little wonder. The key things to know is that you will need a USB to serial module to initially talk to the ESP8266, be familiar
with serial communication and able to do some script programming. For USB to serial, any FTDI232 based module will pretty much work, but be careful as they are counterfeit FTDI232 that can render useless, make sure whatever you get is genuine. Then you need to choose a serial terminal to send commands to the serial module that will send commands to the ESP8266. Something like CoolTerm or SSCOM32 would do the job. I use CoolTerm mostly on the Mac. Also, when you start copying LUA code into the module, CoolTerm does a great job. With this brief introduction to the ESP8266, you can have a lot of fun prototyping all kinds of interesting WIFI projects.

Figure 2a shows the pins and connections on the ESP8266 ESP-12:
VCC: 3.3 Volts
CH_PD: Module enable, connect to VCC
RST: Resets the module when pulled to GND
UTXD: Serial transmit
URXD: Serial receive
GPIO: General purpose IO
ADC: Analog Digital Converter
GND: Ground

Principles of operation

The analog/digital sensor module reads analog data and digital data through its 2 input terminals.
Input analog data limits are zero VDC to 3.3VDC, and this maps into output values of 0 to 1024.
Input digital data limits are zero, for a digital zero, and 3.3VDC for a digital 1.
The module sends the value of the measured analog data periodically every Interval milliseconds, and it sends the value of the measured digital data when this changes from 0 to 1 or from 1 to 0. The user can also request the module to send the measured values of analog and/or digital data at any time by publishing a specific MQTT topic; more on this later.
The module provides a triggering signal whenever the digital data changes (Figure 1).
The module provides a triggering signal when the analog signal is less than a preset value or larger than a preset value (Figure 2).

Setting up the module using a web browser:
- Connect the 5V power
- Press board reset button
- From your computer, check available wireless networks and connect to a network which name
has the form ESP_STATION_xxxxxxx
- When prompted, enter the password to the ESP_STATION. The preset password is ‘espadmin’
- Wait until your computer successfully connects to ESP_STATION_xxxxxxx
- From your web browser and after station is connected enter the following address and WIFI
network SSID and password:
192.168.4.1/?SSID=Your_SSID&Password=Your_password&Server=Your_Server&Port=Your_Por
t&Interval=Interval_in_milliseconds&MinAnlg=min_analog_trigger&MaxAnlg=max_analog_trigge
r


Where:
    SSID= your WIFI router SSID
    Password= your WIFI router password
    Server=the IP address of the MQTT server to connect to
    Port= the MQTT server port (def=1883)
    Interval= the interval (in integer milliseconds) to send analog data to the MQTT server
    (def=5000 ms)
    MinAnlg= when the analog signal is less than min_analog_trigger, LED 1 turns on and terminal pin 1 turns on (def=300)
    MaxAnlg= when the analog signal is greater than max_analog_trigger, LED 2 turns on and
terminal pin 2 turns on (def=800)
    Interval= the interval (in integer seconds) to send analog data to the server
- Reset the board


Operating and communicating with the module

Once the module is connected to the WiFi router it will establish communication with the MQTT
server and port as specified above and will attempt to connect. Wait a few seconds and all 4 LEDs
will blink in sequence indicating a successful connection. If this fails, reset the board and wait a few seconds for the LED sequence. The module uses MQTT protocol for communication. MQTT topics are composed of a four letter acronym followed by the ESP822 chipid (the chipid is listed with your documentation), XXXXchipid

Once a connection with the MQTT sever is established, the module is ready for communication and
therefore reading analog and digital data and sending commands.

A typical MQTT instruction is composed of a topic followed by a message.

MQTT Topics and Messages
RANLchipid : this topic instructs the module to read a sample of the analog data and send it back via an MQTT topic and message. The module in response sends a topic and value as follows:
DANLchipid value ; you can get the analog value by subscribing to the topic DANLchipid and getting the value from the message
RDIGchipid : this topic instructs the module to read a sample of the digital data and send it back via an MQTT topic with the value as a message. The module in response sends a topic and value as
follows:
RANLchipid value ; you can get the digital value by subscribing to the topic RANLchipid and getting the value from the message
MANLchipid min_analog_trigger (min 0, max 1024, def 300): this topic allows the user to set the module’s minimum analog value used for triggering the LED and signal . The change takes immediate effect.
XANLchipid max_analog_trigger (min 0, max 1024, def 800):: this topic allows the user to set the module’s maximum analog value used for triggering the LED and signal. The change takes immediate effect.
INTEchipid Interval_in_milliseconds (min 500 ms, max 240000 ms, def 5000 ms): this topic allows the user to set a new interval in milliseconds for receiving analog data. The change takes immediate effect.
RESTchipid: this topic allows the user to reset the module remotely.

 

The source code

interval= 5000
minanl= 300
maxanl= 800
--dig_pin = 6   -- GPIO12

if file.open("servport.txt","r") ~= nil then
server=file.readline()
port=file.readline()
interval = tonumber(file.readline())
minanl =tonumber(file.readline())
maxanl =tonumber(file.readline())
file.close()
else
wifi.sta.config("","XXXXXXXX")
node.restart()
end

 gpio.mode(6,gpio.INPUT)
gpio.mode(6,gpio.INT)
gpio.mode(2,gpio.OUTPUT)
gpio.mode(1,gpio.OUTPUT)
gpio.mode(7,gpio.OUTPUT)
gpio.mode(5,gpio.OUTPUT)
gpio.write(2,gpio.LOW)
gpio.write(1,gpio.LOW)
gpio.write(7,gpio.LOW)
gpio.write(5,gpio.LOW)

mqttStatus = false

chipid = tostring(node.chipid())

m = mqtt.Client(  "ESP8266-" ..  chipid, 0, "user", "pwd")

function mqttConnect()
    m:connect(server, port, 0, function(conn)
                         print("Connected to MQTT:" .. server .. ":" .. port .." as " .. "ESP8266-" ..  chipid )
                         mqtt_sub()
              mqttStatus = true

gpio.write(2,gpio.LOW)
tmr.delay(500000)
gpio.write(2,gpio.HIGH)
gpio.write(1,gpio.LOW)
tmr.delay(500000)
gpio.write(1,gpio.HIGH)
gpio.write(7,gpio.LOW)
tmr.delay(500000)
gpio.write(7,gpio.HIGH)
gpio.write(5,gpio.LOW)
tmr.delay(500000)
gpio.write(5,gpio.HIGH)
tmr.delay(2000000)
gpio.write(2,gpio.LOW)
gpio.write(1,gpio.LOW)
gpio.write(7,gpio.LOW)
gpio.write(5,gpio.LOW)
     end)
 end

print "Connecting to MQTT broker 1. Please wait..."
mqttConnect()

function mqtt_sub()
m:subscribe("RANL" .. node.chipid() , 0, function(conn)
end)
m:subscribe("RDIG" .. node.chipid() , 0, function(conn)
end)
m:subscribe("MANL" .. node.chipid() , 0, function(conn)
end)
m:subscribe("XANL" .. node.chipid() , 0, function(conn)
end)
m:subscribe("INTE" .. node.chipid() , 0, function(conn)
end)
run_main_prog()
end

function publish_data(topic, payload)
if string.sub(topic, 1, 4) == "RANL" then
onAnalog()
elseif string.sub(topic, 1, 4) == "RDIG" then
onDigital()
elseif string.sub(topic, 1, 4) == "MANL" then
minanl=tonumber(payload)
print(minanl)
elseif string.sub(topic, 1, 4) == "XANL" then
maxanl=tonumber(payload)

print(maxanl)

elseif string.sub(topic, 1, 4) == "INTE" then
interval=tonumber(payload)
tmr.stop(4)
tmr.alarm( 4 , interval , 1 , onAnalog )
end
end 

function onAnalog()
adcval=adc.read(0)
m:publish( "DANL" .. chipid, adcval ,0 ,0 , function(conn)
end)
if adcval and adcval < minanl then
gpio.write(7,gpio.LOW)
gpio.write(5,gpio.HIGH)
elseif adcval and adcval > maxanl then
gpio.write(5,gpio.LOW)
gpio.write(7,gpio.HIGH)
else
gpio.write(7,gpio.LOW)
gpio.write(5,gpio.LOW)
end

end

function onDigital()
digval=gpio.read(6)
m:publish( "DDIG" .. chipid, digval ,0 ,0 , function(conn)
end)
if digval and digval == 0 then
gpio.write(2,gpio.LOW)
gpio.write(1,gpio.HIGH)
elseif digval and digval == 1 then
gpio.write(1,gpio.LOW)
gpio.write(2,gpio.HIGH)
else
gpio.write(1,gpio.LOW)
gpio.write(2,gpio.LOW)
end 

end

function run_main_prog()
gpio.trig(6, 'both', onDigital)
tmr.alarm( 4 , interval , 1 , onAnalog )

m:on("message", function(conn, topic, payload)
publish_data(topic, payload)
topic=nil
payload=nil
end )

m:on("offline",
               function(con)
        mqttStatus = false

print("Going offline" )
pub_sem = 0        
current_topic  = 1 
topicsub_delay = 50

        tmr.alarm(6, 1000, 1, function()
            if mqttStatus then
                tmr.stop(6)
            else
                mqttConnect()
            end
       end)

end)
end


Note: To report broken links or to submit your projects, tutorials please email to Webmaster