Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
DHT11.cpp
00001 /* Copyright (c) 2014 Shigenori Inoue, MIT License 00002 * 00003 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 00004 * and associated documentation files (the "Software"), to deal in the Software without restriction, 00005 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 00006 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 00007 * furnished to do so, subject to the following conditions: 00008 * 00009 * The above copyright notice and this permission notice shall be included in all copies or 00010 * substantial portions of the Software. 00011 * 00012 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 00013 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00014 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00015 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00016 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00017 */ 00018 00019 #include "DHT11.h" 00020 00021 // Constructor 00022 DHT11::DHT11(PinName pin) : io(pin, PIN_INPUT, OpenDrain, 1), io_irq(pin) 00023 { 00024 io_irq.rise(callback(this, &DHT11::pos_edge)); 00025 io_irq.fall(callback(this, &DHT11::neg_edge)); 00026 io_irq.disable_irq(); 00027 t.start(); 00028 first_time = true; 00029 } 00030 00031 // Destructor 00032 DHT11::~DHT11(void) {} 00033 00034 // Constants 00035 const int DHT11::t_tol_start = 2; 00036 const int DHT11::t_tol_pulse = 10; 00037 00038 // Reading the data bits from the DHT11 00039 int DHT11::readData(void) 00040 { 00041 // Checking the measurement frequency 00042 if (chrono::duration_cast<chrono::milliseconds>(t.elapsed_time()).count() < 2000 && first_time == false) { 00043 t.reset(); 00044 return READ_TOO_OFTEN; 00045 } 00046 00047 // Initialize 00048 init(); 00049 00050 // Checking the data bus 00051 if (io == 0) { 00052 t.reset(); 00053 return BUS_BUSY; 00054 } 00055 00056 // Sending start signal, low signal for around 10 ms 00057 t.reset(); 00058 io.output(); 00059 io = 0; 00060 do { 00061 } while (chrono::duration_cast<chrono::milliseconds>(t.elapsed_time()).count() < 20 + t_tol_start); 00062 io.input(); 00063 io = 1; 00064 00065 00066 // Waiting for the start of the response signal 00067 t.reset(); 00068 do { 00069 if (t.elapsed_time().count() > 100) { 00070 t.reset(); 00071 return NOT_PRESENT; 00072 } 00073 } while (io == 1); 00074 00075 // Wainting for the start of the ready signal 00076 t.reset(); 00077 do { 00078 if (t.elapsed_time().count() > 100) { 00079 t.reset(); 00080 return NOT_READY; 00081 } 00082 } while (io == 0); 00083 00084 // Wainting for the end of the ready signal 00085 t.reset(); 00086 do { 00087 if (t.elapsed_time().count() > 100) { 00088 t.reset(); 00089 return WATCHDOG_ERR; 00090 } 00091 } while (io == 1); 00092 00093 // Starting the pulse width sensing 00094 // by the use of interruptions 00095 io_irq.enable_irq(); 00096 00097 do { 00098 wait_us(100); 00099 if (wdt > 50) { 00100 t.reset(); 00101 return WATCHDOG_ERR; 00102 } 00103 wdt++; 00104 } while (eod == false); 00105 00106 // Calculating the check sum 00107 chksum = ((data & 0xff00000000) >> 32) 00108 + ((data & 0x00ff000000) >> 24) 00109 + ((data & 0x0000ff0000) >> 16) 00110 + ((data & 0x000000ff00) >> 8); 00111 00112 if (chksum != (data & 0x00000000ff)) { 00113 t.reset(); 00114 return CHKSUM_ERR; 00115 } else { 00116 t.reset(); 00117 first_time = false; 00118 return OK; 00119 } 00120 } 00121 00122 // Extracting humidity data from the received data 00123 int DHT11::readHumidity(void) 00124 { 00125 return (data & 0xff00000000) >> 32; 00126 } 00127 00128 // Extracting temperature data from the received data 00129 int DHT11::readTemperature(void) 00130 { 00131 return (data & 0x0000ff0000) >> 16; 00132 } 00133 00134 // Initialization of variables 00135 void DHT11::init(void) 00136 { 00137 t_pulse_us = 0; 00138 data = 0; 00139 chksum = 0; 00140 cnt = 0; 00141 wdt = 0; 00142 eod = false; 00143 t.reset(); 00144 } 00145 00146 void DHT11::pos_edge(void) 00147 { 00148 // Disabling the interruptions 00149 io_irq.disable_irq(); 00150 00151 // Initializing the Timer 00152 t.reset(); 00153 00154 // Enabling the interruptions 00155 io_irq.enable_irq(); 00156 } 00157 00158 void DHT11::neg_edge(void) 00159 { 00160 // Disabling the interruptions 00161 io_irq.disable_irq(); 00162 00163 // Reading the positive pulse width 00164 t_pulse_us = t.elapsed_time().count(); 00165 00166 // Detecting 0 if the pulse width ranges around 25 us 00167 if (25 - t_tol_pulse <= t_pulse_us && t_pulse_us <= 30 + t_tol_pulse) { 00168 // Shifting the data buffer and not adding 1 (because this bit is zero) 00169 data = data << 1; 00170 00171 // Counting up the bits 00172 cnt++; 00173 } 00174 00175 // Detecting 1 if the pulse width ranges from 70 us 00176 else if (70 - t_tol_pulse <= t_pulse_us && t_pulse_us <= 70 + t_tol_pulse) { 00177 // Shifting the data buffer and adding 1 (because this bit is one) 00178 data = data << 1; 00179 data++; 00180 00181 // Counting up the bits 00182 cnt++; 00183 } 00184 00185 // Detecting the end of Data 00186 if (cnt < 40) { 00187 // Enabling the interruptions 00188 io_irq.enable_irq(); 00189 } else { 00190 eod = true; 00191 } 00192 }
Generated on Thu Jul 14 2022 08:31:07 by
