DHT22 library, based on Simon Cooksey's. Improved with some error checking and more rigid timing (interrupts off).

Fork of lib_dht22 by Jodie Perry

Committer:
co657_sjc80
Date:
Mon Jan 04 14:45:33 2016 +0000
Revision:
0:257ba13e416e
Child:
2:02cbaab7c6cd
Initial commit;

Who changed what in which revision?

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