Ok, my previous blog entry outlined how to make the NodeMCU board a lot more useful by adding the DHT22 sensor which captured temperature and humidity. This is nice but does require a serial connection between my Linux machine and the NodeMCU board to make the information measured visible. Requiring a hardwired serial cable to establish connectivity made this prototype a lot less useful in the world of IoT. The objective of this blog post is to 'Cut the Serial Cord' and go wireless. Here is where the ESP8266 chipset shines with its integrated wifi capability. Lets see whether it can become a full blown, enterprise grade IoT device.
This blog post builds upon the scripts created in the previous blog post by adding wireless communication using the MQTT protocol and corresponding NodeMCU module.
MQ Telemetry Transport (MQTT) is an open source machine-to-machine (M2M)/"Internet of Things" connectivity protocol. It was designed as an extremely lightweight publish/subscribe messaging transport. It is useful for connections with remote locations where a small code footprint is required and/or network bandwidth is at a premium. -- MQTT.org
As far as IoT protocols go, MQTT is not the only kid on the block, others protocols worth mentioning: HTTP, WebSocket, XMPP and CoAP. If interested in learning more about these protocols, I recommend the article by Micrium, People Internet vs. Device Internet. As far as IOT goes I favor MQTT as it was designed to deliver reliable messaging over unreliable networks. More information on the origins of MQTT (formerly MQ Telemetry Transport) can be found here. In this blog post discusses how to enable communication using this protocol.
The essence of the MQTT protocol is the publish/subscribe (pub/sub) pattern which is an alternative to the traditional client-server model. The main difference is that in a client-server model, the client directly communicates with the end point where as in a pub/sub model such direct link does not exist. Instead a clients who is sending a message (the publisher) is decoupled from another client(s) who is receiving the message (the subscriber). A third component: the broker is known by publisher(s) and subscriber(s) and filters all incoming messages and distributes them accordingly. The MQTT protocol resembles a hub-and-spoke model.
When reviewing he NodeMCU mqtt module documentation it is mentioned that the client adheres to version 3.1.1. of the MQTT protocol. As these protocols are not backward compatible a message broker which is configured for this version is mandatory for establishing connectivity with the device.
For the purposes of this blog I have opted for Mosquitto, an open source (EPL/EDL licensed) message broker that implements the MQTT protocol versions 3.1 and 3.1.1. This section describes the steps to deploy the message broker locally on an GalliumOS/Ubuntu Linux environment. Alternatively online message broker services are available such as the Mosquitto Test Sever or HiveMQ.
The latest Mosquitto message broker can be installed from the Mosquitto PPA which is actively being maintained by Roger Light, the founder of the Mosquitto broker. First order of business is to add the untrusted PPA as software source to the package manager, install the necesarry software packages and validate the broker is up and running.
#Add Mosquitto PPA as untrusted software repository sudo apt-add-repository ppa:mosquitto-dev/mosquitto-ppa sudo apt-get update #Install various Mosquitto packages #Mosquitto message broker sudo apt-get install mosquitto #Mosquitto client development libraries sudo apt-get install libmosquitto-dev #Mosquitto terminal client sudo apt-get install mosquitto-clients #Validate Mosquitto broker is running sudo service mosquitto status
If the script executed successful you should see an active mosquitto service as depicted in screenshot below. Note that the status message mentions mosquitto MQTT v3.1 message broker. This does not mean that protocol version 3.1.1 as the latest version of MQTT support both protocols.
In order to test the message broker we can open a terminal window and enter the following command
mosquitto_sub -t "mqtt-test" -v. This command subscribes the terminal session as a client to the topic mqtt-test.
In a second terminal session enter the command
mosquitto_pub -t "mqtt-test" -m "Hello MQTT World!". This terminal session acts as a publishing client and publishes the message 'Hello MQTT World!' to the topic mqtt-test. If the message broker is working successfully the message published should be visible to the subscriber client terminal session.
The NodeMCU firmware has a module available to establish a MQTT client. 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 config.lua file is extended with several additional variables and constants required for MQTT connectivity.
--wifi module wifi_ssid = "YOUR NETWORK" wifi_password = "YOUR PASSWORD" --mqtt module mqtt_broker_ip = "YOUR LOCALHOST IP" mqtt_broker_port = 1883 mqtt_username = "" mqtt_password = "" mqtt_client_id = "" --dht module dht_pin = 2 -- Pin connected to DHT22 sensor dht_temp_calc = 0 -- Calculated temperature dht_humi_calc = 0 -- Calculated humidity mqtt_temp = 0 -- Temperature for publication mqtt_humi = 0 -- Humidity for publication --sensor reading interval dsleep_time = 60000 --sleep time in us -- Status Message print("Global variables loaded")
This script is an extension for the dht22.lua script. A line of code is added that creates the MQTT client for the ESP8266 device which will connect to the message broker identifying itself by the ESP chip ID:
m = mqtt.Client(node.chipid(), 120, mqtt_username, mqtt_password).
An additional function is added that establishes the connection and publishes the temperature and humidity captured by the sensor:
func_mqtt_pub(). This function executes 3 commands:
- m:connect - creates the connection between the MQTT and the message broker
- m:publish - publishes the values measured by the DHT22 sensor to the topics ESP8266/temp and ESP8266/humi.
- node.dsleep - enters deep sleep mode, wakes up when timed out.
-- 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() -- Establish MQTT client m = mqtt.Client(node.chipid(), 120, mqtt_username, mqtt_password) -- 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 using this example print("DHT Temperature: "..math.floor(temp).."."..temp_dec.." C") mqtt_temp = math.floor(temp).."."..temp_dec print("DHT Humidity: "..math.floor(humi).."."..humi_dec.." %") mqtt_humi = math.floor(humi).."."..humi_dec -- Float firmware using this example -- 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 -- Publish temperature readings and activate deep sleep function func_mqtt_pub() m:connect(mqtt_broker_ip, mqtt_broker_port, 0, function(client) print("Connected to MQTT broker") m:publish("ESP8266/temp",mqtt_temp,0,0, function(client) print("Temp message published") m:publish("ESP8266/humi",mqtt_humi,0,0, function(client) print("Humi message published") print("Going into deep sleep mode for "..(dsleep_time/1000).." seconds.") node.dsleep(dsleep_time*1000) end) end) end) end -- Capture and publish sensor reading and enter deep sleep function func_exec_loop() if wifi.sta.status() == 5 then --STA_GOTIP print("Connected to "..wifi.sta.getip()) func_read_dht() --Retrieve sensor data func_mqtt_pub() --Publish MQTT messages and go to sleep tmr.stop(1) --Exit loop else print("Still connecting...") end end tmr.alarm(1,500,tmr.ALARM_AUTO,function() func_exec_loop() end)
The init.lua script should be modified to execute the newly created mqtt script by modifying the following command:
FileToExecute="mqtt.lua". Once all the scripts have been uploaded to the NodeMCU device its demo time. Disconnect the serial cable from your laptop and insert it into a wall socket using a 3.3V/5V USB power adapter.
On the machine which contains the Mosquitto message broker open a terminal window and subscribe to the ESP8266/# topics:
mosquitto_sub -t "ESP8266/#" -v. The # symbol is considered a wildcard thus subscribing to both the ESP8266/temp and the ESP8266/humi topics. If everything went well the temperature and humidity are received by the local client's wireless through the MQTT protocol subscription!
As you can see MQTT is a powerful protocol, easily scalable and reliable - a perfect protocol for IoT appliance. Unfortunately this protocol is not (yet) supported by the Hana Cloud Platform ("HCP"). Next installment will focus on the HTML and WebSocket protocols and establish connectivity with the HCP.