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

Dependents:   DHT11_Hello_World IBMIoTClientEthernetExample_W5200 AutoPlants PB_Emma_Ethernet ... more

Committer:
s_inoue_mbed
Date:
Tue Sep 16 13:06:43 2014 +0000
Revision:
10:f0d789f49df7
Parent:
9:056d1e9b428c
Child:
11:e91c151d1798
License has been changed from Apache2 to MIT lisence.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
s_inoue_mbed 10:f0d789f49df7 1 /* Copyright (c) 2014 Shigenori Inoue, MIT License
s_inoue_mbed 10:f0d789f49df7 2 *
s_inoue_mbed 10:f0d789f49df7 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
s_inoue_mbed 10:f0d789f49df7 4 * and associated documentation files (the "Software"), to deal in the Software without restriction,
s_inoue_mbed 10:f0d789f49df7 5 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
s_inoue_mbed 10:f0d789f49df7 6 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
s_inoue_mbed 10:f0d789f49df7 7 * furnished to do so, subject to the following conditions:
s_inoue_mbed 10:f0d789f49df7 8 *
s_inoue_mbed 10:f0d789f49df7 9 * The above copyright notice and this permission notice shall be included in all copies or
s_inoue_mbed 10:f0d789f49df7 10 * substantial portions of the Software.
s_inoue_mbed 10:f0d789f49df7 11 *
s_inoue_mbed 10:f0d789f49df7 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
s_inoue_mbed 10:f0d789f49df7 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
s_inoue_mbed 10:f0d789f49df7 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
s_inoue_mbed 10:f0d789f49df7 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
s_inoue_mbed 10:f0d789f49df7 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
s_inoue_mbed 0:4d4c5ea17d86 17 */
s_inoue_mbed 0:4d4c5ea17d86 18
s_inoue_mbed 0:4d4c5ea17d86 19 #include "DHT11.h"
s_inoue_mbed 0:4d4c5ea17d86 20
s_inoue_mbed 0:4d4c5ea17d86 21 // Constructor
s_inoue_mbed 0:4d4c5ea17d86 22 DHT11::DHT11(PinName pin) : io(pin, PIN_INPUT, OpenDrain, 1), io_irq(pin)
s_inoue_mbed 0:4d4c5ea17d86 23 {
s_inoue_mbed 0:4d4c5ea17d86 24 io_irq.rise(this, &DHT11::pos_edge);
s_inoue_mbed 0:4d4c5ea17d86 25 io_irq.fall(this, &DHT11::neg_edge);
s_inoue_mbed 0:4d4c5ea17d86 26 io_irq.disable_irq();
s_inoue_mbed 9:056d1e9b428c 27 t.start();
s_inoue_mbed 6:257e2ab66d0f 28 first_time = true;
s_inoue_mbed 0:4d4c5ea17d86 29 }
s_inoue_mbed 0:4d4c5ea17d86 30
s_inoue_mbed 0:4d4c5ea17d86 31 // Destructor
s_inoue_mbed 0:4d4c5ea17d86 32 DHT11::~DHT11(void) {}
s_inoue_mbed 0:4d4c5ea17d86 33
s_inoue_mbed 9:056d1e9b428c 34 // Constants
s_inoue_mbed 9:056d1e9b428c 35 const int DHT11::t_tol_start = 2;
s_inoue_mbed 9:056d1e9b428c 36 const int DHT11::t_tol_pulse = 10;
s_inoue_mbed 9:056d1e9b428c 37
s_inoue_mbed 6:257e2ab66d0f 38 // Reading the data bits from the DHT11
s_inoue_mbed 9:056d1e9b428c 39 int DHT11::readData(void)
s_inoue_mbed 0:4d4c5ea17d86 40 {
s_inoue_mbed 9:056d1e9b428c 41 // Checking the measurement frequency
s_inoue_mbed 9:056d1e9b428c 42 if (t.read_ms() < 2000 && first_time == false) {
s_inoue_mbed 9:056d1e9b428c 43 t.reset();
s_inoue_mbed 9:056d1e9b428c 44 return READ_TOO_OFTEN;
s_inoue_mbed 9:056d1e9b428c 45 }
s_inoue_mbed 9:056d1e9b428c 46
s_inoue_mbed 0:4d4c5ea17d86 47 // Initialize
s_inoue_mbed 6:257e2ab66d0f 48 init();
s_inoue_mbed 0:4d4c5ea17d86 49
s_inoue_mbed 0:4d4c5ea17d86 50 // Checking the data bus
s_inoue_mbed 0:4d4c5ea17d86 51 if (io == 0) {
s_inoue_mbed 9:056d1e9b428c 52 t.reset();
s_inoue_mbed 0:4d4c5ea17d86 53 return BUS_BUSY;
s_inoue_mbed 0:4d4c5ea17d86 54 }
s_inoue_mbed 0:4d4c5ea17d86 55
s_inoue_mbed 9:056d1e9b428c 56 // Sending start signal, low signal for around 10 ms
s_inoue_mbed 0:4d4c5ea17d86 57 t.reset();
s_inoue_mbed 0:4d4c5ea17d86 58 do {
s_inoue_mbed 0:4d4c5ea17d86 59 io = 0;
s_inoue_mbed 9:056d1e9b428c 60 } while (t.read_ms() < 20 + t_tol_start);
s_inoue_mbed 7:50f5c8efd967 61 io = 1;
s_inoue_mbed 0:4d4c5ea17d86 62
s_inoue_mbed 0:4d4c5ea17d86 63 // Waiting for the start of the response signal
s_inoue_mbed 0:4d4c5ea17d86 64 t.reset();
s_inoue_mbed 0:4d4c5ea17d86 65 do {
s_inoue_mbed 0:4d4c5ea17d86 66 if (t.read_us() > 100) {
s_inoue_mbed 9:056d1e9b428c 67 t.reset();
s_inoue_mbed 0:4d4c5ea17d86 68 return NOT_PRESENT;
s_inoue_mbed 0:4d4c5ea17d86 69 }
s_inoue_mbed 0:4d4c5ea17d86 70 } while (io == 1);
s_inoue_mbed 0:4d4c5ea17d86 71
s_inoue_mbed 0:4d4c5ea17d86 72 // Wainting for the start of the ready signal
s_inoue_mbed 0:4d4c5ea17d86 73 t.reset();
s_inoue_mbed 0:4d4c5ea17d86 74 do {
s_inoue_mbed 0:4d4c5ea17d86 75 if (t.read_us() > 100) {
s_inoue_mbed 9:056d1e9b428c 76 t.reset();
s_inoue_mbed 0:4d4c5ea17d86 77 return NOT_READY;
s_inoue_mbed 0:4d4c5ea17d86 78 }
s_inoue_mbed 0:4d4c5ea17d86 79 } while (io == 0);
s_inoue_mbed 0:4d4c5ea17d86 80
s_inoue_mbed 0:4d4c5ea17d86 81 // Wainting for the end of the ready signal
s_inoue_mbed 0:4d4c5ea17d86 82 t.reset();
s_inoue_mbed 9:056d1e9b428c 83 do {
s_inoue_mbed 9:056d1e9b428c 84 if (t.read_us() > 100) {
s_inoue_mbed 9:056d1e9b428c 85 t.reset();
s_inoue_mbed 9:056d1e9b428c 86 return WATCHDOG_ERR;
s_inoue_mbed 9:056d1e9b428c 87 }
s_inoue_mbed 9:056d1e9b428c 88 } while (io == 1);
s_inoue_mbed 0:4d4c5ea17d86 89
s_inoue_mbed 0:4d4c5ea17d86 90 // Starting the pulse width sensing
s_inoue_mbed 9:056d1e9b428c 91 // by the use of interruptions
s_inoue_mbed 0:4d4c5ea17d86 92 io_irq.enable_irq();
s_inoue_mbed 0:4d4c5ea17d86 93
s_inoue_mbed 0:4d4c5ea17d86 94 do {
s_inoue_mbed 0:4d4c5ea17d86 95 wait_us(100);
s_inoue_mbed 0:4d4c5ea17d86 96 if (wdt > 50) {
s_inoue_mbed 9:056d1e9b428c 97 t.reset();
s_inoue_mbed 0:4d4c5ea17d86 98 return WATCHDOG_ERR;
s_inoue_mbed 0:4d4c5ea17d86 99 }
s_inoue_mbed 0:4d4c5ea17d86 100 wdt++;
s_inoue_mbed 0:4d4c5ea17d86 101 } while (eod == false);
s_inoue_mbed 0:4d4c5ea17d86 102
s_inoue_mbed 0:4d4c5ea17d86 103 // Calculating the check sum
s_inoue_mbed 0:4d4c5ea17d86 104 chksum = ((data & 0xff00000000) >> 32)
s_inoue_mbed 0:4d4c5ea17d86 105 + ((data & 0x00ff000000) >> 24)
s_inoue_mbed 0:4d4c5ea17d86 106 + ((data & 0x0000ff0000) >> 16)
s_inoue_mbed 0:4d4c5ea17d86 107 + ((data & 0x000000ff00) >> 8);
s_inoue_mbed 9:056d1e9b428c 108
s_inoue_mbed 0:4d4c5ea17d86 109 if (chksum != (data & 0x00000000ff)) {
s_inoue_mbed 9:056d1e9b428c 110 t.reset();
s_inoue_mbed 0:4d4c5ea17d86 111 return CHKSUM_ERR;
s_inoue_mbed 0:4d4c5ea17d86 112 } else {
s_inoue_mbed 0:4d4c5ea17d86 113 t.reset();
s_inoue_mbed 0:4d4c5ea17d86 114 first_time = false;
s_inoue_mbed 0:4d4c5ea17d86 115 return OK;
s_inoue_mbed 0:4d4c5ea17d86 116 }
s_inoue_mbed 0:4d4c5ea17d86 117 }
s_inoue_mbed 0:4d4c5ea17d86 118
s_inoue_mbed 0:4d4c5ea17d86 119 // Extracting humidity data from the received data
s_inoue_mbed 9:056d1e9b428c 120 int DHT11::readHumidity(void)
s_inoue_mbed 0:4d4c5ea17d86 121 {
s_inoue_mbed 9:056d1e9b428c 122 return (data & 0xff00000000) >> 32;
s_inoue_mbed 0:4d4c5ea17d86 123 }
s_inoue_mbed 0:4d4c5ea17d86 124
s_inoue_mbed 0:4d4c5ea17d86 125 // Extracting temperature data from the received data
s_inoue_mbed 9:056d1e9b428c 126 int DHT11::readTemperature(void)
s_inoue_mbed 0:4d4c5ea17d86 127 {
s_inoue_mbed 9:056d1e9b428c 128 return (data & 0x0000ff0000) >> 16;
s_inoue_mbed 0:4d4c5ea17d86 129 }
s_inoue_mbed 0:4d4c5ea17d86 130
s_inoue_mbed 0:4d4c5ea17d86 131 // Initialization of variables
s_inoue_mbed 0:4d4c5ea17d86 132 void DHT11::init(void)
s_inoue_mbed 0:4d4c5ea17d86 133 {
s_inoue_mbed 0:4d4c5ea17d86 134 t_pulse_us = 0;
s_inoue_mbed 0:4d4c5ea17d86 135 data = 0;
s_inoue_mbed 0:4d4c5ea17d86 136 chksum = 0;
s_inoue_mbed 0:4d4c5ea17d86 137 cnt = 0;
s_inoue_mbed 0:4d4c5ea17d86 138 wdt = 0;
s_inoue_mbed 0:4d4c5ea17d86 139 eod = false;
s_inoue_mbed 9:056d1e9b428c 140 t.reset();
s_inoue_mbed 0:4d4c5ea17d86 141 }
s_inoue_mbed 0:4d4c5ea17d86 142
s_inoue_mbed 0:4d4c5ea17d86 143 void DHT11::pos_edge(void)
s_inoue_mbed 0:4d4c5ea17d86 144 {
s_inoue_mbed 0:4d4c5ea17d86 145 // Disabling the interruptions
s_inoue_mbed 0:4d4c5ea17d86 146 io_irq.disable_irq();
s_inoue_mbed 0:4d4c5ea17d86 147
s_inoue_mbed 0:4d4c5ea17d86 148 // Initializing the Timer
s_inoue_mbed 0:4d4c5ea17d86 149 t.reset();
s_inoue_mbed 0:4d4c5ea17d86 150
s_inoue_mbed 0:4d4c5ea17d86 151 // Enabling the interruptions
s_inoue_mbed 0:4d4c5ea17d86 152 io_irq.enable_irq();
s_inoue_mbed 0:4d4c5ea17d86 153 }
s_inoue_mbed 0:4d4c5ea17d86 154
s_inoue_mbed 0:4d4c5ea17d86 155 void DHT11::neg_edge(void)
s_inoue_mbed 0:4d4c5ea17d86 156 {
s_inoue_mbed 0:4d4c5ea17d86 157 // Disabling the interruptions
s_inoue_mbed 0:4d4c5ea17d86 158 io_irq.disable_irq();
s_inoue_mbed 0:4d4c5ea17d86 159
s_inoue_mbed 8:160047ca45bf 160 // Reading the positive pulse width
s_inoue_mbed 0:4d4c5ea17d86 161 t_pulse_us = t.read_us();
s_inoue_mbed 0:4d4c5ea17d86 162
s_inoue_mbed 9:056d1e9b428c 163 // Detecting 0 if the pulse width ranges around 25 us
s_inoue_mbed 9:056d1e9b428c 164 if (25 - t_tol_pulse <= t_pulse_us && t_pulse_us <= 30 + t_tol_pulse) {
s_inoue_mbed 0:4d4c5ea17d86 165 // Shifting the data buffer and not adding 1 (because this bit is zero)
s_inoue_mbed 0:4d4c5ea17d86 166 data = data << 1;
s_inoue_mbed 0:4d4c5ea17d86 167
s_inoue_mbed 0:4d4c5ea17d86 168 // Counting up the bits
s_inoue_mbed 0:4d4c5ea17d86 169 cnt++;
s_inoue_mbed 0:4d4c5ea17d86 170 }
s_inoue_mbed 0:4d4c5ea17d86 171
s_inoue_mbed 9:056d1e9b428c 172 // Detecting 1 if the pulse width ranges from 70 us
s_inoue_mbed 9:056d1e9b428c 173 else if (70 - t_tol_pulse <= t_pulse_us && t_pulse_us <= 70 + t_tol_pulse) {
s_inoue_mbed 0:4d4c5ea17d86 174 // Shifting the data buffer and adding 1 (because this bit is one)
s_inoue_mbed 0:4d4c5ea17d86 175 data = data << 1;
s_inoue_mbed 0:4d4c5ea17d86 176 data++;
s_inoue_mbed 0:4d4c5ea17d86 177
s_inoue_mbed 0:4d4c5ea17d86 178 // Counting up the bits
s_inoue_mbed 0:4d4c5ea17d86 179 cnt++;
s_inoue_mbed 0:4d4c5ea17d86 180 }
s_inoue_mbed 0:4d4c5ea17d86 181
s_inoue_mbed 0:4d4c5ea17d86 182 // Detecting the end of Data
s_inoue_mbed 0:4d4c5ea17d86 183 if (cnt < 40) {
s_inoue_mbed 0:4d4c5ea17d86 184 // Enabling the interruptions
s_inoue_mbed 0:4d4c5ea17d86 185 io_irq.enable_irq();
s_inoue_mbed 0:4d4c5ea17d86 186 } else {
s_inoue_mbed 0:4d4c5ea17d86 187 eod = true;
s_inoue_mbed 0:4d4c5ea17d86 188 }
s_inoue_mbed 0:4d4c5ea17d86 189 }