Got It! ESP8266 + LUA + MQTT + DHT22 Working Nicely!

I wasn’t ready to post anything until I got it working reliably. Since last post I received several different version of the ESP boards. I’ll be using the ESP-07 for this demo. Got 10 pcs. for $30. Not bad!

esp-07

  1. I FLASHED the ESP using ESP-Flasher with the latest binary from NodeMCU.
  2. Connected to ESP with LuaLoader with the minor glitch of LuaLoader not showing me the actual port that the ESP was connected to. I’m sure there is a better solution but what I ended up doing was going to my Win Devices and mathing my USB FTDI to the ports available on the LuaLoader. All is good!
  3. After many nights of trying to find the right combination of code that would successfully PUBLISH through the MQTT, I ffinally came upon a solution which I modified to meet my requirements. The original code is at:http://www.esp8266.com/viewtopic.php?p=7993#p7993 by a chap with the handle calgalli.
  4. I ended up experimenting using the test.mosquitto.org/gauge/ site to send data from the ESP to a MQTT broker. There will be interruptions from others users and experimenters, as well as the random data the site itself puts into the indicator.
  5. It works like a champ! I’ve been running it a few hours with no dropouts.

Here’s the Code

I make no claim to its reliability and little or no claim in making it work. This credit goes to the original author. I’m sure there are brighter people out there that can vastly improve this. Sorry for the formatting – it looks a lot better in notepad++

Filename: init.lua
Needs: dht22.lua

=====================================

wifi.setmode(wifi.STATION)
wifi.sta.config(“linksys”,””)
print(wifi.sta.getip())

m = mqtt.Client(“Whatever”, 120)
m:lwt(“/lwt”, “Whatever”, 0, 0)

— Variables
tempc=0
sf = 0
humi=”XX”
temp=”XX”
fare=”XX”
bimb=1
PIN = 4 — data pin, GPIO2

m:on(“offline”, function(con)
print (“Checking MQTT server…”)
connectionCheck()
print(node.heap())
end)

— on publish message receive event
m:on(“message”, function(conn, topic, data)
print(topic .. “:” )
if data ~= nil then
print(data)
end
end)

function Pub_DHT22()
if sf == 0 then
sf = 1
ReadDHT22()
m:publish(“temp/random”,tempc,0,0, function(conn)
sf = 0
end)
end
end
–load DHT22 module and read sensor
function ReadDHT22()
dht22 = require(“dht22″)
dht22.read(PIN)
t = dht22.getTemperature()
h = dht22.getHumidity()
–humi=(h/10)..”.”..(h%10)
temp=(t/10)..”.”..(t%10)
tempc=temp
–fare=(9*t/50+32)..”.”..(9*t/5%10)
–print(“Humidity: “..humi..”%”)
–print(“Temperature: “..temp..” deg C”)
–print(“Temperature: “..fare..” deg F”)
— release module
dht22 = nil
package.loaded[“dht22”]=nil
end

function connectionCheck()
tmr.stop(5)
if wifi.sta.status() == 5 and wifi.sta.getip() ~= nil then
m:connect(“test.mosquitto.org”, 1883, 0, function(conn)
print(“connected”)
m:subscribe(“temp/random”,0, function(conn)
tmr.alarm(3, 3000, 1, Pub_DHT22)
end)
end)
else
tmr.alarm(5,1000,1,connectionCheck)
print(“Retry!!”)
end
end

tmr.alarm(5,1000,1,connectionCheck)

==========================================================

What it Does

I am reading the value of the temperature (C) with the ReadDHT22 function.

This records the value in tempc variable. Subsequently this value is published to test.mosquitto.org for MQTT message transfer. The mosquitto site operates a graphic dial that reads incoming messages and displays the value on the dial. Keep in mind that this is open to everyone so you’ll see the dial jitter when other values are sent.

I later set up my own “dial” using a publicly available MQTT broker which I’ll describe in a later post.

mqttdial

The biggest hurdle for me understanding how to make this work was the use of delays and timers. I’ve been programming since the time I bought an ATARI 800 and got a copy of figFORTH. Best investment in both computer and software I ever made. I owe all the basics of my learning to the the ATARI 800, especially when I started to use the joystick ports as I/O and making stepper motors move and lights blink.

The delays in LUA, as also the case in say Delphi, consume all the processing time of the cpu. Delphi has a call that allows tou to break-in and process data from time to time. It looks like LUA (as far as ESP8266) does not. So, as I gather, many programmers are using the tmr.alarm call. This will allow a short delay while still allowing interrupts to take place. as in the code above the timr.alarm call:

tmr.alarm(5,1000,1,connectionCheck)

waits for 1 second with the connectionCheck function stopping the timer upon entry. Doing it this way (I assume) allows the

m:on(“message”, function(conn, topic, data)
print(topic .. “:” )
if data ~= nil then
print(data)
end
end)

to still cause an interrupt anytime a message is available – both sent from us and sent by others to the test.mosquiito.org site.

The     tmr.alarm(3, 3000, 1, Pub_DHT22)    line will publish the temperature every 3 seconds. The sf=1 and sf=0 if statement essentially checks and see if the data was published from the last call. The interrupt cause by m:on(“offline”, function(con)….. call checks the WiFi connection any disables the publishing until the WiFi reestablishes a connection.

Most of my time was staring at the screen until an image started to appear as to how Lua and ESP8266 works. I’m not familiar with the LUA syntax and that often got in the way. But so far this project has taught me a lot.

DHT22 connected to +, – and GPIO2
CH_PD connected to +V
FTDI connected to +, -, TXD, RXD
REST connected to +V

Hope this helps. I currently have open comments turned off. Got hit by a lot of junk (Dah!) If you don’t mind registering, please leave a comment.

Working on my next post of connecting to your own indicator dial.

Leave a Reply