From 1ce1fa0e3746ed61e5a109d16cc6e31e907abbe7 Mon Sep 17 00:00:00 2001 From: David Dix Date: Fri, 29 Nov 2019 23:47:30 +0000 Subject: [PATCH] Fix support for Si7021 and clarify timing comments Fixed conversion of the Si7021 data and fully tested over large temperature / humidity range. Also tested the AM2301 sensor (often used as alternative to Si7021) --- extras/dht/dht.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/extras/dht/dht.c b/extras/dht/dht.c index 0a2affa..e840e89 100644 --- a/extras/dht/dht.c +++ b/extras/dht/dht.c @@ -35,11 +35,18 @@ * * Initializing communications with the DHT requires four 'phases' as follows: * - * Phase A - MCU pulls signal low for at least 18000 us - * Phase B - MCU allows signal to float back up and waits 20-40us for DHT to pull it low + * Phase A - MCU pulls signal low for a period (see below) + * Phase B - MCU allows signal to float back up and waits 20-200us for DHT to pull it low * Phase C - DHT pulls signal low for ~80us * Phase D - DHT lets signal float back up for ~80us * + * The length of Phase A is dependent on the sensor type: + * DHT_TYPE_DHT11 : at least 18000 us + * DHT_TYPE_DHT22 : 800 us to 20000 us, typically 1100 us + * DHT_TYPE_SI7021 : 300 us to 500 us + * For a DHT21 use DHT_TYPE_DHT22 + * For an AM2301/AM2302 use DHT_TYPE_SI7021 + * * After this, the DHT transmits its first bit by holding the signal low for 50us * and then letting it float back high for a period of time that depends on the data bit. * duration_data_high is shorter than 50us for a logic '0' and longer than 50us for logic '1'. @@ -91,8 +98,8 @@ static inline bool dht_fetch_data(dht_sensor_type_t sensor_type, uint8_t pin, bo sdk_os_delay_us(sensor_type == DHT_TYPE_SI7021 ? 500 : 20000); gpio_write(pin, 1); - // Step through Phase 'B', 40us - if (!dht_await_pin_state(pin, 40, false, NULL)) { + // Step through Phase 'B', 200us + if (!dht_await_pin_state(pin, 200, false, NULL)) { debug("Initialization error, problem in phase 'B'\n"); return false; } @@ -131,7 +138,7 @@ static inline int16_t dht_convert_data(dht_sensor_type_t sensor_type, uint8_t ms { int16_t data; - if (sensor_type == DHT_TYPE_DHT22) { + if (sensor_type == DHT_TYPE_DHT22 || sensor_type == DHT_TYPE_SI7021) { data = msb & 0x7F; data <<= 8; data |= lsb; @@ -139,9 +146,6 @@ static inline int16_t dht_convert_data(dht_sensor_type_t sensor_type, uint8_t ms data = 0 - data; // convert it to negative } } - else if (sensor_type == DHT_TYPE_SI7021) { - data = msb * 256 + (lsb & ~0x3); - } else { data = msb * 10; }