Simple library for the DHT11 temperature and humidity sensor. Forked from an existing Mbed DHT11 project.

Dependents:   UoY-DHT11-test

Simple DHT11 temperature and humidity library.

Example usage

#include "mbed.h"
#include "DHT11.h"

DHT11 dht(D8); // Change pin name here if required

main()
{
    printf("T:%d, H:%d\r\n", dht.readTemperature(), dht.readHumidity());
}

The sensor may be read as often as desired, but temperature and humidity values are cached and will only be updated if they are more than 2 seconds old. This is the underlying sensor update rate.

Please note that this project has been modified only enough to make it work for its intended purpose. Various parts of this project still need work, and the source code should not be seen as an example of best practice.

Committer:
s_inoue_mbed
Date:
Thu Sep 25 14:13:10 2014 +0000
Revision:
11:e91c151d1798
Parent:
10:f0d789f49df7
Child:
12:af1eadec17e5
Bug fix (I/O pin is changed to OUTPUT for the start pulse).

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 11:e91c151d1798 58 io.output();
s_inoue_mbed 11:e91c151d1798 59 io = 0;
s_inoue_mbed 0:4d4c5ea17d86 60 do {
s_inoue_mbed 9:056d1e9b428c 61 } while (t.read_ms() < 20 + t_tol_start);
s_inoue_mbed 11:e91c151d1798 62 io.input();
s_inoue_mbed 7:50f5c8efd967 63 io = 1;
s_inoue_mbed 11:e91c151d1798 64
s_inoue_mbed 0:4d4c5ea17d86 65
s_inoue_mbed 0:4d4c5ea17d86 66 // Waiting for the start of the response signal
s_inoue_mbed 0:4d4c5ea17d86 67 t.reset();
s_inoue_mbed 0:4d4c5ea17d86 68 do {
s_inoue_mbed 0:4d4c5ea17d86 69 if (t.read_us() > 100) {
s_inoue_mbed 9:056d1e9b428c 70 t.reset();
s_inoue_mbed 0:4d4c5ea17d86 71 return NOT_PRESENT;
s_inoue_mbed 0:4d4c5ea17d86 72 }
s_inoue_mbed 0:4d4c5ea17d86 73 } while (io == 1);
s_inoue_mbed 0:4d4c5ea17d86 74
s_inoue_mbed 0:4d4c5ea17d86 75 // Wainting for the start of the ready signal
s_inoue_mbed 0:4d4c5ea17d86 76 t.reset();
s_inoue_mbed 0:4d4c5ea17d86 77 do {
s_inoue_mbed 0:4d4c5ea17d86 78 if (t.read_us() > 100) {
s_inoue_mbed 9:056d1e9b428c 79 t.reset();
s_inoue_mbed 0:4d4c5ea17d86 80 return NOT_READY;
s_inoue_mbed 0:4d4c5ea17d86 81 }
s_inoue_mbed 0:4d4c5ea17d86 82 } while (io == 0);
s_inoue_mbed 0:4d4c5ea17d86 83
s_inoue_mbed 0:4d4c5ea17d86 84 // Wainting for the end of the ready signal
s_inoue_mbed 0:4d4c5ea17d86 85 t.reset();
s_inoue_mbed 9:056d1e9b428c 86 do {
s_inoue_mbed 9:056d1e9b428c 87 if (t.read_us() > 100) {
s_inoue_mbed 9:056d1e9b428c 88 t.reset();
s_inoue_mbed 9:056d1e9b428c 89 return WATCHDOG_ERR;
s_inoue_mbed 9:056d1e9b428c 90 }
s_inoue_mbed 9:056d1e9b428c 91 } while (io == 1);
s_inoue_mbed 0:4d4c5ea17d86 92
s_inoue_mbed 0:4d4c5ea17d86 93 // Starting the pulse width sensing
s_inoue_mbed 9:056d1e9b428c 94 // by the use of interruptions
s_inoue_mbed 0:4d4c5ea17d86 95 io_irq.enable_irq();
s_inoue_mbed 0:4d4c5ea17d86 96
s_inoue_mbed 0:4d4c5ea17d86 97 do {
s_inoue_mbed 0:4d4c5ea17d86 98 wait_us(100);
s_inoue_mbed 0:4d4c5ea17d86 99 if (wdt > 50) {
s_inoue_mbed 9:056d1e9b428c 100 t.reset();
s_inoue_mbed 0:4d4c5ea17d86 101 return WATCHDOG_ERR;
s_inoue_mbed 0:4d4c5ea17d86 102 }
s_inoue_mbed 0:4d4c5ea17d86 103 wdt++;
s_inoue_mbed 0:4d4c5ea17d86 104 } while (eod == false);
s_inoue_mbed 0:4d4c5ea17d86 105
s_inoue_mbed 0:4d4c5ea17d86 106 // Calculating the check sum
s_inoue_mbed 0:4d4c5ea17d86 107 chksum = ((data & 0xff00000000) >> 32)
s_inoue_mbed 0:4d4c5ea17d86 108 + ((data & 0x00ff000000) >> 24)
s_inoue_mbed 0:4d4c5ea17d86 109 + ((data & 0x0000ff0000) >> 16)
s_inoue_mbed 0:4d4c5ea17d86 110 + ((data & 0x000000ff00) >> 8);
s_inoue_mbed 9:056d1e9b428c 111
s_inoue_mbed 0:4d4c5ea17d86 112 if (chksum != (data & 0x00000000ff)) {
s_inoue_mbed 9:056d1e9b428c 113 t.reset();
s_inoue_mbed 0:4d4c5ea17d86 114 return CHKSUM_ERR;
s_inoue_mbed 0:4d4c5ea17d86 115 } else {
s_inoue_mbed 0:4d4c5ea17d86 116 t.reset();
s_inoue_mbed 0:4d4c5ea17d86 117 first_time = false;
s_inoue_mbed 0:4d4c5ea17d86 118 return OK;
s_inoue_mbed 0:4d4c5ea17d86 119 }
s_inoue_mbed 0:4d4c5ea17d86 120 }
s_inoue_mbed 0:4d4c5ea17d86 121
s_inoue_mbed 0:4d4c5ea17d86 122 // Extracting humidity data from the received data
s_inoue_mbed 9:056d1e9b428c 123 int DHT11::readHumidity(void)
s_inoue_mbed 0:4d4c5ea17d86 124 {
s_inoue_mbed 9:056d1e9b428c 125 return (data & 0xff00000000) >> 32;
s_inoue_mbed 0:4d4c5ea17d86 126 }
s_inoue_mbed 0:4d4c5ea17d86 127
s_inoue_mbed 0:4d4c5ea17d86 128 // Extracting temperature data from the received data
s_inoue_mbed 9:056d1e9b428c 129 int DHT11::readTemperature(void)
s_inoue_mbed 0:4d4c5ea17d86 130 {
s_inoue_mbed 9:056d1e9b428c 131 return (data & 0x0000ff0000) >> 16;
s_inoue_mbed 0:4d4c5ea17d86 132 }
s_inoue_mbed 0:4d4c5ea17d86 133
s_inoue_mbed 0:4d4c5ea17d86 134 // Initialization of variables
s_inoue_mbed 0:4d4c5ea17d86 135 void DHT11::init(void)
s_inoue_mbed 0:4d4c5ea17d86 136 {
s_inoue_mbed 0:4d4c5ea17d86 137 t_pulse_us = 0;
s_inoue_mbed 0:4d4c5ea17d86 138 data = 0;
s_inoue_mbed 0:4d4c5ea17d86 139 chksum = 0;
s_inoue_mbed 0:4d4c5ea17d86 140 cnt = 0;
s_inoue_mbed 0:4d4c5ea17d86 141 wdt = 0;
s_inoue_mbed 0:4d4c5ea17d86 142 eod = false;
s_inoue_mbed 9:056d1e9b428c 143 t.reset();
s_inoue_mbed 0:4d4c5ea17d86 144 }
s_inoue_mbed 0:4d4c5ea17d86 145
s_inoue_mbed 0:4d4c5ea17d86 146 void DHT11::pos_edge(void)
s_inoue_mbed 0:4d4c5ea17d86 147 {
s_inoue_mbed 0:4d4c5ea17d86 148 // Disabling the interruptions
s_inoue_mbed 0:4d4c5ea17d86 149 io_irq.disable_irq();
s_inoue_mbed 0:4d4c5ea17d86 150
s_inoue_mbed 0:4d4c5ea17d86 151 // Initializing the Timer
s_inoue_mbed 0:4d4c5ea17d86 152 t.reset();
s_inoue_mbed 0:4d4c5ea17d86 153
s_inoue_mbed 0:4d4c5ea17d86 154 // Enabling the interruptions
s_inoue_mbed 0:4d4c5ea17d86 155 io_irq.enable_irq();
s_inoue_mbed 0:4d4c5ea17d86 156 }
s_inoue_mbed 0:4d4c5ea17d86 157
s_inoue_mbed 0:4d4c5ea17d86 158 void DHT11::neg_edge(void)
s_inoue_mbed 0:4d4c5ea17d86 159 {
s_inoue_mbed 0:4d4c5ea17d86 160 // Disabling the interruptions
s_inoue_mbed 0:4d4c5ea17d86 161 io_irq.disable_irq();
s_inoue_mbed 0:4d4c5ea17d86 162
s_inoue_mbed 8:160047ca45bf 163 // Reading the positive pulse width
s_inoue_mbed 0:4d4c5ea17d86 164 t_pulse_us = t.read_us();
s_inoue_mbed 0:4d4c5ea17d86 165
s_inoue_mbed 9:056d1e9b428c 166 // Detecting 0 if the pulse width ranges around 25 us
s_inoue_mbed 9:056d1e9b428c 167 if (25 - t_tol_pulse <= t_pulse_us && t_pulse_us <= 30 + t_tol_pulse) {
s_inoue_mbed 0:4d4c5ea17d86 168 // Shifting the data buffer and not adding 1 (because this bit is zero)
s_inoue_mbed 0:4d4c5ea17d86 169 data = data << 1;
s_inoue_mbed 0:4d4c5ea17d86 170
s_inoue_mbed 0:4d4c5ea17d86 171 // Counting up the bits
s_inoue_mbed 0:4d4c5ea17d86 172 cnt++;
s_inoue_mbed 0:4d4c5ea17d86 173 }
s_inoue_mbed 0:4d4c5ea17d86 174
s_inoue_mbed 9:056d1e9b428c 175 // Detecting 1 if the pulse width ranges from 70 us
s_inoue_mbed 9:056d1e9b428c 176 else if (70 - t_tol_pulse <= t_pulse_us && t_pulse_us <= 70 + t_tol_pulse) {
s_inoue_mbed 0:4d4c5ea17d86 177 // Shifting the data buffer and adding 1 (because this bit is one)
s_inoue_mbed 0:4d4c5ea17d86 178 data = data << 1;
s_inoue_mbed 0:4d4c5ea17d86 179 data++;
s_inoue_mbed 0:4d4c5ea17d86 180
s_inoue_mbed 0:4d4c5ea17d86 181 // Counting up the bits
s_inoue_mbed 0:4d4c5ea17d86 182 cnt++;
s_inoue_mbed 0:4d4c5ea17d86 183 }
s_inoue_mbed 0:4d4c5ea17d86 184
s_inoue_mbed 0:4d4c5ea17d86 185 // Detecting the end of Data
s_inoue_mbed 0:4d4c5ea17d86 186 if (cnt < 40) {
s_inoue_mbed 0:4d4c5ea17d86 187 // Enabling the interruptions
s_inoue_mbed 0:4d4c5ea17d86 188 io_irq.enable_irq();
s_inoue_mbed 0:4d4c5ea17d86 189 } else {
s_inoue_mbed 0:4d4c5ea17d86 190 eod = true;
s_inoue_mbed 0:4d4c5ea17d86 191 }
s_inoue_mbed 0:4d4c5ea17d86 192 }