DHT11/DHT22 with Raspberry Pi

I can confirm that my MQTT script lost connection a few hours ago after running for about 2 days. I have changed the location of mqttc.loop() to where you have it in your script and have rebooted the Pi. I’ll update in a few days or as soon as I notice that it is in a disconnected state.

I also noticed that right around the time my MQTT device went offline the data reporting to Cayenne were very far apart, about 6-7 hours on the day chart. This may be a new feature of the day chart though with MQTT, I haven’t been paying attention to it lately. My Arduino charts show data points for every hour in the day view.

Here is something different. I have offline message from 8 hours, but the last packet send is about before 2 hours. I reboot and start checking again because I am not sure that I run correctly the test.

Hi, guys after all this post, what is the final relase of this situation?

Now im using free privateeyepi http://www.projects.privateeyepi.com/home/home-alarm-system-project/temperature-and-humidity and it works perfect, no data lost.

It will be great if DHT22 works finally 100% with cayenne.

I put here the privateeyepi scripts, so someone can find it helpful:

1- STEP

cd /home
sudo git clone GitHub - adafruit/Adafruit_Python_DHT: Python library to read the DHT series of humidity and temperature sensors on a Raspberry Pi or Beaglebone Black.
cd Adafruit_Python_DHT
sudo apt-get install build-essential python-dev
sudo python setup.py install

2.STEP
it installs a lot of file, DHT releted file are: dht22.py / globals.py / restarter.py

cd /home
sudo wget -N www.privateeyepi.com/downloads/install.sh

i put here the code of the single file:

dht22.py

#!/usr/bin/env python
"""
DHT22.py 14.00 temperature and humidity to PrivateEyePi
---------------------------------------------------------------------------------
 Works conjunction with host at www.privateeyepi.com                              
 Visit projects.privateeyepi.com for full details                                 
                                                                                  
 J. Evans February 2014       
 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.                                                       
                                                                                  
 Revision History                                                                  
 V1.00 - Created
 V1.01 - Fixed bug with Fahrenheit displaying as "C" not "F"    
 V9    - Rules Release
 v9.01 - Fixed bug with negative temperature readings     
 v13   - Added LCD Functionality   
 V14   - Added support for Raspberry Pi2 
-----------------------------------------------------------------------------------
"""

import time
import RPi.GPIO as GPIO
import urllib2
import subprocess
import globals
from alarmfunctionsr import UpdateHost
from alarmfunctionsr import GetDataFromHost
from alarmfunctionsr import SendToLCD
import Adafruit_DHT

global LocationDesc

#...

def GetData():
		global temp
		global humidity

		# This is the routine that interfaces with the sensor and
		# return a value that will get sent to the host and displayed  
		# on the dashboard. 

		if globals.PrintToScreen: print "Reading DHT22 sensor on pin "+str(globals.dht22_pin_no)

		#Thanks to Adafruit for the DHT22 sensor interface written in c   

		humidity, temp = Adafruit_DHT.read_retry(Adafruit_DHT.AM2302, globals.dht22_gpio)
		
		if humidity is None or temp is None:
				return(False)
		
		humidity = round(humidity,2)
		temp = round(temp,2)
				  
		if globals.PrintToScreen: print "Temperature = " + str(temp)
		if globals.PrintToScreen: print "Humidity = " + str(humidity)
		
		# Do the Farenheit conversion if required
		if globals.Farenheit:
				temp=temp*1.8+32

		return(True)

def GetLocation(number):
    
        global LocationDesc
        
        LocationDesc= ""
        
        RecordSet = GetDataFromHost(21,[0])
        if RecordSet==False:
                return 1
            
        if globals.PrintToScreen: print RecordSet
        
        numrf = len(RecordSet)
        
        for i in range(numrf):
                if RecordSet[i][0]==number:
                        LocationDesc=RecordSet[i][1]
                        if globals.PrintToScreen: print "Location Description = "+ str(LocationDesc)
            
        return 0

def fileexists(filename):
        try:
                with open(filename): pass
        except IOError:
                return False 
        return True
                                  
