A library for the use of DHT11, a temperature and humidity sensor
Dependents: HTTP_SERVER2 lightweight-weather-station
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, PullNone, 1), io_irq(pin) 00023 { 00024 io_irq.rise(this, &DHT11::pos_edge); 00025 io_irq.fall(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 (t.read_ms() < 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 (t.read_ms() < 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.read_us() > 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.read_us() > 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.read_us() > 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.read_us(); 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 Mon Jul 18 2022 19:32:19 by 1.7.2