Library for the control of the DHT22.
Dependents: Interfacage_Disco_DHT22
DHT22.cpp@2:8c7fa818f329, 2020-04-16 (annotated)
- Committer:
- dacamposol
- Date:
- Thu Apr 16 12:00:14 2020 +0000
- Revision:
- 2:8c7fa818f329
- Parent:
- 1:3385bd532812
Increase the detail on the temperature and humidity (float accuracy)
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
dacamposol | 0:a4f404326ee0 | 1 | #include "DHT22.h" |
dacamposol | 0:a4f404326ee0 | 2 | |
dacamposol | 0:a4f404326ee0 | 3 | DHT22::DHT22(PinName pin) |
dacamposol | 0:a4f404326ee0 | 4 | { |
dacamposol | 0:a4f404326ee0 | 5 | pin_name = pin; |
dacamposol | 0:a4f404326ee0 | 6 | |
dacamposol | 0:a4f404326ee0 | 7 | DigitalInOut dht(pin_name); |
dacamposol | 0:a4f404326ee0 | 8 | dht.output(); |
dacamposol | 0:a4f404326ee0 | 9 | dht.write(1); |
dacamposol | 2:8c7fa818f329 | 10 | thread_sleep_for(2); |
dacamposol | 0:a4f404326ee0 | 11 | } |
dacamposol | 0:a4f404326ee0 | 12 | |
dacamposol | 0:a4f404326ee0 | 13 | short DHT22::shortFromBits(bool bits[]) |
dacamposol | 0:a4f404326ee0 | 14 | { |
dacamposol | 0:a4f404326ee0 | 15 | short result = 0; |
dacamposol | 0:a4f404326ee0 | 16 | for (int i = 0; i<8; i++) { |
dacamposol | 0:a4f404326ee0 | 17 | result += bits[i]*(1 << (7-i)); |
dacamposol | 0:a4f404326ee0 | 18 | } |
dacamposol | 0:a4f404326ee0 | 19 | return result; |
dacamposol | 0:a4f404326ee0 | 20 | } |
dacamposol | 0:a4f404326ee0 | 21 | |
dacamposol | 0:a4f404326ee0 | 22 | // Implementation for reading a DHT22 according to the datasheet in |
dacamposol | 0:a4f404326ee0 | 23 | // https://www.sparkfun.com/datasheets/Sensors/Temperature/DHT22.pdf |
dacamposol | 0:a4f404326ee0 | 24 | int DHT22::read() |
dacamposol | 0:a4f404326ee0 | 25 | { |
dacamposol | 0:a4f404326ee0 | 26 | Timer period; |
dacamposol | 0:a4f404326ee0 | 27 | |
dacamposol | 0:a4f404326ee0 | 28 | DigitalInOut dht(pin_name); |
dacamposol | 0:a4f404326ee0 | 29 | |
dacamposol | 0:a4f404326ee0 | 30 | // First, we send a low signal for 1ms to the sensor |
dacamposol | 0:a4f404326ee0 | 31 | dht.output(); |
dacamposol | 0:a4f404326ee0 | 32 | dht.write(0); |
dacamposol | 0:a4f404326ee0 | 33 | thread_sleep_for(2); |
dacamposol | 0:a4f404326ee0 | 34 | |
dacamposol | 0:a4f404326ee0 | 35 | // Now, we pull-up the voltage and wait for the MCU answer |
dacamposol | 0:a4f404326ee0 | 36 | dht.write(1); |
dacamposol | 0:a4f404326ee0 | 37 | dht.input(); |
dacamposol | 0:a4f404326ee0 | 38 | // According to the documentation, the DHT will take between 20-40us to answer, so we just wait the minimum time |
dacamposol | 0:a4f404326ee0 | 39 | // Also, if the sensor doesn't change its status from 1, then it's broken. |
dacamposol | 0:a4f404326ee0 | 40 | period.start(); |
dacamposol | 0:a4f404326ee0 | 41 | while (dht) { |
dacamposol | 0:a4f404326ee0 | 42 | if (period.read() > 1) { |
dacamposol | 0:a4f404326ee0 | 43 | return -1; |
dacamposol | 0:a4f404326ee0 | 44 | } |
dacamposol | 0:a4f404326ee0 | 45 | } |
dacamposol | 0:a4f404326ee0 | 46 | period.stop(); |
dacamposol | 0:a4f404326ee0 | 47 | |
dacamposol | 0:a4f404326ee0 | 48 | // Now the DHT has set to zero, it shall last 80us and then be another 80us in up |
dacamposol | 0:a4f404326ee0 | 49 | wait_us(80); |
dacamposol | 0:a4f404326ee0 | 50 | wait_us(80); |
dacamposol | 0:a4f404326ee0 | 51 | |
dacamposol | 0:a4f404326ee0 | 52 | // Now it starts the data transmision, we expect first 50us before the first bit |
dacamposol | 0:a4f404326ee0 | 53 | // We expect 5 packets of 8 bits: |
dacamposol | 0:a4f404326ee0 | 54 | // - Integral RH Data |
dacamposol | 0:a4f404326ee0 | 55 | // - Decimal RH Data |
dacamposol | 0:a4f404326ee0 | 56 | // - Integral Temp Data |
dacamposol | 0:a4f404326ee0 | 57 | // - Decimal Temp Data |
dacamposol | 0:a4f404326ee0 | 58 | // - Checksum |
dacamposol | 0:a4f404326ee0 | 59 | bool packets[5][8]; |
dacamposol | 0:a4f404326ee0 | 60 | for (int i = 0; i < 5; i++) { |
dacamposol | 0:a4f404326ee0 | 61 | for (int j = 0; j < 8; j++) { |
dacamposol | 0:a4f404326ee0 | 62 | // We wait the start of the bit with wait just in case we have been carrying error |
dacamposol | 0:a4f404326ee0 | 63 | // wait_us(50); |
dacamposol | 0:a4f404326ee0 | 64 | while(!dht); // Low signal of 50us. Each bit has to start with it. |
dacamposol | 0:a4f404326ee0 | 65 | period.reset(); |
dacamposol | 0:a4f404326ee0 | 66 | period.start(); |
dacamposol | 0:a4f404326ee0 | 67 | while(dht); |
dacamposol | 0:a4f404326ee0 | 68 | period.stop(); |
dacamposol | 0:a4f404326ee0 | 69 | |
dacamposol | 0:a4f404326ee0 | 70 | // According to the documentation, it's 26us vs 70us |
dacamposol | 1:3385bd532812 | 71 | packets[i][j] = period.read_us() > 60; |
dacamposol | 0:a4f404326ee0 | 72 | } |
dacamposol | 0:a4f404326ee0 | 73 | } |
dacamposol | 0:a4f404326ee0 | 74 | |
dacamposol | 0:a4f404326ee0 | 75 | // Now we stop the sensor |
dacamposol | 0:a4f404326ee0 | 76 | dht.output(); |
dacamposol | 0:a4f404326ee0 | 77 | dht.write(1); |
dacamposol | 0:a4f404326ee0 | 78 | |
dacamposol | 0:a4f404326ee0 | 79 | // And we treat the received data |
dacamposol | 0:a4f404326ee0 | 80 | |
dacamposol | 0:a4f404326ee0 | 81 | // First, we treat the MSB (bit 0) of the temp, if it's 1, then it's negative. |
dacamposol | 0:a4f404326ee0 | 82 | // The real value for the temperature is stored in the bits 1 ~ 16 |
dacamposol | 0:a4f404326ee0 | 83 | int MSB = 1; |
dacamposol | 0:a4f404326ee0 | 84 | if (packets[2][0]) |
dacamposol | 0:a4f404326ee0 | 85 | MSB = -1; |
dacamposol | 0:a4f404326ee0 | 86 | packets[2][0] = 0; |
dacamposol | 0:a4f404326ee0 | 87 | |
dacamposol | 0:a4f404326ee0 | 88 | short high_humidity = shortFromBits(packets[0]); |
dacamposol | 0:a4f404326ee0 | 89 | short low_humidity = shortFromBits(packets[1]); |
dacamposol | 0:a4f404326ee0 | 90 | short high_temp = shortFromBits(packets[2]); |
dacamposol | 0:a4f404326ee0 | 91 | short low_temp = shortFromBits(packets[3]); |
dacamposol | 0:a4f404326ee0 | 92 | |
dacamposol | 0:a4f404326ee0 | 93 | // If the values coincide with the checksum, then change the last values of temperature and humidity |
dacamposol | 0:a4f404326ee0 | 94 | // Otherwise, print the problem and exit the method |
dacamposol | 0:a4f404326ee0 | 95 | if ((high_humidity + low_humidity + high_temp + low_temp) % 256 == shortFromBits(packets[4])) { |
dacamposol | 0:a4f404326ee0 | 96 | m_humidity = (high_humidity * 256 + low_humidity) / 10; |
dacamposol | 0:a4f404326ee0 | 97 | m_temperature = MSB * (high_temp * 256 + low_temp) / 10; |
dacamposol | 0:a4f404326ee0 | 98 | } else { |
dacamposol | 0:a4f404326ee0 | 99 | return -1; |
dacamposol | 0:a4f404326ee0 | 100 | } |
dacamposol | 0:a4f404326ee0 | 101 | |
dacamposol | 0:a4f404326ee0 | 102 | return 1; |
dacamposol | 0:a4f404326ee0 | 103 | } |
dacamposol | 0:a4f404326ee0 | 104 | |
dacamposol | 2:8c7fa818f329 | 105 | float DHT22::getTemperature() |
dacamposol | 0:a4f404326ee0 | 106 | { |
dacamposol | 0:a4f404326ee0 | 107 | return m_temperature; |
dacamposol | 0:a4f404326ee0 | 108 | } |
dacamposol | 0:a4f404326ee0 | 109 | |
dacamposol | 2:8c7fa818f329 | 110 | float DHT22::getHumidity() |
dacamposol | 0:a4f404326ee0 | 111 | { |
dacamposol | 0:a4f404326ee0 | 112 | return m_humidity; |
dacamposol | 0:a4f404326ee0 | 113 | } |