From cca2f917221e339ae523dac99d9ed932a3747766 Mon Sep 17 00:00:00 2001 From: Olivier Ortigues Date: Sun, 21 Feb 2021 10:28:41 +0100 Subject: [PATCH 1/2] drivers/dht: Add option to do the measure without blocking interrupts. This is done because ESP8266 has a PWM relying on interrupts. Doing the DHT measure with interruption blocking, sometimes makes glitches on the PWM. --- docs/esp8266/tutorial/dht.rst | 19 +++++++++++++++++++ drivers/dht/dht.c | 18 +++++++++++++----- drivers/dht/dht.py | 11 ++++++++--- 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/docs/esp8266/tutorial/dht.rst b/docs/esp8266/tutorial/dht.rst index 1602e8a337455..754522e62741d 100644 --- a/docs/esp8266/tutorial/dht.rst +++ b/docs/esp8266/tutorial/dht.rst @@ -63,3 +63,22 @@ To make newer I2C sensors work in backwards compatible 1-wire mode, you must connect both pins 3 and 4 to GND. This disables the I2C interface. DHT22 sensors are now sold under the name AM2302 and are otherwise identical. + +NOTE: if your are using a PWM channel in parallel of your measure, there can +be some glitches on the PWM channel at the measure time. This is because +the DHT drivers locks interrupts for accurate protocol timing handling, +and the PWM driver relies on these interrupts. The constructor of the DHT +objects has an extra argument irq_lock which can be set to False. +The risk is low, but in case of timing issues a DHTChecksumError can be +raised, catch it and retry. + + >>> import dht + >>> import machine + >>> d = dht.DHT22(machine.Pin(4), False) + >>> measure_ok = False + >>> while not measure_ok: + >>> try: + >>> d.measure() + >>> measure_ok = True + >>> except dht.DHTChecksumError: + >>> pass diff --git a/drivers/dht/dht.c b/drivers/dht/dht.c index 81754ac15f43f..65a0ca61ff633 100644 --- a/drivers/dht/dht.c +++ b/drivers/dht/dht.c @@ -37,7 +37,9 @@ #define mp_hal_pin_od_high_dht mp_hal_pin_od_high #endif -STATIC mp_obj_t dht_readinto(mp_obj_t pin_in, mp_obj_t buf_in) { +STATIC mp_obj_t dht_readinto(mp_obj_t pin_in, mp_obj_t buf_in, mp_obj_t irq_lock) { + mp_uint_t irq_state=0; + mp_hal_pin_obj_t pin = mp_hal_get_pin_obj(pin_in); mp_hal_pin_open_drain(pin); @@ -54,7 +56,9 @@ STATIC mp_obj_t dht_readinto(mp_obj_t pin_in, mp_obj_t buf_in) { mp_hal_pin_od_low(pin); mp_hal_delay_ms(18); - mp_uint_t irq_state = mp_hal_quiet_timing_enter(); + if (mp_obj_is_true(irq_lock)) { + irq_state = mp_hal_quiet_timing_enter(); + } // release the line so the device can respond mp_hal_pin_od_high_dht(pin); @@ -84,11 +88,15 @@ STATIC mp_obj_t dht_readinto(mp_obj_t pin_in, mp_obj_t buf_in) { buf[i / 8] = (buf[i / 8] << 1) | (ticks > 48); } - mp_hal_quiet_timing_exit(irq_state); + if (mp_obj_is_true(irq_lock)) { + mp_hal_quiet_timing_exit(irq_state); + } return mp_const_none; timeout: - mp_hal_quiet_timing_exit(irq_state); + if (mp_obj_is_true(irq_lock)) { + mp_hal_quiet_timing_exit(irq_state); + } mp_raise_OSError(MP_ETIMEDOUT); } -MP_DEFINE_CONST_FUN_OBJ_2(dht_readinto_obj, dht_readinto); +MP_DEFINE_CONST_FUN_OBJ_3(dht_readinto_obj, dht_readinto); diff --git a/drivers/dht/dht.py b/drivers/dht/dht.py index 1163b382bbc77..a86c1927111ff 100644 --- a/drivers/dht/dht.py +++ b/drivers/dht/dht.py @@ -7,16 +7,21 @@ from pyb import dht_readinto +class DHTChecksumError(Exception): + pass + + class DHTBase: - def __init__(self, pin): + def __init__(self, pin, irq_block=True): self.pin = pin self.buf = bytearray(5) + self.irq_block = irq_block def measure(self): buf = self.buf - dht_readinto(self.pin, buf) + dht_readinto(self.pin, buf, self.irq_block) if (buf[0] + buf[1] + buf[2] + buf[3]) & 0xFF != buf[4]: - raise Exception("checksum error") + raise DHTChecksumError("Measure failed") class DHT11(DHTBase): From e6dbe2a1a9bcf3617ab2d50ae9e804ec17aa2c97 Mon Sep 17 00:00:00 2001 From: Olivier Ortigues Date: Wed, 24 Feb 2021 23:14:30 +0100 Subject: [PATCH 2/2] drivers/dht/dht.c: Modifications after pull requests comments. --- docs/esp8266/tutorial/dht.rst | 8 ++++---- drivers/dht/dht.c | 10 ++++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/docs/esp8266/tutorial/dht.rst b/docs/esp8266/tutorial/dht.rst index 754522e62741d..92e837966b936 100644 --- a/docs/esp8266/tutorial/dht.rst +++ b/docs/esp8266/tutorial/dht.rst @@ -70,15 +70,15 @@ the DHT drivers locks interrupts for accurate protocol timing handling, and the PWM driver relies on these interrupts. The constructor of the DHT objects has an extra argument irq_lock which can be set to False. The risk is low, but in case of timing issues a DHTChecksumError can be -raised, catch it and retry. +raised, catch it and retry. Depending on your use case, consider limiting +the number of retries. >>> import dht >>> import machine >>> d = dht.DHT22(machine.Pin(4), False) - >>> measure_ok = False - >>> while not measure_ok: + >>> while True: >>> try: >>> d.measure() - >>> measure_ok = True + >>> break >>> except dht.DHTChecksumError: >>> pass diff --git a/drivers/dht/dht.c b/drivers/dht/dht.c index 65a0ca61ff633..4c4061fa298b8 100644 --- a/drivers/dht/dht.c +++ b/drivers/dht/dht.c @@ -38,7 +38,9 @@ #endif STATIC mp_obj_t dht_readinto(mp_obj_t pin_in, mp_obj_t buf_in, mp_obj_t irq_lock) { - mp_uint_t irq_state=0; + mp_uint_t irq_state = 0; + + const bool do_lock = mp_obj_is_true(irq_lock); mp_hal_pin_obj_t pin = mp_hal_get_pin_obj(pin_in); mp_hal_pin_open_drain(pin); @@ -56,7 +58,7 @@ STATIC mp_obj_t dht_readinto(mp_obj_t pin_in, mp_obj_t buf_in, mp_obj_t irq_lock mp_hal_pin_od_low(pin); mp_hal_delay_ms(18); - if (mp_obj_is_true(irq_lock)) { + if (do_lock) { irq_state = mp_hal_quiet_timing_enter(); } @@ -88,13 +90,13 @@ STATIC mp_obj_t dht_readinto(mp_obj_t pin_in, mp_obj_t buf_in, mp_obj_t irq_lock buf[i / 8] = (buf[i / 8] << 1) | (ticks > 48); } - if (mp_obj_is_true(irq_lock)) { + if (do_lock) { mp_hal_quiet_timing_exit(irq_state); } return mp_const_none; timeout: - if (mp_obj_is_true(irq_lock)) { + if (do_lock) { mp_hal_quiet_timing_exit(irq_state); } mp_raise_OSError(MP_ETIMEDOUT); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy