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 refactoring #7440

Closed
wants to merge 2 commits into from
Closed

DHT sensors protocol refactoring #7440

wants to merge 2 commits into from

Conversation

KrzysztofPrzygoda
Copy link

@KrzysztofPrzygoda KrzysztofPrzygoda commented Jan 4, 2020

Description:

Related issue (if applicable): fixes #5619

Created one switch to embrace start reading protocols for all sensors in one place that helps for better readability. Only DHT22 protocol has been changed according to the issue #5619. Tested on AM2302.

DHT21, DHT22, AM2301, AM2302
Specs:
https://cdn-shop.adafruit.com/datasheets/Digital+humidity+and+temperature+sensor+AM2302.pdf

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")

DHT11
Specs:
https://www.mouser.com/datasheet/2/758/DHT11-Technical-Data-Sheet-Translated-Version-1143054.pdf

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")

SI7021
Specs:
https://www.silabs.com/documents/public/data-sheets/Si7021-A20.pdf

Protocol:
Reverse-engineered on #735 (comment):
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

Checklist:

  • The pull request is done against the latest dev branch
  • Only relevant files were touched
  • Only one feature/fix was added per PR.
  • The code change is tested and works on core 2.6.1
  • The code change pass travis tests. Your PR cannot be merged unless tests pass
  • I accept the CLA.

DHT21, DHT22, AM2301, AM2302
Specs:
https://cdn-shop.adafruit.com/datasheets/Digital+humidity+and+temperature+sensor+AM2302.pdf

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 70 us for "1")

DHT11
Specs:
https://www.mouser.com/datasheet/2/758/DHT11-Technical-Data-Sheet-Translated-Version-1143054.pdf

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")

SI7021
Specs:
https://www.silabs.com/documents/public/data-sheets/Si7021-A20.pdf

Protocol:
Reverse-engineered on #735 (comment):
	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
Addresses issue #5619 with DHT22 report null after a while.
Created one switch to embrace start reading protocols of all sensors in one place.

DHT21, DHT22, AM2301, AM2302
Specs:
https://cdn-shop.adafruit.com/datasheets/Digital+humidity+and+temperature+sensor+AM2302.pdf

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")

DHT11
Specs:
https://www.mouser.com/datasheet/2/758/DHT11-Technical-Data-Sheet-Translated-Version-1143054.pdf

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")

SI7021
Specs:
https://www.silabs.com/documents/public/data-sheets/Si7021-A20.pdf

Protocol:
Reverse-engineered on #735 (comment):
	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
@KrzysztofPrzygoda
Copy link
Author

Issue #7440 still occures.

@kiwichrish
Copy link

Hi. There is an issue copied/repeated by many sites with respect to this protocol.. The MCU should release the pin immediately after pulling it high as the reply time is typically 20-40us. Waiting 40us before releasing the pin causes a high current 'glitch' (showed up as 20-40mv drop in supply rail) of 15-20us when the sensor tries to pull down the pin at the same time the micro is holding it high.. I found this was causing issues for some DHT22 devices. Still testing my mods to the Tasmota drive for this, and not happy with results yet. :-)

@kiwichrish
Copy link

This image shows the release time at 20us min, 30us typical, so the I/O in pin should be in input_pullup (or just input) before the 40us delay that is in a lot of drivers.

https://i.stack.imgur.com/zFXUR.png (linked from R Pi forum comment)

@kiwichrish
Copy link

The 'real' datasheet for the DHT11 correctly shows that the bus should be released after 18ms start pulse.. Page 5, beside one of the timing graphs, 'Release the bus after Host Down'

https://akizukidenshi.com/download/ds/aosong/DHT11.pdf

I can't find a actual manufacturers datasheet for the AM2302 / DHT22 in English, but a lot with the same images repeated with the repeated error.

@kiwichrish
Copy link

Can someone do a literal translation of the Chinese text on those diagrams? They are often used in DHT22 / AM2302 data sheets with different English text on them. That English text does say 'Pull up' and wait for response though, which implies releasing the bus not driving it high? The other interesting thing is that the image on that site of the device itself is edited, no brand/serial/model on the device. Although it appears to be the same company Asair and Aosong DHT22's are definitely different based on the testing I've been doing.

@joba-1
Copy link
Contributor

joba-1 commented Jan 9, 2020

Never worked with this sensor and dont understand chinese, but I think there is just one possible interpretation that makes sense.
The one wire is weakly pulled high by the 5k resistor and mcu or sensor drive it low or release it to talk.
If mcu or sensor would drive it high at any time, they risk a short.

@KrzysztofPrzygoda
Copy link
Author

KrzysztofPrzygoda commented Jan 9, 2020

Sorry for little mess but I recreated PR in #7468. There are my current findings that seem to solve the issue (protocol cleanings and interrupts management). Let's continue discussion there but for now, to finish current comments here I'd replay that:

  1. Regarding timings: Yup, they needed to be adjusted for DHT22 and I did it in PR DHT sensors protocol revision and refactoring #7468 regarding data sheets.

  2. Regarding INPUT_PULLUP mode: It's not about setting GPIO HIGH but about setting ESP8266 internal pull up resistor, which makes GPIO LOW on LOW input.

IMO, the root-cause of the problem were both: 1) DHT22 bad timings and 2) noInterrupts() that was switched on too late (should be on at the very beginning of the protocol). My AM2302 has been working stable for 3 days now. Previously it hung (null readings) every few hours with power cycle as a remedy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

DHT22 report null after a while
4 participants