Monday 25 January 2016

Completed ESP8266/NodeMCU temperature and humidity sensor

Credit where credits due, I have taken a lot of inspiration (and borrowed some LUA code) from this blog: https://odd-one-out.serek.eu/esp8266-nodemcu-dht22-custom-modules-firmware/

Anyway, the prototype has been stable for over a week happily posting MQTT messages every minute with temperature and humidity readings. I've got nothing permanent logging or displaying MQTT at the moment, but that's another project in itself :-)

Time to tidy it up and put it in an enclosure. The one I had in mind was £4.09 from maplin and seemed big enough to fit the NodeMCU board and a small USB phone charger. Everything will be contained in one unit that plugs into the wall. The micro USB port for the NodeMCU board will sit near the top so I can re-flash and diagnose issues with it mounted inside the enclosure. I also bought some veroboard/stripboard and heatshrink for tidying wires up with.

First of all, I installed Fritzing (an awesome piece of software) so I could make some nice plans to work from instead of the messy breadboard of parts and wires that was running the prototype. There is an option in Fritzing to create printed PCB layouts, but I won't bother with that unless I mass produce more than a few of these.

Breadboard layout
Nice and simple. There is one DHT22 sensor onboard (to go inside the enclosure) and the second sensor will attach with a 3.5mm headphone cable so I can put it in the room next door, or further away from the enclosure.
Circuit Diagram
No power connectors visible on these diagrams, but I will just attach the +5V from the phone charger to Vin and GND on the NodeMCU. Also, the resistors can be removed from the DHT22 sensors and they seem to work absolutely fine.


By all means, this is not a direct "howto" guide, and there are quite a few details missing, but here is a rough document (including photos) of how I did it:


Working prototype and most of the parts needed to make it properly

Probably the toughest bit, dismantling an old phone charger

There is just enough space for the NodeMCU and charger board

I added a second DHT22 to the prototype and modified the LUA code

Success! Temperature and Humidity from 2 sensors publishing to MQTT

I broke the stripboard while cutting it, but still had enough working pins

2 thick wires for Live and Neutral mains current...

... soldered to the old phone charger

adding a few wires to the stripboard to complete the circuit

it all fits inside! I added a DIN switch for the deep sleep pin connection

soldering the NodeMCU in place. No going back now!

The finished result. Not very pretty, but it works and will fit in the case

DHT22 sensor on an old headphone cable

Everything squeezed inside the case side-by-side with the prototype 

As you can see, it works. I forgot to take a final photo of it completed. All I added was some electrical tape over the PSU and plenty of hotglue to keep it all from moving around.

There were a few bugs in the Lua code, so I split it into 2 separate files. init.lua with a 2 second delay, which can be interupted with tmr.stop(0), which then loads and executes temp.lua containing the actual code that collects temperature and humidity readings and publishes them to my MQTT broker mosquitto.

I'll write more about the code, and MQTT data, in a separate post. For now it's happily sat plugged into a mains socket, pinging off it's readings every minute until I do something proper with the data.

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.