Pressure, Humidity and Temperature

My weather project is coming along nicely. Now I have added the DHT22 humidity and temperature sensor. Once again I used the drivers from Adafruit. Here is a link to the information: Adafruit DHT tutorial

A few pointers… somehow I managed to install the modules as root, not under my login name (the penalty of not paying attention with lots of terminal windows open). Use ‘chown -R’ to change back the ownership. The DHT22 uses the Dallas Semiconductor one wire interface. On the Raspberry Pi this is accomplished using a GPIO pin and thus the program needs to be run as ‘sudo’ to command the pins. The one wire interface is not as robust as others, so its possible that you will get error messages (if the program crashes with an error of the wrong data type then what happened is that  a ’round’ was not returned). Hence I use the read_retry command from the Adafruit library. The DHT22 library returns a long , so I have used round() to truncate the answer for display on the console.

You should note that the one wire bus needs a pull up resistor on the bus. I am using a 4.7kohm pull up to Vcc. Only one pull up resistor is required. Note how the BMP180 and the DHT22 are powered from different rails.

DHT22+BMP180_2

A few other notes:

I have added code to enable a cleaner exit from the program (the wrapper ‘try’ loop)

To check the i2c devices use “sudo i2cdetect -y 1”.  This will show you the addresses of the various modules. Each needs to be unique. The BMP180 should show up at address 77. If you see UU it means that the kernel has a module running and talking to that address.

i2CdetectSCR

you can see here that I have another device on my I2C… it happens to be a DS1307 RTC.

Here are the new results. Looks like the DHT22 reported an erroneous value in there so eventually I will need to take a look at the driver and see if the robustness can be increased.

temp2humiditypressure

Here is the circuit. Note that the BMP180 is powered from 3.3V and can communicate with the RPi directly. I am using a bi-directional level converter (Fritzing part included in the files) to communicate with the DHT22 which I have powered from 5V.

pressuretemphumidity2

Fritzing files can be found at http://fritzing.org/projects/pressure-temperature-and-humidity

#!/usr/bin/python
# Original Author : Tony DiCola of Adafruit
# With additions by hobbyistdave  www.hobbyspot.org
#
# 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.

# Can enable debug output by uncommenting:
#import logging
#logging.basicConfig(level=logging.DEBUG)

import Adafruit_BMP.BMP085 as BMP085   # the pressure and temnperature sensor
import Adafruit_DHT as DHT22           # the DHT22 hunidty and temperature sensor
import smbus
import time
import requests  # HTTPfor humans
                 # by Kenneth Reitz  docs.python-requests.org

# Default constructor will pick a default I2C bus.
#
# For the Raspberry Pi this means you should hook up to the only exposed I2C bus
# from the main GPIO header and the library will figure out the bus number based
# on the Pi's revision.
#
# For the Beaglebone Black the library will assume bus 1 by default, which is
# exposed with SCL = P9_19 and SDA = P9_20.
sensor = BMP085.BMP085()  # pressure and temperature
sensor2 = DHT22           # humidity and temperature
onewirepin = 4            # the pin for the one wire sensor
sensor1type = "BMP180"    # the type of sensor    
sensor2type = 22          # the type of sensor    

# Optionally you can override the bus number:
#sensor = BMP085.BMP085(busnum=2)

# You can also optionally change the BMP085 mode to one of BMP085_ULTRALOWPOWER, 
# BMP085_STANDARD, BMP085_HIGHRES, or BMP085_ULTRAHIGHRES.  See the BMP085
# datasheet for more details on the meanings of each mode (accuracy and power
# consumption are primarily the differences).  The default mode is STANDARD.

sensor = BMP085.BMP085(mode=BMP085.BMP085_ULTRAHIGHRES)

# setup the info needed to send the results to thingspeak

thingspeakurl = "https://api.thingspeak.com/update"   # url for sending updates to thingspeak
apikey = "1234567890123456"     # thingspeak api address for this channel 
TempField = "field1"            # temperature field
PressField = "field2"           # pressure field

# some debug info... here we print the BMP180 cal table
print "Calibration Coefficients read from sensor device "
print "-------------------------------------------------"
print "ac1 ", sensor.cal_AC1
print "ac2 ", sensor.cal_AC2
print "ac3 ", sensor.cal_AC3
print "ac4 ", sensor.cal_AC4 
print "ac5 ", sensor.cal_AC5
print "ac6 ", sensor.cal_AC6
print "b1  ", sensor.cal_B1
print "b2  ", sensor.cal_B2
print "mb  ", sensor.cal_MB
print "mc  ", sensor.cal_MC
print "md  ", sensor.cal_MD
print "--------------------------------------------------"
print " "

print "Initial data read to check sensors            "
print "-------------------------------------------------"
print "Time          ", time.ctime()
print "Epoch Seconds ", time.time()
print " "
temperature = sensor.read_temperature()  # Note: fixed an error in the Adafruit module where it incorrectly divides by 10 
pressure = sensor.read_pressure()

print "Data read from Sensor 1              "
print "---------------------------------------------------------"
print "Sensor type", sensor1type
print 'Temperature= {0:0.1f} *C  Pressure= {1:0.1f} mbar'.format(temperature,pressure/100)
print " "

print "Data read from Sensor 2              "
print "---------------------------------------------------------"
print "Sensor type", sensor2type
humidity2, temperature2 = DHT22.read_retry( sensor2type, onewirepin )
print 'Temperature= {0:0.1f} *C  Humidity= {1:0.1f} %'.format(temperature2,humidity2)
print " "

print "---------------------------------------------------------------------------"
print "  Time          Point    Temp     Temp2   Pressure     Humidity     Status "
print "(Epoch)           #       C         C        mbar          %         Code  "
print "---------------------------------------------------------------------------"
print " "
time.sleep(2)  # wait for the DHT sensor as it does not like to be accessed faster than every 2 seconds
# Now we enter the min code

try:           # wrapper to allow clean exit
    while True:

        temperature = sensor.read_temperature()
        pressure = sensor.read_pressure()
        humidity2, temperature2 = DHT22.read_retry( sensor2type, onewirepin )
        humidity2 = round(humidity2,3)
        temperature2 = round(temperature2,3)
        time.sleep(0.5)

        url = thingspeakurl
        payload = {'key' : apikey, 'field1' : temperature , 'field2' : pressure/ 100. , 'field3' : temperature2 , 'field4' : humidity2 } # make the payload
    
        try :
            r = requests.get(url, params=payload)  # send to thingspeak
            print time.time(), "  ", r.text, "   ", temperature ,"   ", temperature2 ,"   ", pressure / 100.,"      ", humidity2, "      ", r.status_code
            #r.text will be the data point number
            #r.status code should be 200 if the page posted correctly
        except requests.exceptions as e :
            print e # some simple error trapping to avoid the program timing out
        except requests.exceptions.ConnectionError as e1 :
            print e1 # some simple error trapping if the connection is lost
    
        time.sleep(15) # thingspeak is set to ignore requests that come faster than every 15 seconds

except KeyboardInterrupt:
    time.sleep (0.1)
    print " "
    print "Exiting program due to Keyboard Interrupt"
    print " "
except:
    time.sleep (0.1)
    print " "
    print "An error occurred"
    print " "

# end
 

The terminal output looks like this

presstemphumidSCR