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

Dependents:   HTTP_SERVER2 lightweight-weather-station

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DHT11.cpp Source File

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 }