def NotifyHost():
        global temp
        global humidity
        global LocationDesc
        
        TempBuffer = []
        rt=GetData()
        if rt==False: #fail
                return (0)
        TempBuffer.append(temp)
        if globals.Farenheit:
                TempBuffer.append(1)
        else:
                TempBuffer.append(0)
        TempBuffer.append(globals.dht22_pin_no)
        TempBuffer.append(humidity)
        UpdateHost(14, TempBuffer)
        
        if globals.LCDTemperature==True:
                #SendToLcd receives an array of 7 values
                #RecordSet[0] : GPIO_Pin_Number
                #RecordSet[1] : Location       
                #RecordSet[2] : Display Message
                #RecordSet[3] : type 1=Switch Open, 2=Switch Closed, 3=Temperature, 4=Temperature & Humidity, 5=Free format String
                #RecordSet[4] : Tempeature Value
                #RecordSet[5] : Humidity Value
                #RecordSet[6] : Unit of measure, 0=Centigrade, 1=Fahrenheit
                #RecordSet[7] : Armed/Disarmed 1=Armed, 2=Disarmed
                #RecordSet[8] : Date/Time
                SendToLCD([globals.dht22_pin_no,LocationDesc,0,4,temp,humidity, globals.Farenheit,0,0])
        
        return (0)
                   
def main():
        global start_time
        global elapsed_time
        
        globals.init()

        # Interval in seconds that temperature is sent to the server
        start_time = time.time()
        
        GetLocation(globals.dht22_pin_no)
        
        NotifyHost()
        
        #Main Loop
        while True:
             
                elapsed_time = time.time() - start_time
                
                if (elapsed_time > 300):
                        start_time = time.time()
                        # Get the latest temperature
                        NotifyHost()
                    
                time.sleep(.2)

if __name__ == "__main__":
        main()

globals.py

#!/usr/bin/env python
"""
globals.py 10.00 PrivateEyePi Globals Parameters
---------------------------------------------------------------------------------
 Works conjunction with host at www.privateeyepi.com                              
 Visit projects.privateeyepi.com for full details                                 
                                                                                  
 J. Evans October 2013       
 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.                                                       
                                                                                  
 Revision History                                                                  
 V1.00 - Release
 V2.00 - Added generic poll interval
 V3.00 - Incorporated rules functionality
 V4.00 - Added siren rule action, chime, siren beep delay
 v9.00 - Rules release     
 v10.00 - Added support for flexible sensor voltages                                                        
 -----------------------------------------------------------------------------------
"""

