Ok, having blinking LED's connected to an ESP8266 SOC is nice but is not very useful in terms of information exchange and/or interaction. This blog builds a simple IoT application which measures temperature and humidity and returns the measured values. This build is relatively straightforward build as we can leverage DHT22 temperature-humidity sensor and the corresponding native NodeMCU dht module.
We need to wire up the DHT22 sensor to the NodeMCU which will provide ground and power - black and red wires respectively. Second the sensor data must be captured using the GPIO4 pin - purple wire. As this is an IoT use case I would like to enable deep sleep capabilities to conserve power in between sensor readings - yellow wire. The breadboard sketch is depicted below.
With the wiring in place we move on to the coding portion of this prototype. This blog assumes you have successfully flashed the NodeMCU with the modules necessary for this. For more details, check out my blog post Flash NodeMCU for more information.
The NodeMCU firmware has a module available to interact with DHT sensors. The code snippets below fully utilize the functions provided by this module. In addition, the wifi module is used to connect the ESP8266 SoC onto the internet.
The variables required for this sketch are stored in a separate file for easy maintenance. In this case we need variables for the NodeMCU wifi and dht modules. A constant is declared for the duration of the deep sleep cycle in milliseconds.
--[[ config.lua | Tiest van Gool Global variables definitions for usage across various lua scripts --]] --wifi module wifi_ssid = "YOUR NETWORK" wifi_password = "YOUR PASSWORD" --dht module dht_pin = 2 -- Pin for DHT22 sensor (GPIO4) dht_temp_calc = 0 -- Calculated temperature dht_humi_calc = 0 -- Calculated humidity --sensor reading interval dsleep_time = 60000 --sleep time in microseconds (us) -- Status Message print("Global variables loaded")
With the necessary variables defined we move forward with the code that does the heavy lifting. If we examine the code below closer we can identify 3 different functions:
- First a connection is made to the wifi network using NodeMCU's
wifimodule. Without connectivity to the network no further actions are taken.
dhtmodule to read the temperature and humidity information as collected by the dht22 sensor. Once the information is retrieved its outputted in the serial window.
- The routine
func_exec_loopexecutes the logic as described previously and once successfully completed initiates deep sleep mode using the
node.dsleepcommand. Upon waking up the ESP8266 unit starts up and initiates the init.lua script.
--[[ dht22.lua | Tiest van Gool Script connects to internet through NodeMCU wifi module. Once connection is established dht module and temperature and humidity is retrieved. --]] -- Load global user-defined variables dofile("config.lua") -- Connect to the wifi network using wifi module wifi.setmode(wifi.STATION) wifi.sta.config(wifi_ssid, wifi_password) wifi.sta.connect() -- Read out DHT22 sensor using dht module function func_read_dht() status, temp, humi, temp_dec, humi_dec = dht.read(2) if( status == dht.OK ) then -- Integer firmware use this code print("DHT Temperature: "..math.floor(temp).."."..temp_dec.." C") print("DHT Humidity: "..math.floor(humi).."."..humi_dec.." %") -- Float firmware uuse this code -- print("DHT Temperature: "..temp.." C") -- print("DHT Humidity: "..humi.." %") elseif( dht_status == dht.ERROR_CHECKSUM ) then print( "DHT Checksum error" ) elseif( dht_status == dht.ERROR_TIMEOUT ) then print( "DHT Time out" ) end end -- Execute sensor reading and enter deep sleep function func_exec_loop() if wifi.sta.status() == 5 then --STA_GOTIP print("Connected to "..wifi.sta.getip()) tmr.stop(1) --Exit loop func_read_dht() --Retrieve sensor data print("Going into deep sleep mode for "..(dsleep_time/1000).." seconds.") node.dsleep(dsleep_time*1000) else print("Still connecting...") end end tmr.alarm(1,500,tmr.ALARM_AUTO,function() func_exec_loop() end)
NodeMCU uses init.lua as the auto executable which is invoked upon boot-up. The script below calls the dht22.lua. It contains a 15 second delay to allow for cancelling the excution in the situation of an error in order to interrupt and endless loop.
--[[ init.lua | Tiest van Gool Init.lua is automatically executed on bootup of the NodeMCU. This launcher file loads the actual init_XYZ file only when everything has been tested and debugged. A 15 second delay has been added in case of error and enable abort. --]] -- Set local variable FileToExecute="dht22.lua" -- Set timer to abort initialization of actual program print("You have 15 second to enter file.remove('init.lua') to abort") tmr.alarm(0, 15000, 0, function() print("Executing: ".. FileToExecute) dofile(FileToExecute) end)
With all the Lua based scripts they can be transferred to the ESP8266 using Luatool. If all scripts have been successfully transferred and NodeMCU is restarted the result should be something as depicted in the screenshot below.
Even though wifi connectivity is established its not leveraged for communication of the sensor data. The next blog entry will introduce the NodeMCU's mqtt module. MQTT is a machine-to-machine (M2M)/"Internet of Things" connectivity protocol. Leveraging this protocol the DHT22 sensor data will be wireless communicated to a broker/server for visualization without a serial communication channel.