Add retry to DHT11/21/22 sensors

Might fix issue (#961)
This commit is contained in:
arendst 2017-10-27 12:13:36 +02:00
parent 844ec2f868
commit 133ba11a6c
1 changed files with 45 additions and 39 deletions

View File

@ -27,6 +27,7 @@
\*********************************************************************************************/ \*********************************************************************************************/
#define DHT_MAX_SENSORS 3 #define DHT_MAX_SENSORS 3
#define DHT_MAX_RETRY 8
#define MIN_INTERVAL 2000 #define MIN_INTERVAL 2000
uint32_t dht_max_cycles; uint32_t dht_max_cycles;
@ -38,15 +39,15 @@ struct DHTSTRUCT {
byte type; byte type;
char stype[10]; char stype[10];
uint32_t lastreadtime; uint32_t lastreadtime;
uint16_t lastresult; uint8_t lastresult;
float t; float t;
float h = 0; float h = 0;
} dht[DHT_MAX_SENSORS]; } Dht[DHT_MAX_SENSORS];
void DhtReadPrep() void DhtReadPrep()
{ {
for (byte i = 0; i < dht_sensors; i++) { for (byte i = 0; i < dht_sensors; i++) {
digitalWrite(dht[i].pin, HIGH); digitalWrite(Dht[i].pin, HIGH);
} }
} }
@ -54,7 +55,7 @@ uint32_t DhtExpectPulse(byte sensor, bool level)
{ {
uint32_t count = 0; uint32_t count = 0;
while (digitalRead(dht[sensor].pin) == level) { while (digitalRead(Dht[sensor].pin) == level) {
if (count++ >= dht_max_cycles) { if (count++ >= dht_max_cycles) {
return 0; return 0;
} }
@ -67,33 +68,38 @@ void DhtRead(byte sensor)
uint32_t cycles[80]; uint32_t cycles[80];
uint32_t currenttime = millis(); uint32_t currenttime = millis();
if ((currenttime - dht[sensor].lastreadtime) < 2000) { if ((currenttime - Dht[sensor].lastreadtime) < MIN_INTERVAL) {
return; return;
} }
dht[sensor].lastreadtime = currenttime; Dht[sensor].lastreadtime = currenttime;
dht_data[0] = dht_data[1] = dht_data[2] = dht_data[3] = dht_data[4] = 0; dht_data[0] = dht_data[1] = dht_data[2] = dht_data[3] = dht_data[4] = 0;
// digitalWrite(dht[sensor].pin, HIGH); // digitalWrite(Dht[sensor].pin, HIGH);
// delay(250); // delay(250);
pinMode(dht[sensor].pin, OUTPUT); if (Dht[sensor].lastresult > DHT_MAX_RETRY) {
digitalWrite(dht[sensor].pin, LOW); Dht[sensor].lastresult = 0;
digitalWrite(Dht[sensor].pin, HIGH); // Retry read prep
delay(250);
}
pinMode(Dht[sensor].pin, OUTPUT);
digitalWrite(Dht[sensor].pin, LOW);
delay(20); delay(20);
noInterrupts(); noInterrupts();
digitalWrite(dht[sensor].pin, HIGH); digitalWrite(Dht[sensor].pin, HIGH);
delayMicroseconds(40); delayMicroseconds(40);
pinMode(dht[sensor].pin, INPUT_PULLUP); pinMode(Dht[sensor].pin, INPUT_PULLUP);
delayMicroseconds(10); delayMicroseconds(10);
if (0 == DhtExpectPulse(sensor, LOW)) { if (0 == DhtExpectPulse(sensor, LOW)) {
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DHT D_TIMEOUT_WAITING_FOR " " D_START_SIGNAL_LOW " " D_PULSE)); AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DHT D_TIMEOUT_WAITING_FOR " " D_START_SIGNAL_LOW " " D_PULSE));
dht[sensor].lastresult++; Dht[sensor].lastresult++;
return; return;
} }
if (0 == DhtExpectPulse(sensor, HIGH)) { if (0 == DhtExpectPulse(sensor, HIGH)) {
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DHT D_TIMEOUT_WAITING_FOR " " D_START_SIGNAL_HIGH " " D_PULSE)); AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DHT D_TIMEOUT_WAITING_FOR " " D_START_SIGNAL_HIGH " " D_PULSE));
dht[sensor].lastresult++; Dht[sensor].lastresult++;
return; return;
} }
for (int i = 0; i < 80; i += 2) { for (int i = 0; i < 80; i += 2) {
@ -107,7 +113,7 @@ void DhtRead(byte sensor)
uint32_t highCycles = cycles[2*i+1]; uint32_t highCycles = cycles[2*i+1];
if ((0 == lowCycles) || (0 == highCycles)) { if ((0 == lowCycles) || (0 == highCycles)) {
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DHT D_TIMEOUT_WAITING_FOR " " D_PULSE)); AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DHT D_TIMEOUT_WAITING_FOR " " D_PULSE));
dht[sensor].lastresult++; Dht[sensor].lastresult++;
return; return;
} }
dht_data[i/8] <<= 1; dht_data[i/8] <<= 1;
@ -121,30 +127,30 @@ void DhtRead(byte sensor)
AddLog(LOG_LEVEL_DEBUG); AddLog(LOG_LEVEL_DEBUG);
if (dht_data[4] == ((dht_data[0] + dht_data[1] + dht_data[2] + dht_data[3]) & 0xFF)) { if (dht_data[4] == ((dht_data[0] + dht_data[1] + dht_data[2] + dht_data[3]) & 0xFF)) {
dht[sensor].lastresult = 0; Dht[sensor].lastresult = 0;
} else { } else {
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DHT D_CHECKSUM_FAILURE)); AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DHT D_CHECKSUM_FAILURE));
dht[sensor].lastresult++; Dht[sensor].lastresult++;
} }
} }
boolean DhtReadTempHum(byte sensor, float &t, float &h) boolean DhtReadTempHum(byte sensor, float &t, float &h)
{ {
if (!dht[sensor].h) { if (!Dht[sensor].h) {
t = NAN; t = NAN;
h = NAN; h = NAN;
} else { } else {
if (dht[sensor].lastresult > 8) { // Reset after 8 misses if (Dht[sensor].lastresult > DHT_MAX_RETRY) { // Reset after 8 misses
dht[sensor].t = NAN; Dht[sensor].t = NAN;
dht[sensor].h = NAN; Dht[sensor].h = NAN;
} }
t = dht[sensor].t; t = Dht[sensor].t;
h = dht[sensor].h; h = Dht[sensor].h;
} }
DhtRead(sensor); DhtRead(sensor);
if (!dht[sensor].lastresult) { if (!Dht[sensor].lastresult) {
switch (dht[sensor].type) { switch (Dht[sensor].type) {
case GPIO_DHT11: case GPIO_DHT11:
h = dht_data[0]; h = dht_data[0];
t = ConvertTemp(dht_data[2]); t = ConvertTemp(dht_data[2]);
@ -166,10 +172,10 @@ boolean DhtReadTempHum(byte sensor, float &t, float &h)
break; break;
} }
if (!isnan(t)) { if (!isnan(t)) {
dht[sensor].t = t; Dht[sensor].t = t;
} }
if (!isnan(h)) { if (!isnan(h)) {
dht[sensor].h = h; Dht[sensor].h = h;
} }
} }
return (!isnan(t) && !isnan(h)); return (!isnan(t) && !isnan(h));
@ -180,8 +186,8 @@ boolean DhtSetup(byte pin, byte type)
boolean success = false; boolean success = false;
if (dht_sensors < DHT_MAX_SENSORS) { if (dht_sensors < DHT_MAX_SENSORS) {
dht[dht_sensors].pin = pin; Dht[dht_sensors].pin = pin;
dht[dht_sensors].type = type; Dht[dht_sensors].type = type;
dht_sensors++; dht_sensors++;
success = true; success = true;
} }
@ -193,21 +199,21 @@ void DhtInit()
dht_max_cycles = microsecondsToClockCycles(1000); // 1 millisecond timeout for reading pulses from DHT sensor. dht_max_cycles = microsecondsToClockCycles(1000); // 1 millisecond timeout for reading pulses from DHT sensor.
for (byte i = 0; i < dht_sensors; i++) { for (byte i = 0; i < dht_sensors; i++) {
pinMode(dht[i].pin, INPUT_PULLUP); pinMode(Dht[i].pin, INPUT_PULLUP);
dht[i].lastreadtime = 0; Dht[i].lastreadtime = 0;
dht[i].lastresult = 0; Dht[i].lastresult = 0;
switch (dht[i].type) { switch (Dht[i].type) {
case GPIO_DHT11: case GPIO_DHT11:
strcpy_P(dht[i].stype, PSTR("DHT11")); strcpy_P(Dht[i].stype, PSTR("DHT11"));
break; break;
case GPIO_DHT21: case GPIO_DHT21:
strcpy_P(dht[i].stype, PSTR("AM2301")); strcpy_P(Dht[i].stype, PSTR("AM2301"));
break; break;
case GPIO_DHT22: case GPIO_DHT22:
strcpy_P(dht[i].stype, PSTR("DHT22")); strcpy_P(Dht[i].stype, PSTR("DHT22"));
} }
if (dht_sensors > 1) { if (dht_sensors > 1) {
snprintf_P(dht[i].stype, sizeof(dht[i].stype), PSTR("%s-%02d"), dht[i].stype, dht[i].pin); snprintf_P(Dht[i].stype, sizeof(Dht[i].stype), PSTR("%s-%02d"), Dht[i].stype, Dht[i].pin);
} }
} }
} }
@ -228,7 +234,7 @@ void MqttShowDht(uint8_t* djson)
if (DhtReadTempHum(i, t, h)) { // Read temperature if (DhtReadTempHum(i, t, h)) { // Read temperature
dtostrfd(t, Settings.flag.temperature_resolution, stemp1); dtostrfd(t, Settings.flag.temperature_resolution, stemp1);
dtostrfd(h, Settings.flag.humidity_resolution, stemp2); dtostrfd(h, Settings.flag.humidity_resolution, stemp2);
snprintf_P(mqtt_data, sizeof(mqtt_data), JSON_SNS_TEMPHUM, mqtt_data, dht[i].stype, stemp1, stemp2); snprintf_P(mqtt_data, sizeof(mqtt_data), JSON_SNS_TEMPHUM, mqtt_data, Dht[i].stype, stemp1, stemp2);
*djson = 1; *djson = 1;
#ifdef USE_DOMOTICZ #ifdef USE_DOMOTICZ
if (!dsxflg) { if (!dsxflg) {
@ -252,10 +258,10 @@ String WebShowDht()
for (byte i = 0; i < dht_sensors; i++) { for (byte i = 0; i < dht_sensors; i++) {
if (DhtReadTempHum(i, t, h)) { if (DhtReadTempHum(i, t, h)) {
dtostrfi(t, Settings.flag.temperature_resolution, stemp); dtostrfi(t, Settings.flag.temperature_resolution, stemp);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, dht[i].stype, stemp, TempUnit()); snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, Dht[i].stype, stemp, TempUnit());
page += sensor; page += sensor;
dtostrfi(h, Settings.flag.humidity_resolution, stemp); dtostrfi(h, Settings.flag.humidity_resolution, stemp);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_HUM, dht[i].stype, stemp); snprintf_P(sensor, sizeof(sensor), HTTP_SNS_HUM, Dht[i].stype, stemp);
page += sensor; page += sensor;
} }
} }