Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DHT sensors protocol revision and refactoring #7468

Closed
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 56 additions & 12 deletions tasmota/xsns_06_dht.ino
Original file line number Diff line number Diff line change
Expand Up @@ -72,28 +72,70 @@ bool DhtRead(uint8_t sensor)

dht_data[0] = dht_data[1] = dht_data[2] = dht_data[3] = dht_data[4] = 0;

// digitalWrite(Dht[sensor].pin, HIGH);
// delay(250);

if (Dht[sensor].lastresult > DHT_MAX_RETRY) {
Dht[sensor].lastresult = 0;
digitalWrite(Dht[sensor].pin, HIGH); // Retry read prep
delay(250);
}

// Activate sensor using its protocol
noInterrupts();
pinMode(Dht[sensor].pin, OUTPUT);
digitalWrite(Dht[sensor].pin, LOW);

if (GPIO_SI7021 == Dht[sensor].type) {
delayMicroseconds(500);
} else {
delay(20);
switch (Dht[sensor].type) {
case GPIO_SI7021: // Start protocol for iTead SI7021
/*
Protocol:
Reverse-engineered on https://github.com/arendst/Tasmota/issues/735#issuecomment-348718383:
1. MCU PULLS LOW data bus for at 500us to activate sensor
2. MCU PULLS UP data bus for ~40us to ask sensor for response
3. SENSOR starts sending data (LOW 40us then HIGH ~25us for "0" or ~75us for "1")
4. SENSOR sends "1" start bit as a response
5. SENSOR sends 16 bits (2 bytes) of a humidity with one decimal (i.e. 35.6% is sent as 356)
6. SENSOR sends 16 bits (2 bytes) of a temperature with one decimal (i.e. 23.4C is sent as 234)
7. SENSOR sends 8 bits (1 byte) checksum of 4 data bytes
*/
digitalWrite(Dht[sensor].pin, LOW);
delayMicroseconds(500);
digitalWrite(Dht[sensor].pin, HIGH);
delayMicroseconds(40);
break;

case GPIO_DHT22: // Start protocol for DHT21, DHT22, AM2301, AM2302, AM2321
/*
Protocol:
1. MCU PULLS LOW data bus for 1 to 10ms to activate sensor
2. MCU PULLS UP data bus for 20-40us to ask sensor for response
3. SENSOR PULLS LOW data bus for 80us as a response
4. SENSOR PULLS UP data bus for 80us for data sending preparation
5. SENSOR starts sending data (LOW 50us then HIGH 26-28us for "0" or 70us for "1")
*/
digitalWrite(Dht[sensor].pin, LOW);
delayMicroseconds(1100); // data sheet says "at least 1ms to 10ms"
digitalWrite(Dht[sensor].pin, HIGH);
delayMicroseconds(30); // data sheet says "20 to 40us"
break;

case GPIO_DHT11: // Start protocol for DHT11
/*
Protocol:
1. MCU PULLS LOW data bus for at least 18ms to activate sensor
2. MCU PULLS UP data bus for 20-40us to ask sensor for response
3. SENSOR PULLS LOW data bus for 80us as a response
4. SENSOR PULLS UP data bus for 80us for data sending preparation
5. SENSOR starts sending data (LOW 50us then HIGH 26-28us for "0" or 70 us for "1")
*/
default:
digitalWrite(Dht[sensor].pin, LOW);
delay(20); // data sheet says at least 18ms, 20ms just to be safe
digitalWrite(Dht[sensor].pin, HIGH);
delayMicroseconds(30); // data sheet says "20 to 40us"
break;
}

noInterrupts();
digitalWrite(Dht[sensor].pin, HIGH);
delayMicroseconds(40);
// Listen to the sensor response
pinMode(Dht[sensor].pin, INPUT_PULLUP);
delayMicroseconds(10);

if (-1 == DhtExpectPulse(sensor, LOW)) {
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DHT D_TIMEOUT_WAITING_FOR " " D_START_SIGNAL_LOW " " D_PULSE));
error = 1;
Expand All @@ -111,6 +153,7 @@ bool DhtRead(uint8_t sensor)
interrupts();
if (error) { return false; }

// Decode response
for (uint32_t i = 0; i < 40; ++i) {
int32_t lowCycles = cycles[2*i];
int32_t highCycles = cycles[2*i+1];
Expand All @@ -124,6 +167,7 @@ bool DhtRead(uint8_t sensor)
}
}

// Check response
uint8_t checksum = (dht_data[0] + dht_data[1] + dht_data[2] + dht_data[3]) & 0xFF;
if (dht_data[4] != checksum) {
char hex_char[15];
Expand Down