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

Committer:
ajp109
Date:
Wed Sep 15 14:47:06 2021 +0000
Revision:
13:11d0770eb603
Parent:
12:af1eadec17e5
Child:
14:dc91e960af81
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 }