mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-28 13:16:32 +00:00
Update xsns_06_dht.ino
the DHT22/AM2301 did not work on Sonoff S20 and NodeMCU (possibly microsecond delay not exact enough??) and gave only "null" values for temperature and humidity. So I changed the way to determine if a bit is "0" or "1" by measuring the time in microseconds until state changes. If time > 50 usec (in data sheet it should be 80 usec), it is recognized as "1", otherwise (a "0" should be 26-28 usec by specs from data sheet) it is treated as "0". Also, the old version omitted the first bit (by waiting the sequence 0 - 1 - 0, I have changed it to the only first "0" This change has been tested on Sonoff S20 (on GPIO 3) and on NodeMCU (GPIO 2) on Tasmota version 9.3.1.4 (on version 9.5. it should make no difference) with a DHT22 with included pull-up resistor
This commit is contained in:
parent
80f18a53e1
commit
5c329713fe
@ -47,18 +47,21 @@ struct DHTSTRUCT {
|
|||||||
float h = NAN;
|
float h = NAN;
|
||||||
} Dht[DHT_MAX_SENSORS];
|
} Dht[DHT_MAX_SENSORS];
|
||||||
|
|
||||||
bool DhtWaitState(uint32_t sensor, uint32_t level)
|
// changed from bool to unsigned long returning the time to wait until state changes
|
||||||
|
unsigned long DhtWaitState(uint32_t sensor, uint32_t level)
|
||||||
{
|
{
|
||||||
unsigned long timeout = micros() + 100;
|
unsigned long timeout = micros() + 100;
|
||||||
|
unsigned long startms = micros();
|
||||||
|
|
||||||
while (digitalRead(Dht[sensor].pin) != level) {
|
while (digitalRead(Dht[sensor].pin) != level) {
|
||||||
if (TimeReachedUsec(timeout)) {
|
if (TimeReachedUsec(timeout)) {
|
||||||
AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_DHT D_TIMEOUT_WAITING_FOR " %s " D_PULSE),
|
AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_DHT D_TIMEOUT_WAITING_FOR " %s " D_PULSE),
|
||||||
(level) ? D_START_SIGNAL_HIGH : D_START_SIGNAL_LOW);
|
(level) ? D_START_SIGNAL_HIGH : D_START_SIGNAL_LOW);
|
||||||
return false;
|
return 0; // return 0 (==false for compatibility) if timeout reached
|
||||||
}
|
}
|
||||||
delayMicroseconds(1);
|
delayMicroseconds(1);
|
||||||
}
|
}
|
||||||
return true;
|
return micros()-startms;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DhtRead(uint32_t sensor)
|
bool DhtRead(uint32_t sensor)
|
||||||
@ -78,7 +81,8 @@ bool DhtRead(uint32_t sensor)
|
|||||||
break;
|
break;
|
||||||
case GPIO_DHT22: // DHT21, DHT22, AM2301, AM2302, AM2321
|
case GPIO_DHT22: // DHT21, DHT22, AM2301, AM2302, AM2321
|
||||||
// delay(2); // minimum 1ms
|
// delay(2); // minimum 1ms
|
||||||
delayMicroseconds(2000); // See https://github.com/arendst/Tasmota/pull/7468#issuecomment-647067015
|
// delayMicroseconds(2000); // See https://github.com/arendst/Tasmota/pull/7468#issuecomment-647067015
|
||||||
|
delayMicroseconds(1100); // changed to Arduino DHT library value
|
||||||
break;
|
break;
|
||||||
case GPIO_SI7021: // iTead SI7021
|
case GPIO_SI7021: // iTead SI7021
|
||||||
delayMicroseconds(500);
|
delayMicroseconds(500);
|
||||||
@ -133,14 +137,12 @@ bool DhtRead(uint32_t sensor)
|
|||||||
|
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
noInterrupts();
|
noInterrupts();
|
||||||
if (DhtWaitState(sensor, 0) && DhtWaitState(sensor, 1) && DhtWaitState(sensor, 0)) {
|
if (DhtWaitState(sensor, 0)) { // only wait for one state change to 0
|
||||||
for (i = 0; i < 40; i++) {
|
for (i = 0; i < 40; i++) {
|
||||||
if (!DhtWaitState(sensor, 1)) { break; }
|
if (!DhtWaitState(sensor, 1)) { break; }
|
||||||
delayMicroseconds(32); // Was 30
|
int wt = DhtWaitState(sensor,0); // determine time to change state
|
||||||
if (digitalRead(Dht[sensor].pin)) {
|
if(wt==0) break;
|
||||||
dht_data[i / 8] |= (1 << (7 - i % 8));
|
if(wt>50) dht_data[i / 8] |= (1 << (7 - i % 8)); // if longer than 50 usec then 1, else 0
|
||||||
}
|
|
||||||
if (!DhtWaitState(sensor, 0)) { break; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
interrupts();
|
interrupts();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user