DHT22 / AM2302 library for Wipy

Discuss development of drivers for external hardware and components, such as LCD screens, sensors, motor drivers, etc.
Target audience: Users and developers of drivers.
Miguel
Posts: 20
Joined: Fri Sep 09, 2016 7:53 am

Re: DHT22 / AM2302 library for Wipy

Post by Miguel » Tue Sep 20, 2016 9:03 am

Hello Jim!

I have a 4.7k pull-up resistor between VCC and DATA pins, so the data pin should be high by default.

I have also tried to set the data pin to 1 for a long period before sending start signal with the same results.

I am obviously doing something wrong. My sensor readings are not consistent in time and I usually get 0s in the first 8 bits.

I have also purchased BME280 module for I2C bus. Works flawlessly with this driver from Paul: viewtopic.php?f=14&t=1315#p8064

Looking forward to your tests.

Michal

jgmdavies
Posts: 57
Joined: Tue Aug 09, 2016 2:39 pm

Re: DHT22 / AM2302 library for Wipy

Post by jgmdavies » Tue Sep 20, 2016 9:05 am

Also, after looking at the two other code examples, I suspect your 'edge' function should have:

Code: Select all

times[index] = utime.ticks_us())
instead of using 'ticks_diff', as you're testing the differences later, in 'process_data'?

Miguel
Posts: 20
Joined: Fri Sep 09, 2016 7:53 am

Re: DHT22 / AM2302 library for Wipy

Post by Miguel » Tue Sep 20, 2016 9:42 am

I think both ways are correct. We can use ticks_diff in edge function or later in process_data. But using it in process_data might be better becuase it will make edge function faster.

Michal

jgmdavies
Posts: 57
Joined: Tue Aug 09, 2016 2:39 pm

Re: DHT22 / AM2302 library for Wipy

Post by jgmdavies » Tue Sep 20, 2016 10:51 am

But aren't you getting a sort of 'double difference' at the moment, by using 'times_diff' in the ISR, and then subtracting times later??

Miguel
Posts: 20
Joined: Fri Sep 09, 2016 7:53 am

Re: DHT22 / AM2302 library for Wipy

Post by Miguel » Tue Sep 20, 2016 11:08 am

Now I store in times list just simple timestamps - the number of microseconds from the moment, when the whole communication started to the actual moment, when the edge function is called. Then in process_data, I just count the difference between two consecutive values thus getting the number of microseconds between two falling edges.

Michal

jgmdavies
Posts: 57
Joined: Tue Aug 09, 2016 2:39 pm

Re: DHT22 / AM2302 library for Wipy

Post by jgmdavies » Tue Sep 20, 2016 11:35 am

Ah, OK - I get it.

I'll experiment when I get the DHT22 (and I've also ordered a BME280!).

Thanks Michal.

Miguel
Posts: 20
Joined: Fri Sep 09, 2016 7:53 am

Re: DHT22 / AM2302 library for Wipy

Post by Miguel » Tue Sep 20, 2016 11:53 am

You are welcome. I am glad that you will help me with the driver because I don't have much experience with neither Python nor electronics.

Warning: I realized that having working sensor with BME280 is a strong demotivating factor for my effort to debug the DHT22 driver:-)

Michal

quantalume
Posts: 15
Joined: Thu Aug 04, 2016 3:04 pm

Re: DHT22 / AM2302 library for Wipy

Post by quantalume » Wed Sep 21, 2016 5:39 pm

I took a crack at this but was ultimately unsuccessful. The problem is that it takes too long to switch pin modes in Python, and you lose the data before you even get interrupts set up to catch the falling edges. One way around this problem might be to use two pins connected together, one configured as open drain output and the other as input. That way, you only need to set up interrupts in the beginning. However, calls to time.ticks may also take too long. Probably the best way to handle this is a true driver written in C, but I doubt anyone will bother now that WiPy 2.0 is out. Here is my code in case anyone wants to have a go. I did clean up the original code, removing global variables and making it object-oriented and a bit more Pythonic.

Code: Select all

from machine import Pin
import time

class DHT22:
    FALLING_EDGES = 42 # we have 42 falling edges during data receive

    def __init__(self, pin):
        self.times = [0] * DHT22.FALLING_EDGES
        self.data = Pin(pin, mode=Pin.OUT)
        self.data(1)
        self.index = 0	

    # The interrupt handler
    def edge(self, line):
        self.times[index] = time.ticks_diff(self.start, time.ticks_us())
        if self.index < (DHT22.FALLING_EDGES - 1): # Avoid overflow of the buffer in case of any noise on the line
            self.index += 1

    # Start signal
    def do_measurement(self):
        # Send the START signal
        self.data.init(mode=Pin.OUT)
        self.index = 0
        self.data(0)
        time.sleep_ms(2)
        self.data(1)
        self.start = time.ticks_us()

        # Activate reading on the data pin
        self.data.init(mode=Pin.IN)
        self.data.irq(trigger=Pin.IRQ_FALLING, handler=self.edge)
        # Till 5mS the measurement must be over
        time.sleep_ms(5)

    # Parse the data read from the sensor
    def process_data(self):
        i = 2 # We ignore the first two falling edges as it is a response on the start signal
        result_i = 0
        result = list([0, 0, 0, 0, 0])
        while i < DHT22.FALLING_EDGES:
            result[result_i] <<= 1
            if self.times[i] - self.times[i - 1] > 100:
                result[result_i] += 1
            if (i % 8) == 1:
                result_i += 1
            i += 1
        [int_rh, dec_rh, int_t, dec_t, csum] = result
        humidity = ((int_rh * 256) + dec_rh)/10
        temperature = (((int_t & 0x7F) * 256) + dec_t)/10
        if (int_t & 0x80) > 0:
            temperature *= -1
        comp_sum = int_rh + dec_rh + int_t + dec_t
        if (comp_sum & 0xFF) != csum:
            raise ValueError('Checksum does not match')
        return (humidity, temperature)

    def measure(self):
        self.do_measurement()
        if self.index != (DHT22.FALLING_EDGES -1):
            raise ValueError('Data transfer failed: %s falling edges only' % str(self.index))
        return self.process_data()

Miguel
Posts: 20
Joined: Fri Sep 09, 2016 7:53 am

Re: DHT22 / AM2302 library for Wipy

Post by Miguel » Thu Sep 22, 2016 6:34 am

Thanks a lot for your effort! It's a pitty that such driver works on Pyboard but doesn't work on Wipy. Do you think that Wipy 2.0 (based on ESP32) will do better in this particular case?

I have just noticed your latest post in former DHT thread viewtopic.php?f=14&t=1392#p14098 Since I use that Robert's firmware too, I will try the driver from RinusW again.

Michal

quantalume
Posts: 15
Joined: Thu Aug 04, 2016 3:04 pm

Re: DHT22 / AM2302 library for Wipy

Post by quantalume » Thu Sep 22, 2016 7:42 pm

The ESP series of modules seems to have a bigger following than the CC3200-based modules. A DHT driver already exists for micropython on the ESP8266, and I imagine there will soon be one for ESP32. Actually, unless you need bluetooth or more processor power, the ESP8266 is pretty much the best micropython platform IMHO. You have the alternative of running Arduino or Lua on the module too, should you need to take advantage of code already developed in one of those environments. The pyboard and WiPy were great when they were the only Python options, but we have more choices today.

Post Reply