Welcome to the Pycom forum Forum
    • \[\[global:header.categories\]\]
    • \[\[global:header.recent\]\]
    • \[\[global:header.tags\]\]
    • \[\[global:header.popular\]\]
    • Login

    Explore Pybytes | Official Documentation | Report a Firmware Bug/Issue | GitHub

    DHT 11 sensor always return same value

    Scheduled Pinned Locked Moved LoPy
    dht11lopypycom
    16 Posts 4 Posters 5.9k Views 5 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • robert-hhR Offline
      robert-hh @jmarcelino
      last edited by

      @jmarcelino The loop is a little bit slower than 1-2µs, because the loop management needs time too. But that has to be determined. So without real timing testing cou cannot get any results. There were people who managed to get this type of code working on ESP8266.
      Nevertheless, knowing about the irreular timing of the esp devices, it's better to use sensors with a stanard communication method.

      1 Reply Last reply Reply Quote 1
      • J Offline
        jmarcelino
        last edited by

        Just noticed the original poster is also using G4 (P14) which is an input-only pin, so trying to set it high dht_pin(1) does nothing. This means the DHT11 is not initialising.

        robert-hhR 1 Reply Last reply Reply Quote 1
        • robert-hhR Offline
          robert-hh @jmarcelino
          last edited by

          @jmarcelino Right, that's whatI wanted to check too. But at that point the docs at machine.pin should spend a few words about it. Normal users would not look into the esp32 data sheet.

          J 1 Reply Last reply Reply Quote 0
          • J Offline
            jmarcelino @robert-hh
            last edited by jmarcelino

            @robert-hh
            You don't need to look into the esp32 data sheet, it's on the LoPy pinout map with a red warning sign: https://docs.pycom.io/pycom_esp32/_downloads/lopy_pinout.pdf

            "Only Input pins!"

            The pinout map should really be required reading for everyone. Maybe the text could be made larger.

            By the way I tested the loop - you are absolutely right I was overlooking the loop and memory access involved - each cycle takes about 20 μS. So perhaps 1200 samples could be enough.

            robert-hhR 1 Reply Last reply Reply Quote 0
            • robert-hhR Offline
              robert-hh @jmarcelino
              last edited by

              @jmarcelino If a cycle takes 20 µs, and the actual reading time is less than 5 ms (160 µs lead in and 40 bits at 120µs worst case), then 250 samples are sufficient. So with 300 takes the buffer is large enough. So taking the wrong Input is the first thing to change.

              J 1 Reply Last reply Reply Quote 1
              • J Offline
                jmarcelino @robert-hh
                last edited by jmarcelino

                @robert-hh
                Good catch, I was going by the datasheet which states 23ms for a read, but that includes the initial delay already accounted for in the code.

                So in summary @bihut :

                -Change power supplt to 3.3v
                -Use another Pin that isn't input only (so don't use G5, G4, G0, G3, G31, G30)

                1 Reply Last reply Reply Quote 0
                • robert-hhR Offline
                  robert-hh @bihut
                  last edited by robert-hh

                  @bihut I gave your code a try, and as @jmarcelino saidm

                  • the port was wrong, and
                  • the first trailing 0/1 change was not detected because python was busy with changing functions.
                    The attached code works with my AM2302, which is identical to DHT22.
                  from machine import enable_irq, disable_irq,  Pin
                  import time
                  _LIMIT = const(8)
                  _BUFFERSIZE = const(1000)
                  
                  def getval(pin) :
                      ms = [1] * _BUFFERSIZE
                      pin(0)
                      time.sleep_us(20000)
                      pin(1)
                      irqf = disable_irq()
                      mslen = len(ms)
                      for _ in range(mslen):
                          ms[_] = pin()      ## sample input and store value
                      enable_irq(irqf)
                      return ms
                  
                  def decode(inp):
                      res= [0]*5
                      bits=[]
                      ix = 0
                      try:
                          if inp[0] == 1 : ix = inp.index(0, ix) ## skip to first 0
                  #        ix = inp.index(1,ix) ## skip first 0's to next 1
                  #        ix = inp.index(0,ix) ## skip first 1's to next 0
                          while len(bits) < len(res)*8 : ##need 5 * 8 bits :
                              ix = inp.index(1,ix) ## index of next 1
                              ie = inp.index(0,ix) ## nr of 1's = ie-ix
                              bits.append(ie-ix)
                              ix = ie
                      except Exception as err:
                          print (err, ix, len(bits))
                          return([0xff,0xff,0xff,0xff])
                  
                      for i in range(len(res)):
                          for v in bits[i*8:(i+1)*8]:   #process next 8 bit
                              res[i] = res[i]<<1  ##shift byte one place to left
                              if v > _LIMIT:
                                  res[i] = res[i]+1  ##and add 1 if lsb is 1
                  
                      if (res[0]+res[1]+res[2]+res[3])&0xff != res[4] :   ##parity error!
                          print("Checksum Error")
                          res= [0xff,0xff,0xff,0xff]
                  
                      return(res[0:4])
                  
                  def DHT11(pin):
                      res = decode(getval(pin))
                      temp = 10*res[0] + res[1]
                      hum = 10 * res[2] + res[3]
                      return temp, hum
                  
                  def DHT22(pin) :
                      res = decode(getval(pin))
                      hum = res[0]*256+res[1]
                      temp = res[2]*256 + res[3]
                      if (temp > 0x7fff):
                          temp = 0x8000 - temp
                      return temp, hum
                  
                  dht_pin=Pin('G7', mode=Pin.OPEN_DRAIN)
                  dht_pin(1)
                  
                  temp, hum = DHT11(dht_pin)
                  
                  temp_str = '{}.{}'.format(temp//10,temp%10)
                  hum_str = '{}.{}'.format(hum//10,hum%10)
                  
                  # Print or upload it
                  print(temp_str, hum_str)
                  

                  It matches with a 10% difference with two cheap commercial temp/humidity devices I have, but I cannot tell which is right or wrong
                  Update: After an hour of settling, the two sensors show almost identical readings.

                  robert-hhR 1 Reply Last reply Reply Quote 1
                  • robert-hhR Offline
                    robert-hh @robert-hh
                    last edited by robert-hh

                    @robert-hh A slight re-arrangement of lines in getval() made the capture get the leading '0' bit. That also tells how critical the timing is. Still, even with IRQ disabled, sometimes transitions are missing.

                    from machine import enable_irq, disable_irq,  Pin
                    import time
                    _LIMIT = const(8)
                    _BUFFERSIZE = const(1000)
                    
                    def getval(pin) :
                        ms = [1] * _BUFFERSIZE
                        mslen = len(ms)
                        pin(0)
                        time.sleep_us(20000)
                        pin(1)
                        irqf = disable_irq()
                        for _ in range(mslen):
                            ms[_] = pin()      ## sample input and store value
                        enable_irq(irqf)
                        return ms
                    
                    def decode(inp):
                        res= [0]*5
                        bits=[]
                        ix = 0
                        try:
                            if inp[0] == 1 : 
                                ix = inp.index(0, ix) ## skip to first 0
                            ix = inp.index(1,ix) ## skip first 0's to next 1
                            ix = inp.index(0,ix) ## skip first 1's to next 0
                            while len(bits) < len(res)*8 : ##need 5 * 8 bits :
                                ix = inp.index(1,ix) ## index of next 1
                                ie = inp.index(0,ix) ## nr of 1's = ie-ix
                                bits.append(ie-ix)
                                ix = ie
                        except Exception as err:
                            print (err, ix, len(bits))
                            return([0xff,0xff,0xff,0xff])
                    
                        for i in range(len(res)):
                            for v in bits[i*8:(i+1)*8]:   #process next 8 bit
                                res[i] = res[i]<<1  ##shift byte one place to left
                                if v > _LIMIT:
                                    res[i] = res[i]+1  ##and add 1 if lsb is 1
                    
                        if (res[0]+res[1]+res[2]+res[3])&0xff != res[4] :   ##parity error!
                            print("Checksum Error")
                            res= [0xff,0xff,0xff,0xff]
                    
                        return(res[0:4])
                    
                    def DHT11(pin):
                        res = decode(getval(pin))
                        temp = 10 * res[0] + res[1]
                        hum = 10 * res[2] + res[3]
                        return temp, hum
                    
                    def DHT22(pin) :
                        res = decode(getval(pin))
                        hum = res[0]*256+res[1]
                        temp = res[2]*256 + res[3]
                        if (temp > 0x7fff):
                            temp = 0x8000 - temp
                        return temp, hum
                    
                    def run():
                        dht_pin=Pin('G7', mode=Pin.OPEN_DRAIN)
                        dht_pin(1)
                    
                        temp, hum = DHT11(dht_pin)
                    
                        temp_str = '{}.{}'.format(temp//10,temp%10)
                        hum_str = '{}.{}'.format(hum//10,hum%10)
                    
                        # Print or upload it
                        print(temp_str, hum_str)
                    
                    run()
                    
                    1 Reply Last reply Reply Quote 0
                    • Jurassic PorkJ Offline
                      Jurassic Pork
                      last edited by

                      This post is deleted!
                      1 Reply Last reply Reply Quote 0
                      • Jurassic PorkJ Offline
                        Jurassic Pork @jmarcelino
                        last edited by

                        hello,
                        if someone can try my dht11 class and say me if it works for him.
                        It seems to be OK with a SiPy powered with USB .
                        DHT11_PyCom

                        Friendly, J.P

                        1 Reply Last reply Reply Quote 0

                        Hello! It looks like you're interested in this conversation, but you don't have an account yet.

                        Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

                        With your input, this post could be even better 💗

                        Register Login
                        • 1 / 1
                        • First post
                          Last post

                        Pycom on Twitter

                        Pycom