8000 drivers/dht: Add option to do the measure without blocking interrupts. · micropython/micropython@cca2f91 · GitHub
[go: up one dir, main page]

Skip to content

Commit cca2f91

Browse files
committed
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.
1 parent 75db0b9 commit cca2f91

File tree

3 files changed

+40
-8
lines changed

3 files changed

+40
-8
lines changed

docs/esp8266/tutorial/dht.rst

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,22 @@ To make newer I2C sensors work in backwards compatible 1-wire mode, you must
6363
connect both pins 3 and 4 to GND. This disables the I2C interface.
6464

6565
DHT22 sensors are now sold under the name AM2302 and are otherwise identical.
66+
67+
NOTE: if your are using a PWM channel in parallel of your measure, there can
68+
be some glitches on the PWM channel at the measure time. This is because
69+
the DHT drivers locks interrupts for accurate protocol timing handling,
70+
and the PWM driver relies on these interrupts. The constructor of the DHT
71+
objects has an extra argument irq_lock which can be set to False.
72+
The risk is low, but in case of timing issues a DHTChecksumError can be
73+
raised, catch it and retry.
74+
75+
>>> import dht
76+
>>> import machine
77+
>>> d = dht.DHT22(machine.Pin(4), False)
78+
>>> measure_ok = False
79+
>>> while not measure_ok:
80+
>>> try:
81+
>>> d.measure()
82+
>>> measure_ok = True
83+
>>> except dht.DHTChecksumError:
84+
>>> pass

drivers/dht/dht.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@
3737
#define mp_hal_pin_od_high_dht mp_hal_pin_od_high
3838
#endif
3939

40-
STATIC mp_obj_t dht_readinto(mp_obj_t pin_in, mp_obj_t buf_in) {
40+
STATIC mp_obj_t dht_readinto(mp_obj_t pin_in, mp_obj_t buf_in, mp_obj_t irq_lock) {
41+
mp_uint_t irq_state=0;
42+
4143
mp_hal_pin_obj_t pin = mp_hal_get_pin_obj(pin_in);
4244
mp_hal_pin_open_drain(pin);
4345

@@ -54,7 +56,9 @@ STATIC mp_obj_t dht_readinto(mp_obj_t pin_in, mp_obj_t buf_in) {
5456
mp_hal_pin_od_low(pin);
5557
mp_hal_delay_ms(18);
5658

57-
mp_uint_t irq_state = mp_hal_quiet_timing_enter();
59+
if (mp_obj_is_true(irq_lock)) {
60+
irq_state = mp_hal_quiet_timing_enter();
61+
}
5862

5963
// release the line so the device can respond
6064
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) {
8488
buf[i / 8] = (buf[i / 8] << 1) | (ticks > 48);
8589
}
8690

87-
mp_hal_quiet_timing_exit(irq_state);
91+
if (mp_obj_is_true(irq_lock)) {
92+
mp_hal_quiet_timing_exit(irq_state);
93+
}
8894
return mp_const_none;
8995

9096
timeout:
91-
mp_hal_quiet_timing_exit(irq_state);
97+
if (mp_obj_is_true(irq_lock)) {
98+
mp_hal_quiet_timing_exit(irq_state);
99+
}
92100
mp_raise_OSError(MP_ETIMEDOUT);
93101
}
94-
MP_DEFINE_CONST_FUN_OBJ_2(dht_readinto_obj, dht_readinto);
102+
MP_DEFINE_CONST_FUN_OBJ_3(dht_readinto_obj, dht_readinto);

drivers/dht/dht.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,21 @@
77
from pyb import dht_readinto
88

99

10+
class DHTChecksumError(Exception):
11+
pass
12+
13+
1014
class DHTBase:
11-
def __init__(self, pin):
15+
def __init__(self, pin, irq_block=True):
1216
self.pin = pin
1317
self.buf = bytearray(5)
18+
self.irq_block = irq_block
1419

1520
def measure(self):
1621
buf = self.buf
17-
dht_readinto(self.pin, buf)
22+
dht_readinto(self.pin, buf, self.irq_block)
1823
if (buf[0] + buf[1] + buf[2] + buf[3]) & 0xFF != buf[4]:
19-
raise Exception("checksum error")
24+
raise DHTChecksumError("Measure failed")
2025

2126

2227
class DHT11(DHTBase):

0 commit comments

Comments
 (0)
0