Monday 28 March 2016

AM2302 Temperature and Humidity Sensor - Bat Project #01 - Durrell, Jersey

In this post I'll detail how I fared with getting a AM2302 working with the RPi.

This is the first step in a project I'm working on for Durrell Wildlife Conservation Trust. As well as working on a Gorilla feeder with my friend Max, they were also interested in data logging for their bat house:




I bought a sensor from eBay for a few pounds.


From what I can understand, the output from these devices is a digital stream of bits containing the relevant data, but it is not in a regular format like I2C, therefore you have to download a special library. I followed the instructions from Adafruit and it worked really well.

I wasn't that bothered about uploading my data to a google sheet, but since I discovered Thingspeak
a few days ago, I've been itching to try it. It's a great solution for the zoo project because the data goes straight to the web and is formatted and graphed automatically, and can be made public.

I found a great tutorial for linking python to thingspeak here:

http://www.australianrobotics.com.au/news/how-to-talk-to-thingspeak-with-python-a-memory-cpu-monitor

I just adapted the code and added it to the Adafruit example code. Resulting code is messy but worked really well.

I developed this using a model B+ but once it was running I shrunk it down onto a headless Pi Zero.

The thingspeak project site for the trial data (from my lounge) is here:

https://thingspeak.com/channels/103719

And you can embed the graphs using an iframe embed code. I presume this will update as data gets added, but I don't yet know for sure.




Hardware wise I set it up exactly as shown in the diagrams of the tutorial, but added a blue LED between the data and ground pins of the AM2302. It was a lucky guess and works nicely, flashing brightly as data is sent to the pi every minute.

(Sidenote: I've been trying out Node Red recently and I love it, but the instructions I could find online for getting the sensor to work in Node Red seem out of date and I ran into errors trying to install the nodes.)


The code:



#!/usr/bin/python
# Copyright (c) 2014 Adafruit Industries
# Author: Tony DiCola

# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:

# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.

# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import sys
import httplib, urllib
import Adafruit_DHT
from time import sleep

# Parse command line parameters.
sensor_args = { '11': Adafruit_DHT.DHT11,
    '22': Adafruit_DHT.DHT22,
    '2302': Adafruit_DHT.AM2302 }
if len(sys.argv) == 3 and sys.argv[1] in sensor_args:
 sensor = sensor_args[sys.argv[1]]
 pin = sys.argv[2]
else:
 print 'usage: sudo ./Adafruit_DHT.py [11|22|2302] GPIOpin#'
 print 'example: sudo ./Adafruit_DHT.py 2302 4 - Read from an AM2302 connected to GPIO #4'
 sys.exit(1)

# Try to grab a sensor reading.  Use the read_retry method which will retry up
# to 15 times to get a sensor reading (waiting 2 seconds between each retry).

while True:
 humidity, temperature = Adafruit_DHT.read_retry(sensor, pin)

# Un-comment the line below to convert the temperature to Fahrenheit.
# temperature = temperature * 9/5.0 + 32

# Note that sometimes you won't get a reading and
# the results will be null (because Linux can't
# guarantee the timing of calls to read the sensor).  
# If this happens try again!
#Pushing data to Thingspeak
# python

        if humidity is not None and temperature is not None:
                print 'Temp={0:0.1f}*  Humidity={1:0.1f}%'.format(temperature, humidity)
        else:
                print 'Failed to get reading. Try again!'
                sys.exit(1)


 params = urllib.urlencode({'field1': temperature, 'field2': humidity,'key':'92P5L3PGPTT8ZE8N'})
 headers = {"Content-type": "application/x-www-form-urlencoded","Accept":"text/plain"}
 conn = httplib.HTTPConnection("api.thingspeak.com:80")
 conn.request("POST", "/update", params, headers)
 response = conn.getresponse()
 print response.status, response.reason
 data = response.read()
 conn.close()


 if humidity is not None and temperature is not None:
  print 'Temp={0:0.1f}*  Humidity={1:0.1f}%'.format(temperature, humidity)
 else:
  print 'Failed to get reading. Try again!'
  sys.exit(1)
 
 sleep(60)





Sunday 27 March 2016

Node Red

I've had a play with Node Red for the first time tonight. In a matter of minutes I was able to operate an LED through the Node Red interface, something I'd been wanting to do for a long time.




I couldn't be much simpler to use. I could do quite a lot of things in Node Red after just one evening playing around. The web side of things is still puzzling for now, with websockets and HTTP the next nut to crack.

I reckon I could control my home heating now just using Node Red and the right hardware.

LATER THAT SAME EVENING........

Couldn't let it lie so I had another play. Now the status of the LED can be output to wherever, e.g. twitter:



Output:




Copy and paste the code below if you want to try it (minus the twitter feed) - I used pin 11 (GPIO 17) to drive the LED.


[{"id":"d82e83d.f27d18","type":"inject","z":"2fc3a5ef.d03c5a","name":"LED on","topic":"","payload":"1","payloadType":"string","repeat":"","crontab":"","once":false,"x":295,"y":112,"wires":[["24897f1c.db768","1b8bd14c.e4742f"]]},{"id":"795f97e3.86a068","type":"inject","z":"2fc3a5ef.d03c5a","name":"LED off","topic":"","payload":"0","payloadType":"string","repeat":"","crontab":"","once":false,"x":297,"y":187,"wires":[["24897f1c.db768","1b8bd14c.e4742f"]]},{"id":"24897f1c.db768","type":"rpi-gpio out","z":"2fc3a5ef.d03c5a","name":"Yellow LED","pin":"11","set":true,"level":"0","out":"out","x":497,"y":146,"wires":[]},{"id":"4a42382a.b5bdc8","type":"debug","z":"2fc3a5ef.d03c5a","name":"LED status","active":true,"console":"false","complete":"payload","x":622,"y":286,"wires":[]},{"id":"1b8bd14c.e4742f","type":"change","z":"2fc3a5ef.d03c5a","name":"Create Human Readable Output","rules":[{"t":"change","p":"payload","from":"0","to":"LED is OFF","re":false},{"t":"change","p":"payload","from":"1","to":"LED is ON","re":false}],"action":"","property":"","from":"","to":"","reg":false,"x":356,"y":287,"wires":[["4a42382a.b5bdc8"]]}]