Monday 11 January 2016

Building remote temperature sensors with Nodemcu/ESP8266 DHT22 and MQTT

The Concept

I knew I'd need remote temperature and humidity monitoring for my house, and it'd need to be wireless. I've previously used DHT22 sensors directly connected to a raspberry Pi at work so knew they were cheap and would work.

But how to connect them wirelessly? Over the last few years I've considered Xbee (Zigbee) modules like: (I even bought a book about how to make your own wireless mesh networks) but it looked very complex and the sensors wouldn't directly talk to the radio modules.

I recently found the wonderful MySensors website, which uses Arduinos as sensor controllers and a gateway, and it was compatible with most of the Home Automation platforms I've considered using (e.g. HomeAssistant, OpenHAB, etc) so I asked for an Arduino starter kit for Christmas 2015 which included some useful parts and an Arduino Uno.

The Solution

But then I realised, thats a lot of microcontrollers! I had seen the ESP8266 radio chip mentioned as a module to connect Arduinos together, but then I found out the ESP8266 can be loaded with Arduino code itself! Further research revealed the perfect solution for combining a WiFi connection, lots of digital IO connections (for DHT22 sensors) and arduino compatible firmware: The NodeMCU


So, off to Google I went, and searching for DHT22, MQTT and Nodemcu eventually revealed the following blog entry: https://odd-one-out.serek.eu/esp8266-nodemcu-dht22-mqtt-deep-sleep/

Perfect! So I ordered 2 NodeMCU boards from eBay and some DHT22 sensors, and waited for them to arrive and for a quiet weekend when I could plug them in. That day was yesterday (Sat 9th January 2016) and it wasn't as easy as the blog entry I'd read had implied! Below is what happened:

The Prototype

So, to start with I have:
  • 10 year old MacBook Pro running OS X 10.6.8 (which can't be upgraded) 
  • Breadboard and all relevant cables
  • NodeMCU Dev Kit 1.0 module

The instructions I followed were slightly different, as the NodeMCU LUA firmware now includes DHT support: https://odd-one-out.serek.eu/esp8266-nodemcu-dht22-custom-modules-firmware/

1) Check the NodeMCU boards work

Luckily the eBay seller I bought pre-loaded them with an Arduino program to scan for wireless networks and print it out on the serial console. So, connect to the NodeMCU and read it's output. Sounds simple, doesn't it? Not on a 10 year old MacBook Pro!

https://github.com/nodemcu/nodemcu-devkit/wiki/Getting-Started-on-OSX was where I started, but I quickly found I had none of the software or tools installed.

  1. First download esptools to flash the Nodemcu firmware to the development board. Doesn't work. No python installed!
  2. Download python2.7
  3. Download the correct usb serial port driver to connect to the nodemcu board (following these instructions http://plugable.com/2011/07/12/installing-a-usb-serial-adapter-on-mac-os-x)
  4. Don't mess around with screen or telnet, download coolterm (lucky compatible with OS X 10.6.8) to see the serial port output. 
Awesome! Now I can connect to the nodemcu board and see the output of the test program preloaded by the ebay seller. It works. Now, onto making it do what I want.

2) Flash the NodeMCU boards with the latest firmware

Based on the blog post I read, it seems a lot simpler to code in LUA, so I want to flash the latest firmware which also includes native MQTT and DHT22 support. Full instructions are at: 
https://odd-one-out.serek.eu/esp8266-development-kit-nodemcu-firmware-update-os-x/

I built a custom firmware at http://nodemcu-build.com/

With no components attached to the nodemcu, it's time to wipe it and load the custom firmware. This is quite simple and worked first time. I hit the reset button on the nodemcu and got the following boot up message in coolterm:

NodeMCU custom build by frightanic.com
.branch: master
.commit: c8037568571edb5c568c2f8231e4f8ce0683b883
.SSL: false
.modules: node,file,gpio,wifi,net,tmr,uart,mqtt,dht
 build .built on: 2016-01-09 15:59
 powered by Lua 5.1.4 on SDK 1.4.0
lua: cannot open init.lua

Hurrah! Blank firmware works! Now to program it to read the DHT22 sensor and report the data with MQTT.

3) Program the NodeMCU 

The preferred software to program the board is esplorer. I very quickly I discovered I can't run it because I don't have Java 7 on my mac. Officially it's not supported by Apple or oracle on anything older than OS X 10.7. Some Google searching later, and this turns out to be a mostly political issue, and there is a way to force Java 7 to install on OS X 10.6.8 so cant run eplorer (to program the mcu)

I found the following instructions to trick the java installer that I was running OS X 10.7 lion: http://jksha.blogspot.se/2013/09/java-7-and-snow-leopard-osx-106.html

Some scary config file editing later and I've got Java 7 installed, but esplorer still didn't work. It turns out I downloaded and install jre (java runtime) when really I needed jdk (java development kit). Whoops. So try again.

Fake the OS X version again, download Java 7 DK, install it, revert to correct OS X version.... still doesn't work! java-version in terminal reports version 6. I've not restarted the MacBook Pro yet, so that can't hurt.

One restart later, and Java 7 is working, but when opening esplorer I now get the error:
NSInvocation: warning: object 0x108b8a3c0 of class 'ThreadUtilities' does not implement methodSignatureForSelector: -- trouble ahead

Whoops. Sounds pretty nasty! Some more Google searching and it turns I can't use anything later than Java DK 1.7u25 on osx 10.6.8 otherwise it just spits out the error above.

Ugh. Repeat above steps, but this time I need an account to log into the Oracle Java download site, 
download the correct version Java SE Development Kit and install it. Then, open esplorer with the correct java version using the command:
/Library/Java/JavaVirtualMachines/jdk1.7.0_25.jdk/Contents/Home/bin/java -jar ESPlorer.jar 

SUCCESS!

Now, I can use the code from https://odd-one-out.serek.eu/esp8266-nodemcu-dht22-mqtt-deep-sleep with the IP address, WiFi and MQTT details updated to match my network. Load it into an init.lua file, upload it to the NodeMCU board, hit the reset button and away it goes!

4) Check the remote sensor works

There should be some debugging output via the serial port, but this only worked for me if I uploaded the code and executed it. After a hard reset of the NodeMCU board it didn't output anything over the serial port. Instead, I watched the MQTT feed with mosquitto_sub and saw the following:

ESP8266/temperature 20.8
ESP8266/humidity 61.1
ESP8266/temperature 20.7
ESP8266/humidity 61.1
ESP8266/temperature 20.7
ESP8266/humidity 61.1

Hurrah! Prototype complete! For now I'm saving the raw MQTT data into a text file with timestamps, so I can verify it works and manually check temperatures for different times of day.

5) Next Steps

To complete the sensors and set them up permanently I need to:
  • Change the code to use 2 sensors attached to one NodeMCU board, one on an extension cable into the room next to the sensor. This allows monitoring of 2 rooms from one board and saves on components.
  • Find a 5V power supply (possibly an old smartphone charger?)
  • Buy an enclosure for the board, and solder and wire it up properly. Possibly this one: http://www.maplin.co.uk/p/vented-psu-enclosure-4-n06kh
  • Setup OpenHAB to subscribe to the MQTT feed and process/display it.
  • Enable persistance in OpenHAB to record historical data.
  • Create some pretty graphs.

No comments:

Post a Comment