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:
ajp109
Date:
Wed Sep 15 14:47:06 2021 +0000
Revision:
13:11d0770eb603
Parent:
12:af1eadec17e5
Interface changes to remove the need for separate readData() calls

Who changed what in which revision?

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