A simple library for reading data from a DHT22 sensor

Fork of lib_dht22 by Simon Cooksey

Committer:
co657_jnp8
Date:
Wed Nov 02 16:29:53 2016 +0000
Revision:
2:02cbaab7c6cd
Parent:
0:257ba13e416e
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_jnp8 2:02cbaab7c6cd 22 //__disable_irq ();
co657_sjc80 0:257ba13e416e 23 dht22_s.input();
co657_sjc80 0:257ba13e416e 24
co657_sjc80 0:257ba13e416e 25 // Timing is done by increasing this number, as the Timer class appears to
co657_sjc80 0:257ba13e416e 26 // be super slow.
co657_sjc80 0:257ba13e416e 27 int time = 0;
co657_sjc80 0:257ba13e416e 28 do {
co657_sjc80 0:257ba13e416e 29 wait_us(2);
co657_sjc80 0:257ba13e416e 30 time+=2;
co657_sjc80 0:257ba13e416e 31 } while(dht22_s != (int)type);
co657_sjc80 0:257ba13e416e 32
co657_sjc80 0:257ba13e416e 33 // wait for the edge to transition properly
co657_sjc80 0:257ba13e416e 34 wait_us(2);
co657_jnp8 2:02cbaab7c6cd 35 //__enable_irq ();
co657_sjc80 0:257ba13e416e 36 return time;
co657_sjc80 0:257ba13e416e 37 }
co657_sjc80 0:257ba13e416e 38
co657_sjc80 0:257ba13e416e 39 /*
co657_sjc80 0:257ba13e416e 40 * Send a start bit to the DHT22
co657_sjc80 0:257ba13e416e 41 */
co657_sjc80 0:257ba13e416e 42 void DHT22::send_start()
co657_sjc80 0:257ba13e416e 43 {
co657_jnp8 2:02cbaab7c6cd 44 //__disable_irq ();
co657_sjc80 0:257ba13e416e 45 dht22_s.output();
co657_sjc80 0:257ba13e416e 46 dht22_s = 0;
co657_sjc80 0:257ba13e416e 47 wait_us(DHT22_START_BIT_TIME);
co657_sjc80 0:257ba13e416e 48 dht22_s = 1;
co657_sjc80 0:257ba13e416e 49 dht22_s.input();
co657_jnp8 2:02cbaab7c6cd 50 //__enable_irq ();
co657_sjc80 0:257ba13e416e 51 }
co657_sjc80 0:257ba13e416e 52
co657_sjc80 0:257ba13e416e 53 /*
co657_sjc80 0:257ba13e416e 54 * Wait for the DHT22 to send the start bit ACK, after this we can read data.
co657_sjc80 0:257ba13e416e 55 */
co657_sjc80 0:257ba13e416e 56 void DHT22::await_start_response()
co657_sjc80 0:257ba13e416e 57 {
co657_sjc80 0:257ba13e416e 58 dht22_s.input();
co657_sjc80 0:257ba13e416e 59 wait_for_edge(EDGE_TYPE_FALLING); // 20-40 uS
co657_sjc80 0:257ba13e416e 60 wait_for_edge(EDGE_TYPE_RISING); // 80 uS
co657_sjc80 0:257ba13e416e 61 wait_for_edge(EDGE_TYPE_FALLING); // 80 uS
co657_sjc80 0:257ba13e416e 62 }
co657_sjc80 0:257ba13e416e 63
co657_sjc80 0:257ba13e416e 64 /*
co657_sjc80 0:257ba13e416e 65 * Reads 16 bits of data from the DHT22
co657_sjc80 0:257ba13e416e 66 *
co657_sjc80 0:257ba13e416e 67 * Returns: the signed value read. dht22_t.
co657_sjc80 0:257ba13e416e 68 * NB. the DHT22 uses a sign bit to do -ve and positive, but this is
co657_sjc80 0:257ba13e416e 69 * incompatible with signed numbers in C, so the conversion is done here.
co657_sjc80 0:257ba13e416e 70 */
co657_sjc80 0:257ba13e416e 71 int16_t DHT22::read_word()
co657_sjc80 0:257ba13e416e 72 {
co657_sjc80 0:257ba13e416e 73 dht22_s.input();
co657_sjc80 0:257ba13e416e 74 int32_t duration;
co657_sjc80 0:257ba13e416e 75 int16_t word = 0x00;
co657_sjc80 0:257ba13e416e 76 for(char bit = 0; bit < 16; bit++)
co657_sjc80 0:257ba13e416e 77 {
co657_sjc80 0:257ba13e416e 78 /* /-----------\
co657_sjc80 0:257ba13e416e 79 * / duration \ 50us
co657_sjc80 0:257ba13e416e 80 * ----/ \-------
co657_sjc80 0:257ba13e416e 81 */
co657_sjc80 0:257ba13e416e 82 wait_for_edge(EDGE_TYPE_RISING);
co657_sjc80 0:257ba13e416e 83 duration = wait_for_edge(EDGE_TYPE_FALLING);
co657_sjc80 0:257ba13e416e 84
co657_sjc80 0:257ba13e416e 85 if(duration > DHT22_SIGNAL_HIGH_LOW_BOUNDARY)
co657_sjc80 0:257ba13e416e 86 {
co657_sjc80 0:257ba13e416e 87 word |= (1 << 15-bit);
co657_sjc80 0:257ba13e416e 88 }
co657_sjc80 0:257ba13e416e 89 else
co657_sjc80 0:257ba13e416e 90 {
co657_sjc80 0:257ba13e416e 91 word |= (0 << 15-bit);
co657_sjc80 0:257ba13e416e 92 }
co657_sjc80 0:257ba13e416e 93 }
co657_sjc80 0:257ba13e416e 94 if(word & 0x8000)
co657_sjc80 0:257ba13e416e 95 return 1 - (word ^ 0x8000);
co657_sjc80 0:257ba13e416e 96 return word;
co657_sjc80 0:257ba13e416e 97 }
co657_sjc80 0:257ba13e416e 98
co657_sjc80 0:257ba13e416e 99 /*
co657_sjc80 0:257ba13e416e 100 * Reads 8 bits of data from the DHT22
co657_sjc80 0:257ba13e416e 101 *
co657_sjc80 0:257ba13e416e 102 * Returns: the unsigned checksum value read. dht22_t.
co657_sjc80 0:257ba13e416e 103 */
co657_sjc80 0:257ba13e416e 104 uint8_t DHT22::read_checksum()
co657_sjc80 0:257ba13e416e 105 {
co657_sjc80 0:257ba13e416e 106 dht22_s.input();
co657_sjc80 0:257ba13e416e 107 uint32_t duration;
co657_sjc80 0:257ba13e416e 108 uint8_t word;
co657_sjc80 0:257ba13e416e 109 for(char bit = 0; bit < sizeof(uint8_t)*8; bit++)
co657_sjc80 0:257ba13e416e 110 {
co657_sjc80 0:257ba13e416e 111 /* /-----------\
co657_sjc80 0:257ba13e416e 112 * / duration \ 50us
co657_sjc80 0:257ba13e416e 113 * ----/ \-------
co657_sjc80 0:257ba13e416e 114 */
co657_sjc80 0:257ba13e416e 115 wait_for_edge(EDGE_TYPE_RISING);
co657_sjc80 0:257ba13e416e 116 duration = wait_for_edge(EDGE_TYPE_FALLING);
co657_sjc80 0:257ba13e416e 117
co657_sjc80 0:257ba13e416e 118 if(duration > DHT22_SIGNAL_HIGH_LOW_BOUNDARY)
co657_sjc80 0:257ba13e416e 119 {
co657_sjc80 0:257ba13e416e 120 word |= (1 << 7-bit);
co657_sjc80 0:257ba13e416e 121 }
co657_sjc80 0:257ba13e416e 122 else
co657_sjc80 0:257ba13e416e 123 {
co657_sjc80 0:257ba13e416e 124 word |= (0 << 7-bit);
co657_sjc80 0:257ba13e416e 125 }
co657_sjc80 0:257ba13e416e 126 }
co657_sjc80 0:257ba13e416e 127 return word;
co657_sjc80 0:257ba13e416e 128 }
co657_sjc80 0:257ba13e416e 129
co657_sjc80 0:257ba13e416e 130 /*
co657_sjc80 0:257ba13e416e 131 * Reads a packet of DHT22 data.
co657_sjc80 0:257ba13e416e 132 *
co657_sjc80 0:257ba13e416e 133 * Param data: the packet to fill.
co657_sjc80 0:257ba13e416e 134 */
co657_sjc80 0:257ba13e416e 135 void DHT22::read(DHT22_data_t * data)
co657_sjc80 0:257ba13e416e 136 {
co657_sjc80 0:257ba13e416e 137 // Send start bits
co657_sjc80 0:257ba13e416e 138 send_start();
co657_sjc80 0:257ba13e416e 139
co657_sjc80 0:257ba13e416e 140 // Wait for device to respond
co657_sjc80 0:257ba13e416e 141 await_start_response();
co657_sjc80 0:257ba13e416e 142
co657_sjc80 0:257ba13e416e 143 // Read data bits (16+16)
co657_sjc80 0:257ba13e416e 144 int16_t humidity = read_word();
co657_sjc80 0:257ba13e416e 145 int16_t temp = read_word();
co657_sjc80 0:257ba13e416e 146
co657_sjc80 0:257ba13e416e 147 // Read checksum (8)
co657_sjc80 0:257ba13e416e 148 uint8_t checksum = read_checksum();
co657_sjc80 0:257ba13e416e 149
co657_sjc80 0:257ba13e416e 150 data->humidity = (humidity);
co657_sjc80 0:257ba13e416e 151 data->temp = (temp);
co657_sjc80 0:257ba13e416e 152 data->checksum = checksum;
co657_sjc80 0:257ba13e416e 153 }