driver_dht22.py 5.94 KB
# -*- coding: utf-8 -*-
from time import *
import RPi.GPIO as io

def get_data(pin_data_bcm=13, debug_level=0):
    if False:
        # --- method perso pure python
        err=0
        k=0
        sortie=False
        while (sortie==False):
            err_dht22, tmp, hum, seuil, data = get_data0(pin_data_bcm,debug_level)
            if ((err_dht22==0) or (k>20)):
                sortie=True
            else:
                sleep(0.1)
            k+=1
    else:
        # --- method lib python+C
        import Adafruit_DHT
        sensorDHT = Adafruit_DHT.DHT22
        hum, tmp = Adafruit_DHT.read_retry(sensorDHT, pin_data_bcm)
        err_dht22 = 0
        seuil = 0
        data = ""
        if (hum==None) or (tmp==None):
            err_dht22 = 1
            hum = 0
            tmp = 0
        elif (hum>100):
            err_dht22 = 2
            hum = 0
            tmp = 0
    return err_dht22, tmp, hum, seuil, data

def get_data0(pin_data_bcm=13, debug_level=0):
   """Lecture d'une trame du capteur meteo DHT22. 
Retourne un tuple, dans l'ordre: Un code de validité, la température en °C, le % d'humidité, le seuil de binarisation, les bits de la trame lue. Le code de validité =0 si la trame est valide, =1 si le checksum est mauvais, =2 si le nombre de bits lu n'est pas égal à 40.
valide = 3 si la liste est vide
Exemple:

import driver_dht22 ; driver_dht22.get_data(13,2)
"""
   listetrame = [] #trame échantillonnée
   data = [] #trame du capteur
   tableN = [] #liste des nombres de 1

   io.setwarnings(False)
   io.setmode(io.BCM)

   # --- Pin GPIOxx for DHT data in mode OUT
   io.setup(pin_data_bcm,io.OUT)
   # --- Send HIGH->LOW(1ms)->HIGH to start an acquisition
   io.output(pin_data_bcm,io.HIGH)
   io.output(pin_data_bcm,io.LOW)
   sleep(0.001)
   io.output(pin_data_bcm,io.HIGH)

   # --- Pin GPIOxx for DHT data in mode IN
   io.setup(pin_data_bcm,io.IN)
   # --- Read continuously the GPIxx pin during few ms
   for k in range (0,2500):
      listetrame.append(io.input(pin_data_bcm)) #récupération de la trame suréchantillonnée
   if (debug_level==3):
      print("=== Raw data ===")
      print(listetrame)
        
   if (debug_level==2):
      print("=== Data -> 40 bits ===")
   cpt1=0 #compteur des 1
   nb=1 #nombre du bit
   t = len(listetrame)
   for k in range(0,t-1) : #compte le nombre de 1 par bit
      a = listetrame[k]
      b = listetrame[k+1]
      if (b==1) :
         cpt1 = cpt1 + 1
      if ((b-a) ==-1) :
         tableN.append(cpt1) #enregistrer le nombre de 1 dans tableN
         if (debug_level==2):
            print ("bit=",nb," len=",cpt1)
            if (nb%8==0):
               print()
         nb=nb+1
         cpt1=0

   try:
      
      seuil = (max(tableN)+min(tableN))/2
   except ValueError :
      valide = 3
      seuil = 0
      return valide, 0, 0, 0 ,data
   if (debug_level==2):
      print("=== Threshold to binarize ===")
      print ("seuil=",seuil)

   # --- autocorrection of the first bit
   lent=len(tableN)
   #print("lent A=",lent)
   if (lent==41):
      tableN = tableN[1:lent:1]         
   if (lent==39):
      tableN.insert(0,0)
   #print("tableN=",tableN)
   lent=len(tableN)
   #print("lent B=",lent)

   valide=0
   tmp=0
   hum=0
   for elem in tableN:
      if elem > seuil:
         d=1
      else:
         d=0
      data.append(d) #on remplit data avec ses vraies valeurs binaires

   if lent != 40:
      valide=2
      return valide, 0, 0, lent,data

   if (debug_level==2):
      print("=== 40 Bits -> 16_hum 16_temp 8_chksum ===")
   k=1
   bi_hum="0b"
   bi_tmp="0b"
   bi="0b"
   sg_tmp=1
   chk=0; #check somme
   for elem in tableN:
      if elem > seuil:
         d=1
      else:
         d=0
      if (k>=1 and k<=16):
         bi_hum=bi_hum+str(d) #on assemble le mot binaire de l'humidité
      if (k==16):
         hum=int(bi_hum,2)/10; #convertion du nombre binaire en décimal
         if (debug_level==2):
            print ("Binary humidity = ",bi_hum) 
            print ("Decimal humidity = ",hum) 
      if (k==17 and d==1):
         sg_tmp=-1
      if (k>=18 and k<=32):
         bi_tmp=bi_tmp+str(d) #on assemble le mot binaire de la température
         #      print ("le binaire de la temp vaut :",bi_tmp," (",k,")")
      if (k==32):
         tmp=sg_tmp*int(bi_tmp,2)/10; #convertion du nombre binaire en décimal
         if (debug_level==2):
            print ("Binary temperature = ",bi_tmp) 
            print ("Decimal temperature = ",tmp) 

      #checksum
      if (k>=1 and k<=8):
         bi=bi+str(d)        #premier octet
         #     print ("le binaire vaut :",bi," (",k,")")
      if (k==8):
         chk+=int(bi,2)  #conversion du premier octet en décimal et addition du premier octet
         bi="0b";
      if (k>=9 and k<=16):
         bi=bi+str(d)        #second octet
         #      print ("le binaire vaut :",bi," (",k,")")
      if (k==16):
         chk+=int(bi,2) #ajout du second octet
         bi="0b";
      if (k>=17 and k<=24):
         bi=bi+str(d)        
         #     print ("le binaire vaut :",bi," (",k,")")
      if (k==24):
         chk+=int(bi,2)
         bi="0b";
      if (k>=25 and k<=32):
         bi=bi+str(d)        
         #     print ("le binaire vaut :",bi," (",k,")")
      if (k==32):
         chk+=int(bi,2)
         bi="0b";
      if (k>=33 and k<=40):
         bi=bi+str(d)        
         #     print ("le binaire vaut :",bi," (",k,")")
      if (k==40):
         if (debug_level==2):
            print ("=== Checksum ===") 
            print ("Binary checksum data = ",bin(chk)) 
            print ("Decimal checksum data = ",chk) 
         chk=chk%256 #modulo 256 
         if (debug_level==2):
            print ("Decimal checksum data modulo = ",chk) 
         chksum=int(bi,2)
         if (debug_level==2):
            print ("Binary checksum frame modulo = ",bi) 
            print ("Decimal checksum frame modulo = ",chksum) 
         if (chksum==chk):
            valide=0
         else:
            valide=1

      k+=1

   return valide, tmp, hum, seuil, data