A library for the use of DHT11, a temperature and humidity sensor

Dependents:   HTTP_SERVER2 lightweight-weather-station

Committer:
s_inoue_mbed
Date:
Thu Sep 11 13:45:00 2014 +0000
Revision:
9:056d1e9b428c
Parent:
8:160047ca45bf
Child:
10:f0d789f49df7
Bug fix

Who changed what in which revision?

UserRevisionLine numberNew contents of line
s_inoue_mbed 4:48798b126d93 1 /*
s_inoue_mbed 4:48798b126d93 2 * Library for the use of the DHT11, a temperature and humidity sensor
s_inoue_mbed 4:48798b126d93 3 * Shigenori Inoue, September 10, 2014
s_inoue_mbed 0:4d4c5ea17d86 4 */
s_inoue_mbed 0:4d4c5ea17d86 5
s_inoue_mbed 0:4d4c5ea17d86 6 #include "DHT11.h"
s_inoue_mbed 0:4d4c5ea17d86 7
s_inoue_mbed 0:4d4c5ea17d86 8 // Constructor
s_inoue_mbed 0:4d4c5ea17d86 9 DHT11::DHT11(PinName pin) : io(pin, PIN_INPUT, OpenDrain, 1), io_irq(pin)
s_inoue_mbed 0:4d4c5ea17d86 10 {
s_inoue_mbed 0:4d4c5ea17d86 11 io_irq.rise(this, &DHT11::pos_edge);
s_inoue_mbed 0:4d4c5ea17d86 12 io_irq.fall(this, &DHT11::neg_edge);
s_inoue_mbed 0:4d4c5ea17d86 13 io_irq.disable_irq();
s_inoue_mbed 9:056d1e9b428c 14 t.start();
s_inoue_mbed 6:257e2ab66d0f 15 first_time = true;
s_inoue_mbed 0:4d4c5ea17d86 16 }
s_inoue_mbed 0:4d4c5ea17d86 17
s_inoue_mbed 0:4d4c5ea17d86 18 // Destructor
s_inoue_mbed 0:4d4c5ea17d86 19 DHT11::~DHT11(void) {}
s_inoue_mbed 0:4d4c5ea17d86 20
s_inoue_mbed 9:056d1e9b428c 21 // Constants
s_inoue_mbed 9:056d1e9b428c 22 const int DHT11::t_tol_start = 2;
s_inoue_mbed 9:056d1e9b428c 23 const int DHT11::t_tol_pulse = 10;
s_inoue_mbed 9:056d1e9b428c 24
s_inoue_mbed 6:257e2ab66d0f 25 // Reading the data bits from the DHT11
s_inoue_mbed 9:056d1e9b428c 26 int DHT11::readData(void)
s_inoue_mbed 0:4d4c5ea17d86 27 {
s_inoue_mbed 9:056d1e9b428c 28 // Checking the measurement frequency
s_inoue_mbed 9:056d1e9b428c 29 if (t.read_ms() < 2000 && first_time == false) {
s_inoue_mbed 9:056d1e9b428c 30 t.reset();
s_inoue_mbed 9:056d1e9b428c 31 return READ_TOO_OFTEN;
s_inoue_mbed 9:056d1e9b428c 32 }
s_inoue_mbed 9:056d1e9b428c 33
s_inoue_mbed 0:4d4c5ea17d86 34 // Initialize
s_inoue_mbed 6:257e2ab66d0f 35 init();
s_inoue_mbed 0:4d4c5ea17d86 36
s_inoue_mbed 0:4d4c5ea17d86 37 // Checking the data bus
s_inoue_mbed 0:4d4c5ea17d86 38 if (io == 0) {
s_inoue_mbed 9:056d1e9b428c 39 t.reset();
s_inoue_mbed 0:4d4c5ea17d86 40 return BUS_BUSY;
s_inoue_mbed 0:4d4c5ea17d86 41 }
s_inoue_mbed 0:4d4c5ea17d86 42
s_inoue_mbed 9:056d1e9b428c 43 // Sending start signal, low signal for around 10 ms
s_inoue_mbed 0:4d4c5ea17d86 44 t.reset();
s_inoue_mbed 0:4d4c5ea17d86 45 do {
s_inoue_mbed 0:4d4c5ea17d86 46 io = 0;
s_inoue_mbed 9:056d1e9b428c 47 } while (t.read_ms() < 20 + t_tol_start);
s_inoue_mbed 7:50f5c8efd967 48 io = 1;
s_inoue_mbed 0:4d4c5ea17d86 49
s_inoue_mbed 0:4d4c5ea17d86 50 // Waiting for the start of the response signal
s_inoue_mbed 0:4d4c5ea17d86 51 t.reset();
s_inoue_mbed 0:4d4c5ea17d86 52 do {
s_inoue_mbed 0:4d4c5ea17d86 53 if (t.read_us() > 100) {
s_inoue_mbed 9:056d1e9b428c 54 t.reset();
s_inoue_mbed 0:4d4c5ea17d86 55 return NOT_PRESENT;
s_inoue_mbed 0:4d4c5ea17d86 56 }
s_inoue_mbed 0:4d4c5ea17d86 57 } while (io == 1);
s_inoue_mbed 0:4d4c5ea17d86 58
s_inoue_mbed 0:4d4c5ea17d86 59 // Wainting for the start of the ready signal
s_inoue_mbed 0:4d4c5ea17d86 60 t.reset();
s_inoue_mbed 0:4d4c5ea17d86 61 do {
s_inoue_mbed 0:4d4c5ea17d86 62 if (t.read_us() > 100) {
s_inoue_mbed 9:056d1e9b428c 63 t.reset();
s_inoue_mbed 0:4d4c5ea17d86 64 return NOT_READY;
s_inoue_mbed 0:4d4c5ea17d86 65 }
s_inoue_mbed 0:4d4c5ea17d86 66 } while (io == 0);
s_inoue_mbed 0:4d4c5ea17d86 67
s_inoue_mbed 0:4d4c5ea17d86 68 // Wainting for the end of the ready signal
s_inoue_mbed 0:4d4c5ea17d86 69 t.reset();
s_inoue_mbed 9:056d1e9b428c 70 do {
s_inoue_mbed 9:056d1e9b428c 71 if (t.read_us() > 100) {
s_inoue_mbed 9:056d1e9b428c 72 t.reset();
s_inoue_mbed 9:056d1e9b428c 73 return WATCHDOG_ERR;
s_inoue_mbed 9:056d1e9b428c 74 }
s_inoue_mbed 9:056d1e9b428c 75 } while (io == 1);
s_inoue_mbed 0:4d4c5ea17d86 76
s_inoue_mbed 0:4d4c5ea17d86 77 // Starting the pulse width sensing
s_inoue_mbed 9:056d1e9b428c 78 // by the use of interruptions
s_inoue_mbed 0:4d4c5ea17d86 79 io_irq.enable_irq();
s_inoue_mbed 0:4d4c5ea17d86 80
s_inoue_mbed 0:4d4c5ea17d86 81 do {
s_inoue_mbed 0:4d4c5ea17d86 82 wait_us(100);
s_inoue_mbed 0:4d4c5ea17d86 83 if (wdt > 50) {
s_inoue_mbed 9:056d1e9b428c 84 t.reset();
s_inoue_mbed 0:4d4c5ea17d86 85 return WATCHDOG_ERR;
s_inoue_mbed 0:4d4c5ea17d86 86 }
s_inoue_mbed 0:4d4c5ea17d86 87 wdt++;
s_inoue_mbed 0:4d4c5ea17d86 88 } while (eod == false);
s_inoue_mbed 0:4d4c5ea17d86 89
s_inoue_mbed 0:4d4c5ea17d86 90 // Calculating the check sum
s_inoue_mbed 0:4d4c5ea17d86 91 chksum = ((data & 0xff00000000) >> 32)
s_inoue_mbed 0:4d4c5ea17d86 92 + ((data & 0x00ff000000) >> 24)
s_inoue_mbed 0:4d4c5ea17d86 93 + ((data & 0x0000ff0000) >> 16)
s_inoue_mbed 0:4d4c5ea17d86 94 + ((data & 0x000000ff00) >> 8);
s_inoue_mbed 9:056d1e9b428c 95
s_inoue_mbed 0:4d4c5ea17d86 96 if (chksum != (data & 0x00000000ff)) {
s_inoue_mbed 9:056d1e9b428c 97 t.reset();
s_inoue_mbed 0:4d4c5ea17d86 98 return CHKSUM_ERR;
s_inoue_mbed 0:4d4c5ea17d86 99 } else {
s_inoue_mbed 0:4d4c5ea17d86 100 t.reset();
s_inoue_mbed 0:4d4c5ea17d86 101 first_time = false;
s_inoue_mbed 0:4d4c5ea17d86 102 return OK;
s_inoue_mbed 0:4d4c5ea17d86 103 }
s_inoue_mbed 0:4d4c5ea17d86 104 }
s_inoue_mbed 0:4d4c5ea17d86 105
s_inoue_mbed 0:4d4c5ea17d86 106 // Extracting humidity data from the received data
s_inoue_mbed 9:056d1e9b428c 107 int DHT11::readHumidity(void)
s_inoue_mbed 0:4d4c5ea17d86 108 {
s_inoue_mbed 9:056d1e9b428c 109 return (data & 0xff00000000) >> 32;
s_inoue_mbed 0:4d4c5ea17d86 110 }
s_inoue_mbed 0:4d4c5ea17d86 111
s_inoue_mbed 0:4d4c5ea17d86 112 // Extracting temperature data from the received data
s_inoue_mbed 9:056d1e9b428c 113 int DHT11::readTemperature(void)
s_inoue_mbed 0:4d4c5ea17d86 114 {
s_inoue_mbed 9:056d1e9b428c 115 return (data & 0x0000ff0000) >> 16;
s_inoue_mbed 0:4d4c5ea17d86 116 }
s_inoue_mbed 0:4d4c5ea17d86 117
s_inoue_mbed 0:4d4c5ea17d86 118 // Initialization of variables
s_inoue_mbed 0:4d4c5ea17d86 119 void DHT11::init(void)
s_inoue_mbed 0:4d4c5ea17d86 120 {
s_inoue_mbed 0:4d4c5ea17d86 121 t_pulse_us = 0;
s_inoue_mbed 0:4d4c5ea17d86 122 data = 0;
s_inoue_mbed 0:4d4c5ea17d86 123 chksum = 0;
s_inoue_mbed 0:4d4c5ea17d86 124 cnt = 0;
s_inoue_mbed 0:4d4c5ea17d86 125 wdt = 0;
s_inoue_mbed 0:4d4c5ea17d86 126 eod = false;
s_inoue_mbed 9:056d1e9b428c 127 t.reset();
s_inoue_mbed 0:4d4c5ea17d86 128 }
s_inoue_mbed 0:4d4c5ea17d86 129
s_inoue_mbed 0:4d4c5ea17d86 130 void DHT11::pos_edge(void)
s_inoue_mbed 0:4d4c5ea17d86 131 {
s_inoue_mbed 0:4d4c5ea17d86 132 // Disabling the interruptions
s_inoue_mbed 0:4d4c5ea17d86 133 io_irq.disable_irq();
s_inoue_mbed 0:4d4c5ea17d86 134
s_inoue_mbed 0:4d4c5ea17d86 135 // Initializing the Timer
s_inoue_mbed 0:4d4c5ea17d86 136 t.reset();
s_inoue_mbed 0:4d4c5ea17d86 137
s_inoue_mbed 0:4d4c5ea17d86 138 // Enabling the interruptions
s_inoue_mbed 0:4d4c5ea17d86 139 io_irq.enable_irq();
s_inoue_mbed 0:4d4c5ea17d86 140 }
s_inoue_mbed 0:4d4c5ea17d86 141
s_inoue_mbed 0:4d4c5ea17d86 142 void DHT11::neg_edge(void)
s_inoue_mbed 0:4d4c5ea17d86 143 {
s_inoue_mbed 0:4d4c5ea17d86 144 // Disabling the interruptions
s_inoue_mbed 0:4d4c5ea17d86 145 io_irq.disable_irq();
s_inoue_mbed 0:4d4c5ea17d86 146
s_inoue_mbed 8:160047ca45bf 147 // Reading the positive pulse width
s_inoue_mbed 0:4d4c5ea17d86 148 t_pulse_us = t.read_us();
s_inoue_mbed 0:4d4c5ea17d86 149
s_inoue_mbed 9:056d1e9b428c 150 // Detecting 0 if the pulse width ranges around 25 us
s_inoue_mbed 9:056d1e9b428c 151 if (25 - t_tol_pulse <= t_pulse_us && t_pulse_us <= 30 + t_tol_pulse) {
s_inoue_mbed 0:4d4c5ea17d86 152 // Shifting the data buffer and not adding 1 (because this bit is zero)
s_inoue_mbed 0:4d4c5ea17d86 153 data = data << 1;
s_inoue_mbed 0:4d4c5ea17d86 154
s_inoue_mbed 0:4d4c5ea17d86 155 // Counting up the bits
s_inoue_mbed 0:4d4c5ea17d86 156 cnt++;
s_inoue_mbed 0:4d4c5ea17d86 157 }
s_inoue_mbed 0:4d4c5ea17d86 158
s_inoue_mbed 9:056d1e9b428c 159 // Detecting 1 if the pulse width ranges from 70 us
s_inoue_mbed 9:056d1e9b428c 160 else if (70 - t_tol_pulse <= t_pulse_us && t_pulse_us <= 70 + t_tol_pulse) {
s_inoue_mbed 0:4d4c5ea17d86 161 // Shifting the data buffer and adding 1 (because this bit is one)
s_inoue_mbed 0:4d4c5ea17d86 162 data = data << 1;
s_inoue_mbed 0:4d4c5ea17d86 163 data++;
s_inoue_mbed 0:4d4c5ea17d86 164
s_inoue_mbed 0:4d4c5ea17d86 165 // Counting up the bits
s_inoue_mbed 0:4d4c5ea17d86 166 cnt++;
s_inoue_mbed 0:4d4c5ea17d86 167 }
s_inoue_mbed 0:4d4c5ea17d86 168
s_inoue_mbed 0:4d4c5ea17d86 169 // Detecting the end of Data
s_inoue_mbed 0:4d4c5ea17d86 170 if (cnt < 40) {
s_inoue_mbed 0:4d4c5ea17d86 171 // Enabling the interruptions
s_inoue_mbed 0:4d4c5ea17d86 172 io_irq.enable_irq();
s_inoue_mbed 0:4d4c5ea17d86 173 } else {
s_inoue_mbed 0:4d4c5ea17d86 174 eod = true;
s_inoue_mbed 0:4d4c5ea17d86 175 }
s_inoue_mbed 0:4d4c5ea17d86 176 }