Wednesday 4 November 2015

NodeMCU + DHT22 (ESP8266) wifi thermometer/humidity sensors pt1

Wifi temperature / humidity sensor for under £20

Overview

So I travel a lot, and want to know what's happening in the house whilst I am abroad.
I've researched and there are many solutions out there (like here or here), but mostly they are way, way over priced at over £150 EACH per unit.

I need at least 5 units, for the bathroom, kitchen, boiler room etc. so even doing it with a raspberry pi would have been pricey at around £40-50 per 'sensor' (using the DHT22 for readings), so an outlay of about £250.

What I have found is something even better. The ESP8266. This is a self contained wifi module with built in TCP/IP stack for around £3 and under the size of a 50pence piece. Whoa - cheap eh? Ok, so the issue here is that it can't do a 5v-3v logic shift nor can I be bothered to figure out the electronics to step it down and connect it to USB TTL etc.

So.... I researched a bit more and there is a board that combines the ESP8266 and the step down and the USB TTL and allows me to either publish data via a message queue or host a webserver! This is the NodeMCU

Fantastic little thing that does everything you need it to + can be powered from a micro USB connection.

Parts list

ok so the parts list (you may not need to purchase everything, as you may have some parts already)
1 x NodeMCU (Amazon or ebay) - Beware of the version you get tho! Check the PCB colour and size.
1 x DHT22 temperature/humidity sensor (Amazon or ebay)
A breadboard /protoboard to prototype stuff (pimoroni) - you'll solder it onto this.
A solderless breadboard to test things work (pimoroni)
Soldering iron
Micro USB cable for connecting to a PC
some cheap micro usb charger
Wires for testing (Jumper jerky makes it easier)
Wires for permanent installation (pimoroni)

Total cost of the above is about £30 for the first unit. Cost of the 2nd unit will be about £13, 3rd unit about £13 too, so for 5 units, it's about £16 each. Not bad

Circuit diagram

 

Dev software

ESP software - for loading up LUAs and code

Firmware

Download the firmware

Flashing firmware

config tab
select first slot
flash on tab one
ensure the MAC addresses show. If not, then something went wron.
A green tick at the end shows success.

Modules

DHT22 from here

Upload it with esplorer from above using the 'upload' button. Then compile by clicking reload on the middle right side, then a list of modules will appear. Right click and select compile.

Code

Set the wifi access point and set NIC to DHCP

print(wifi.sta.getip())
--nil
wifi.setmode(wifi.STATION)
wifi.sta.config("SSID","password")
print(wifi.sta.getip())
--192.168.18.110
 
View wifi SSIDs
function listap(t)
  for k,v in pairs(t) do 
    print(k.." : "..v) 
  end 
end 
wifi.sta.getap(listap)

onboard LED

Flash the blue LED near the USB connector
gpio.write(0,gpio.LOW)
gpio.write(0,gpio.HIGH)

GPIO LEDs

Flash an LED on GPIO pin 2
You can change the duty cycles by checking the docs http://www.nodemcu.com/docs/
 pwm.setup(2,1,10)
pwm.start(2)

Reading temperature/humidity

PIN=4
dht22 = require("dht22")
dht22.read(PIN)
t = dht22.getTemperature()
h = dht22.getHumidity()
humi=(h/10).."."..(h%10)
temp=(t/10).."."..(t%10)
print("Humidity:    "..humi.." %")
print("Temperature: "..temp.." deg C")
dht22 = nil
package.loaded["dht22"]=nil

 
All together:
print(wifi.sta.getip())
gpio.mode(2,gpio.OUTPUT)
--gpio.write(2,gpio.HIGH)
--gpio.write(2,gpio.LOW)
--gpio.write(1,gpio.LOW)
gpio.write(0,gpio.LOW)
BLUE=1 -- blue LED is on GPIO 1
pwm.stop(2)
pwm.stop(1)

pwm.setup(2,1,10)
pwm.start(2)

gpio.write(0,gpio.HIGH)


  sv=net.createServer(net.TCP, 2) 
  sv:listen(80,function(c)
      c:on("receive", function(c, pl)
         print(pl) 
      end)
        gpio.mode(BLUE,gpio.OUTPUT)
        gpio.write(BLUE,gpio.HIGH)
        PIN=4
        dht22 = require("dht22")
        dht22.read(PIN)
        t = dht22.getTemperature()
        h = dht22.getHumidity()
        humi=(h/10).."."..(h%10)
        temp=(t/10).."."..(t%10)
        print("Humidity:    "..humi.." %")
        print("Temperature: "..temp.." deg C")
        dht22 = nil
        package.loaded["dht22"]=nil
        c:send("H:"..humi.." ; T:"..temp.."\r\n")
        c:close()
        gpio.write(BLUE,gpio.LOW)
       end)
Note the above server doesn't respond to normal HTTP requests.  it responds with a simple:
H:xx ; T: xx
and disconnects after the initial connect.
You can use either curl or netcat to get the data.
It also flashes the blue LED whilst a network operation is in effect.
The white LED I've used blinks every second, to show it is working.

Dashboard

RRDtool - Create the RRD

This creates a RRD for 5 sensors, values 0 to 100 and 524160 data points (60*24*7*52) so 1 data point a minute
<?
    echo "Creates blank temp graphs";
    $options = array (
     "--step", "60",            // Use a step-size of 1 minute
     "--start", "-1 day",         "DS:hum1:GAUGE:100:0:100",
     "DS:hum2:GAUGE:100:0:100",
     "DS:hum3:GAUGE:100:0:100",
     "DS:hum4:GAUGE:100:0:100",
     "DS:hum5:GAUGE:100:0:100",
     "RRA:AVERAGE:0.3:1:524160",
    );


    $ret = rrd_create("./hum.rrd", $options);
    if (! $ret) {
     echo "<b>Creation error: </b>".rrd_error()."\n";
    }
?>

In part two, I'll show how to render the graphs

Part 2 here