def init():
        global PrintToScreen
        global user
        global password
        global RFPollInterval
        global smtp_server
        global smtp_user
        global smtp_pass
        global Farenheit
        global DallasSensorNumbers
        global DallasSensorDirectory
        global TemperaturePollInterval
        global GenericPollInterval
        global GPIOPollInterval
        global UseSiren
        global SirenGPIOPin
        global SirenTimeout
        global SirenStartTime
        global Armed
        global RemoteZoneDescription
        global ArmPin
        global DisarmPin
        global ArmDisarm
        global GPIO 
        global ChimeDuration
        global SirenPollInterval
        global SirenDelay
        global BeepDuringDelay
        global ButtonBList
        global ButtonBId
        global dht22_gpio
        global dht22_pin_no
        global auto_dht22
        global auto_alarm
        global auto_rfsensor
        global auto_dallas
        global auto_lcd
        global auto_control
        global install_directory
        global email_type
        global ChimeGPIOPin
        global photopath
        global RelayPin
        global WRelayPin
        global VoltageList
        global MaxVoltage
        global LCDName
        global LCDTemperature
        global LCDAlarmActivity
        global lcd_ip
        global LCDChime
        global disp
        
        #User and password that has been registered on www.privateeyepi.com website
        user=""     #Enter your email address
        password="" #Enter your password here
        
        # Set this to True if you want to send outputs to the screen
        # This is useful for debugging
        PrintToScreen=False
        
        # If you want to receive email alerts define SMTP email server details
        # This is the SMTP server, username and password trequired to send email through your internet service provider
        smtp_server="" # usually something like smtp.yourisp.com
        smtp_user=""   # usually the main email address of the account holder
        smtp_pass=""   # usually your email address password
        email_type=1   # 1 for No Encryption, 
                       # 2 for SSL and 
                       # 3 and TLS
        
        # Set the path to the photos that get attached to emails when
        # a rule is triggered to send photos
        photopath = "/home"
        
        #Indicator to record temperature in Farenheit
        Farenheit=False
                
        #Temperature settings
        #if you are using the dht22 temperature and humidity sensor set the gpio number and the pin number here
        # note!! the GPIO number and the pin number are not the same e.g GPIO4=RPIPin7
        dht22_gpio=4
        dht22_pin_no=7
        
        DallasSensorNumbers = []
        DallasSensorDirectory = []
        
        #Set the directory and sensor numbers for the Dallas temperature gauge
        DallasSensorNumbers.append(7) #sensor number defined in the number field in the GPIO settings
        #DallasSensorNumbers.append(80) #add more sensors..
        #DallasSensorNumbers.append() #add more sensors..
        
        DallasSensorDirectory.append("28-0000055d57dd") #directory name on RPI in the /sys/bus/w1/devices directory  
        #DallasSensorDirectory.append("28-000005020815") #add another directory 
        #DallasSensorDirectory.append("") #add another directory

        #Auto restart settings
        auto_dallas = False
        auto_alarm = False
        auto_dht22 = False
        auto_rfsensor = False
        auto_lcd = False
        auto_control = False
        install_directory = "/home" #The PrivateEyePi software directory

        # Set this to true if you want to connect an external siren. Put siren activation and deactivation code in the Siren function.
        UseSiren = False
        SirenGPIOPin = 18
        SirenDelay=30 #The amount of time the siren will delay before it sounds
        BeepDuringDelay = True #if your want the siren to beep during the SirenDelay period
        SirenTimeout = 30 #siren will timeout after 30 seconds
        ChimeGPIOPin = 18
        ChimeDuration = 5
     
        #Arm/Disarm zone from a switch
        ArmDisarm=False # set this to True if you want to arm/disarm using switches
        RemoteZoneDescription="" #The description of the zone you want to arm/disarm
        ArmPin=13
        DisarmPin=15
        Armed = True

        #Configure your button B sensors here
        #Button B is the second button on the RF Switch
        ButtonBList = []
        ButtonBId = []
        #ButtonBList.append(80) # this is the device ID of the sensor 
        #ButtonBId.append(90)   # sensor number defined in the number field in the GPIO settings
        
        #ButtonBList.append(81)
        #ButtonBId.append(90)
        #...add more button B sensors by copying the above two lines and updating the numbers in brackets....
        
        #Relay pin configuration for the relay ON/OFF rule action
        RelayPin=12 
        #WRelayPin=99
        
        #Configure alternate voltages here. This is for wireless sensors that have a voltage
        #that is not the standard 3V. This voltage setting is used for the battery display
        #on the dashboard so the system knows what the maximum voltage is for the display
        #The below example will set the maximum voltage for Device ID 81 to 9V
        VoltageList = []
        MaxVoltage = []
        #VoltageList.append(92)
        #MaxVoltage.append(1.5)
        #VoltageList.append(81)
        #MaxVoltage.append(9)
        #...add more max voltages by copying the above two lines and updating the numbers in brackets....
        
        #Configure an LCD panel here
        LCDTemperature=False
        LCDAlarmActivity=False
        LCDChime=False
        lcd_ip="127.0.0.1"

restarter.py

#!/usr/bin/env python
"""
Check to see if an process is running. If not, restart.
Run this in a cron job
"""
import os
import globals

globals.init()

process_name= "alarm.py" # change this to the name of your process
tmp2 = os.popen("ps -Af").read()

if process_name not in tmp2[:] and globals.auto_alarm:
    newprocess="nohup python %s/%s &" % (globals.install_directory, process_name)
    os.system(newprocess)

process_name= "dallas.py" # change this to the name of your process
tmp2 = os.popen("ps -Af").read()

if process_name not in tmp2[:] and globals.auto_dallas:
    newprocess="nohup python %s/%s &" % (globals.install_directory, process_name)
    os.system(newprocess)

process_name= "rfsensor.py" # change this to the name of your process
tmp2 = os.popen("ps -Af").read()

if process_name not in tmp2[:] and globals.auto_rfsensor:
    newprocess="nohup python %s/%s &" % (globals.install_directory, process_name)
    os.system(newprocess)

process_name= "dht22.py" # change this to the name of your process
tmp2 = os.popen("ps -Af").read()

if process_name not in tmp2[:]  and globals.auto_dht22:
    newprocess="nohup python %s/%s &" % (globals.install_directory, process_name)
    os.system(newprocess)

