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

Dependents:   HTTP_SERVER2 lightweight-weather-station

Committer:
gjanusz
Date:
Sat Nov 24 22:19:48 2018 +0000
Revision:
12:c5a7faaeddd6
Parent:
11:e91c151d1798
Change OpenDrain;

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
gjanusz 12:c5a7faaeddd6 22 DHT11::DHT11(PinName pin) : io(pin, PIN_INPUT, PullNone, 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 }