Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: Mytemperature_Motion
dht22.cpp@0:e50b1c66ec57, 2019-04-21 (annotated)
- Committer:
- sharifdeens
- Date:
- Sun Apr 21 03:29:29 2019 +0000
- Revision:
- 0:e50b1c66ec57
n/a
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
sharifdeens | 0:e50b1c66ec57 | 1 | /* |
sharifdeens | 0:e50b1c66ec57 | 2 | * (C) The University of Kent and Simon Cooksey 2015. |
sharifdeens | 0:e50b1c66ec57 | 3 | */ |
sharifdeens | 0:e50b1c66ec57 | 4 | |
sharifdeens | 0:e50b1c66ec57 | 5 | #include "mbed.h" |
sharifdeens | 0:e50b1c66ec57 | 6 | #include <inttypes.h> |
sharifdeens | 0:e50b1c66ec57 | 7 | |
sharifdeens | 0:e50b1c66ec57 | 8 | #include "dht22.h" |
sharifdeens | 0:e50b1c66ec57 | 9 | |
sharifdeens | 0:e50b1c66ec57 | 10 | /* |
sharifdeens | 0:e50b1c66ec57 | 11 | * The DHT22 uses a 1 wire interface, sending 1's and 0s by varying the length |
sharifdeens | 0:e50b1c66ec57 | 12 | * of the HIGH time on the signal pin. |
sharifdeens | 0:e50b1c66ec57 | 13 | */ |
sharifdeens | 0:e50b1c66ec57 | 14 | |
sharifdeens | 0:e50b1c66ec57 | 15 | /* |
sharifdeens | 0:e50b1c66ec57 | 16 | * Wait for a rising or falling edge on the sense pin. |
sharifdeens | 0:e50b1c66ec57 | 17 | * |
sharifdeens | 0:e50b1c66ec57 | 18 | * Returns: the number of uS elapsed before the transition |
sharifdeens | 0:e50b1c66ec57 | 19 | */ |
sharifdeens | 0:e50b1c66ec57 | 20 | int DHT22::wait_for_edge(edge_type_t type) |
sharifdeens | 0:e50b1c66ec57 | 21 | { |
sharifdeens | 0:e50b1c66ec57 | 22 | dht22_s.input(); |
sharifdeens | 0:e50b1c66ec57 | 23 | |
sharifdeens | 0:e50b1c66ec57 | 24 | // Timing is done by increasing this number, as the Timer class appears to |
sharifdeens | 0:e50b1c66ec57 | 25 | // be super slow. |
sharifdeens | 0:e50b1c66ec57 | 26 | int time = 0; |
sharifdeens | 0:e50b1c66ec57 | 27 | do { |
sharifdeens | 0:e50b1c66ec57 | 28 | wait_us(2); |
sharifdeens | 0:e50b1c66ec57 | 29 | time+=2; |
sharifdeens | 0:e50b1c66ec57 | 30 | } while(dht22_s != (int)type); |
sharifdeens | 0:e50b1c66ec57 | 31 | |
sharifdeens | 0:e50b1c66ec57 | 32 | // wait for the edge to transition properly |
sharifdeens | 0:e50b1c66ec57 | 33 | wait_us(2); |
sharifdeens | 0:e50b1c66ec57 | 34 | return time; |
sharifdeens | 0:e50b1c66ec57 | 35 | } |
sharifdeens | 0:e50b1c66ec57 | 36 | |
sharifdeens | 0:e50b1c66ec57 | 37 | /* |
sharifdeens | 0:e50b1c66ec57 | 38 | * Send a start bit to the DHT22 |
sharifdeens | 0:e50b1c66ec57 | 39 | */ |
sharifdeens | 0:e50b1c66ec57 | 40 | void DHT22::send_start() |
sharifdeens | 0:e50b1c66ec57 | 41 | { |
sharifdeens | 0:e50b1c66ec57 | 42 | dht22_s.output(); |
sharifdeens | 0:e50b1c66ec57 | 43 | dht22_s = 0; |
sharifdeens | 0:e50b1c66ec57 | 44 | wait_us(DHT22_START_BIT_TIME); |
sharifdeens | 0:e50b1c66ec57 | 45 | dht22_s = 1; |
sharifdeens | 0:e50b1c66ec57 | 46 | dht22_s.input(); |
sharifdeens | 0:e50b1c66ec57 | 47 | } |
sharifdeens | 0:e50b1c66ec57 | 48 | |
sharifdeens | 0:e50b1c66ec57 | 49 | /* |
sharifdeens | 0:e50b1c66ec57 | 50 | * Wait for the DHT22 to send the start bit ACK, after this we can read data. |
sharifdeens | 0:e50b1c66ec57 | 51 | */ |
sharifdeens | 0:e50b1c66ec57 | 52 | void DHT22::await_start_response() |
sharifdeens | 0:e50b1c66ec57 | 53 | { |
sharifdeens | 0:e50b1c66ec57 | 54 | dht22_s.input(); |
sharifdeens | 0:e50b1c66ec57 | 55 | wait_for_edge(EDGE_TYPE_FALLING); // 20-40 uS |
sharifdeens | 0:e50b1c66ec57 | 56 | wait_for_edge(EDGE_TYPE_RISING); // 80 uS |
sharifdeens | 0:e50b1c66ec57 | 57 | wait_for_edge(EDGE_TYPE_FALLING); // 80 uS |
sharifdeens | 0:e50b1c66ec57 | 58 | } |
sharifdeens | 0:e50b1c66ec57 | 59 | |
sharifdeens | 0:e50b1c66ec57 | 60 | /* |
sharifdeens | 0:e50b1c66ec57 | 61 | * Reads 16 bits of data from the DHT22 |
sharifdeens | 0:e50b1c66ec57 | 62 | * |
sharifdeens | 0:e50b1c66ec57 | 63 | * Returns: the signed value read. dht22_t. |
sharifdeens | 0:e50b1c66ec57 | 64 | * NB. the DHT22 uses a sign bit to do -ve and positive, but this is |
sharifdeens | 0:e50b1c66ec57 | 65 | * incompatible with signed numbers in C, so the conversion is done here. |
sharifdeens | 0:e50b1c66ec57 | 66 | */ |
sharifdeens | 0:e50b1c66ec57 | 67 | int16_t DHT22::read_word() |
sharifdeens | 0:e50b1c66ec57 | 68 | { |
sharifdeens | 0:e50b1c66ec57 | 69 | dht22_s.input(); |
sharifdeens | 0:e50b1c66ec57 | 70 | int32_t duration; |
sharifdeens | 0:e50b1c66ec57 | 71 | int16_t word = 0x00; |
sharifdeens | 0:e50b1c66ec57 | 72 | for(char bit = 0; bit < 16; bit++) |
sharifdeens | 0:e50b1c66ec57 | 73 | { |
sharifdeens | 0:e50b1c66ec57 | 74 | /* /-----------\ |
sharifdeens | 0:e50b1c66ec57 | 75 | * / duration \ 50us |
sharifdeens | 0:e50b1c66ec57 | 76 | * ----/ \------- |
sharifdeens | 0:e50b1c66ec57 | 77 | */ |
sharifdeens | 0:e50b1c66ec57 | 78 | wait_for_edge(EDGE_TYPE_RISING); |
sharifdeens | 0:e50b1c66ec57 | 79 | duration = wait_for_edge(EDGE_TYPE_FALLING); |
sharifdeens | 0:e50b1c66ec57 | 80 | |
sharifdeens | 0:e50b1c66ec57 | 81 | if(duration > DHT22_SIGNAL_HIGH_LOW_BOUNDARY) |
sharifdeens | 0:e50b1c66ec57 | 82 | { |
sharifdeens | 0:e50b1c66ec57 | 83 | word |= (1 << 15-bit); |
sharifdeens | 0:e50b1c66ec57 | 84 | } |
sharifdeens | 0:e50b1c66ec57 | 85 | else |
sharifdeens | 0:e50b1c66ec57 | 86 | { |
sharifdeens | 0:e50b1c66ec57 | 87 | word |= (0 << 15-bit); |
sharifdeens | 0:e50b1c66ec57 | 88 | } |
sharifdeens | 0:e50b1c66ec57 | 89 | } |
sharifdeens | 0:e50b1c66ec57 | 90 | if(word & 0x8000) |
sharifdeens | 0:e50b1c66ec57 | 91 | return 1 - (word ^ 0x8000); |
sharifdeens | 0:e50b1c66ec57 | 92 | return word; |
sharifdeens | 0:e50b1c66ec57 | 93 | } |
sharifdeens | 0:e50b1c66ec57 | 94 | |
sharifdeens | 0:e50b1c66ec57 | 95 | /* |
sharifdeens | 0:e50b1c66ec57 | 96 | * Reads 8 bits of data from the DHT22 |
sharifdeens | 0:e50b1c66ec57 | 97 | * |
sharifdeens | 0:e50b1c66ec57 | 98 | * Returns: the unsigned checksum value read. dht22_t. |
sharifdeens | 0:e50b1c66ec57 | 99 | */ |
sharifdeens | 0:e50b1c66ec57 | 100 | uint8_t DHT22::read_checksum() |
sharifdeens | 0:e50b1c66ec57 | 101 | { |
sharifdeens | 0:e50b1c66ec57 | 102 | dht22_s.input(); |
sharifdeens | 0:e50b1c66ec57 | 103 | uint32_t duration; |
sharifdeens | 0:e50b1c66ec57 | 104 | uint8_t word; |
sharifdeens | 0:e50b1c66ec57 | 105 | for(char bit = 0; bit < sizeof(uint8_t)*8; bit++) |
sharifdeens | 0:e50b1c66ec57 | 106 | { |
sharifdeens | 0:e50b1c66ec57 | 107 | /* /-----------\ |
sharifdeens | 0:e50b1c66ec57 | 108 | * / duration \ 50us |
sharifdeens | 0:e50b1c66ec57 | 109 | * ----/ \------- |
sharifdeens | 0:e50b1c66ec57 | 110 | */ |
sharifdeens | 0:e50b1c66ec57 | 111 | wait_for_edge(EDGE_TYPE_RISING); |
sharifdeens | 0:e50b1c66ec57 | 112 | duration = wait_for_edge(EDGE_TYPE_FALLING); |
sharifdeens | 0:e50b1c66ec57 | 113 | |
sharifdeens | 0:e50b1c66ec57 | 114 | if(duration > DHT22_SIGNAL_HIGH_LOW_BOUNDARY) |
sharifdeens | 0:e50b1c66ec57 | 115 | { |
sharifdeens | 0:e50b1c66ec57 | 116 | word |= (1 << 7-bit); |
sharifdeens | 0:e50b1c66ec57 | 117 | } |
sharifdeens | 0:e50b1c66ec57 | 118 | else |
sharifdeens | 0:e50b1c66ec57 | 119 | { |
sharifdeens | 0:e50b1c66ec57 | 120 | word |= (0 << 7-bit); |
sharifdeens | 0:e50b1c66ec57 | 121 | } |
sharifdeens | 0:e50b1c66ec57 | 122 | } |
sharifdeens | 0:e50b1c66ec57 | 123 | return word; |
sharifdeens | 0:e50b1c66ec57 | 124 | } |
sharifdeens | 0:e50b1c66ec57 | 125 | |
sharifdeens | 0:e50b1c66ec57 | 126 | /* |
sharifdeens | 0:e50b1c66ec57 | 127 | * Reads a packet of DHT22 data. |
sharifdeens | 0:e50b1c66ec57 | 128 | * |
sharifdeens | 0:e50b1c66ec57 | 129 | * Param data: the packet to fill. |
sharifdeens | 0:e50b1c66ec57 | 130 | */ |
sharifdeens | 0:e50b1c66ec57 | 131 | void DHT22::read(DHT22_data_t * data) |
sharifdeens | 0:e50b1c66ec57 | 132 | { |
sharifdeens | 0:e50b1c66ec57 | 133 | // Send start bits |
sharifdeens | 0:e50b1c66ec57 | 134 | send_start(); |
sharifdeens | 0:e50b1c66ec57 | 135 | |
sharifdeens | 0:e50b1c66ec57 | 136 | // Wait for device to respond |
sharifdeens | 0:e50b1c66ec57 | 137 | await_start_response(); |
sharifdeens | 0:e50b1c66ec57 | 138 | |
sharifdeens | 0:e50b1c66ec57 | 139 | // Read data bits (16+16) |
sharifdeens | 0:e50b1c66ec57 | 140 | int16_t humidity = read_word(); |
sharifdeens | 0:e50b1c66ec57 | 141 | int16_t temp = read_word(); |
sharifdeens | 0:e50b1c66ec57 | 142 | |
sharifdeens | 0:e50b1c66ec57 | 143 | // Read checksum (8) |
sharifdeens | 0:e50b1c66ec57 | 144 | uint8_t checksum = read_checksum(); |
sharifdeens | 0:e50b1c66ec57 | 145 | |
sharifdeens | 0:e50b1c66ec57 | 146 | data->humidity = (humidity); |
sharifdeens | 0:e50b1c66ec57 | 147 | data->temp = (temp); |
sharifdeens | 0:e50b1c66ec57 | 148 | data->checksum = checksum; |
sharifdeens | 0:e50b1c66ec57 | 149 | } |