process_name= "subscribe.py" # change this to the name of your process
tmp2 = os.popen("ps -Af").read()

if process_name not in tmp2[:]  and globals.auto_lcd:
    newprocess="nohup python %s/%s &" % (globals.install_directory, process_name)
    os.system(newprocess)

process_name= "control.py" # change this to the name of your process
tmp2 = os.popen("ps -Af").read()

if process_name not in tmp2[:]  and globals.auto_control:
    newprocess="nohup python %s/%s &" % (globals.install_directory, process_name)
    os.system(newprocess)
1 Like

Did you also remove the time.sleep(5) in addition to moving the mqttc.loop() function? If not it would still block mqttc.loop() from running for 5 seconds. That would need to be replaced with some code that runs the sensor checks every 5 seconds, but doesn’t prevent mqttc.loop() from running.

If you did remove the time.sleep(5) and still see a disconnect keep happening it might be some network or sever issue causing a disconnect. In that case you may want to add some code to reconnect on a disconnect. You can do this by creating an on_disconnect callback to handle that case and attempt to reconnect at intervals. That is how the cayenne-mqtt Python library handles disconnects.

1 Like

I’ve seen stack examples that use time.sleep() in a loop with mqttc.loop(), but that doesn’t necessarily mean that it’s ok. From a post from on stack that I trust: “The ping messages are only needed if you have a low message rate (less than 1 msg per keep alive period).” so I guess it really depends what the server has set for the timeout. 5 seconds might just be too long, however I’d think it would error out a lot faster than it does.

According to the docs on_disconnect is only called when the client calls disconnect(). It doesn’t say anything about it calling on a network or server error, but I guess that could just be a documentation omission/error. I’ll test this out when I get some time.

I have changed my code to start a loop in another thread with loop_start(). I’ll let this run for a while to see what happens.

Hello everybody. The code that @adam post is working for me. Any other that test is?

That’s a good point @adam. I believe the keep alive default is 60 seconds so that delay might not be the issue.

As for on_disconnect, I recall in my testing it was called when the connection was broken on the sever side as well, though it’s been a little while so I could be remembering that incorrectly.

Hello all I am back and now have my dht22 and all supplies I would like to get started with code tonight here is my wiring currently 5 v and on gpio pin 25. Please let me know if I need to change pin to ease things . I’m sorry for not knowing much but what would be my next step add mattq and if so how ?

Hello All ,

here is the rest of my photos i am currently at the add new mattq device , but it says attempting to connect to the board.
please excuse me not knowing much about programming and cayenne. But i am totally hooked and anxious to learn more . i would love to get this working properly to try and help out test the code. please advise

Hello @austin.rodriguez210 you can scroll up and find my last code. You have to change just a couple of things - ID, Username and Password and GPIO pin. I believe that in the code I have comments so you will be orientated very fast.

i am currently having trouble installing the git clone adafruit libary , This is my first time attempting to get a clone . I understand i need to download the clone and install the file but i have been following this tutorial but with no luck . thank you for any help i am very new once again and in over my head .

i have been following these instructions on working with Working With Existing Repositories

hmmm git should be installed by default. You can install it with sudo apt-get install git

ok now I’m really lost lol then what steps do I need to do I need to install the adadfruit library … I have no experience with python

Any help is greatly appreciated I am sorry for any frustration for my lack of understanding all of this

update

i do have git installed , but can not download the Python library to read the DHT series of humidity and temperature sensors on a Raspberry Pi. am i doing something wrong please advise.

i have the libary finally installed thank you for all of the help , i also have created the text file and inputed all of my mattq info, but do not understand how to move my file to the proper folder.

You don’t have to put it there, just personal preference that I put my python files in a folder called python. You can put it right in /home/pi if you want.

i just realized that i have been have an error when running the sudo python setup.py install command

Also My file that i created that i copied the code to i made with nano and just saved is there something special that i need to do . i feel like i am close but can not get anything to succesfully install, would you recommend me waiting till this is added as a plug and play sensor .

thasnk you
austin

Great news! Using the threaded loop has been working great for 3 days. I’ll update my original post.

Adam ,

What do you think could be causing the error while I am attempting to install the driver thank you for you help

Austin

What OS are you running? It sounds like you don’t even have python installed. Run these commands:

sudo apt-get install python-dev
sudo apt-get install python3-dev