A library for the use of AM2303 (a.k.a. DHT22), a temperature and humidity sensor.
Dependents: AM2303_Hello_World
Fork of DHT11 by
Revision 0:4d4c5ea17d86, committed 2014-09-10
- Comitter:
- s_inoue_mbed
- Date:
- Wed Sep 10 15:14:31 2014 +0000
- Child:
- 1:95b80cc3f676
- Commit message:
- First version of the library for the use of DHT11, temperature and humidity sensor
Changed in this revision
DHT11.cpp | Show annotated file Show diff for this revision Revisions of this file |
DHT11.h | Show annotated file Show diff for this revision Revisions of this file |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DHT11.cpp Wed Sep 10 15:14:31 2014 +0000 @@ -0,0 +1,186 @@ +/** @file + Library for the use of the DHT11, a temperature and humidity sensor + Shigenori Inoue, September 10, 2014 + */ + +#include "DHT11.h" + +// Constructor +DHT11::DHT11(PinName pin) : io(pin, PIN_INPUT, OpenDrain, 1), io_irq(pin) +{ + io_irq.rise(this, &DHT11::pos_edge); + io_irq.fall(this, &DHT11::neg_edge); + io_irq.disable_irq(); + init(); +} + +// Destructor +DHT11::~DHT11(void) {} + +// Reading the data bits from DHT11 +int DHT11::readData() +{ + // Initialize + eod = false; + err = OK; + data = 0; + cnt = 0; + wdt = 0; + + // Checking the measurement frequency + if (t.read_ms() < 2000 & first_time == false) { + t.reset(); + return TOO_FAST_READ; + } + + // Checking the data bus + if (io == 0) { + io.input(); + return BUS_BUSY; + } + + // Sending start signal + io.output(); + t.reset(); + t.start(); + do { + io = 0; + } while (t.read_ms() < 18); + io.input(); + io = 1; + + // Waiting for the start of the response signal + t.reset(); + t.start(); + do { + if (t.read_us() > 100) { + io.input(); + io = 1; + return NOT_PRESENT; + } + } while (io == 1); + + // Wainting for the start of the ready signal + t.reset(); + t.start(); + do { + if (t.read_us() > 100) { + io.input(); + io = 1; + return NOT_READY; + } + } while (io == 0); + + // Wainting for the end of the ready signal + t.reset(); + t.start(); + do {} while (io == 1); + + // Starting the pulse width sensing + + io_irq.enable_irq(); + + do { + wait_us(100); + if (wdt > 50) { + return WATCHDOG_ERR; + } + wdt++; + } while (eod == false); + + // Calculating the check sum + chksum = ((data & 0xff00000000) >> 32) + + ((data & 0x00ff000000) >> 24) + + ((data & 0x0000ff0000) >> 16) + + ((data & 0x000000ff00) >> 8); + if (chksum != (data & 0x00000000ff)) { + io.input(); + io = 1; + return CHKSUM_ERR; + } else { + t.reset(); + first_time = false; + return OK; + } +} + +// Extracting humidity data from the received data +int DHT11::readHumidity() +{ + if (err == OK) { + return (data & 0xff00000000) >> 32; + } else { + return 0xffffffff; + } +} + +// Extracting temperature data from the received data +int DHT11::readTemperature() +{ + if (err == OK) { + return (data & 0x0000ff0000) >> 16; + } else { + return 0xffffffff; + } +} + +// Initialization of variables +void DHT11::init(void) +{ + t_pulse_us = 0; + first_time = true; + data = 0; + chksum = 0; + cnt = 0; + wdt = 0; + err = OK; + eod = false; +} + +void DHT11::pos_edge(void) +{ + // Disabling the interruptions + io_irq.disable_irq(); + + // Initializing the Timer + t.reset(); + + // Enabling the interruptions + io_irq.enable_irq(); +} + +void DHT11::neg_edge(void) +{ + // Disabling the interruptions + io_irq.disable_irq(); + + // Reading the length of + t_pulse_us = t.read_us(); + + // Detecting 0 if the pulse width ranges from 26 us to 28 us + if (20 <= t_pulse_us && t_pulse_us <= 30) { + // Shifting the data buffer and not adding 1 (because this bit is zero) + data = data << 1; + + // Counting up the bits + cnt++; + } + + // Detecting 1 if the pulse width ranges from 68 us to 72 us + else if (60 <= t_pulse_us && t_pulse_us <= 80) { + // Shifting the data buffer and adding 1 (because this bit is one) + data = data << 1; + data++; + + // Counting up the bits + cnt++; + } + + // Detecting the end of Data + if (cnt < 40) { + // Enabling the interruptions + io_irq.enable_irq(); + } else { + eod = true; + } +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DHT11.h Wed Sep 10 15:14:31 2014 +0000 @@ -0,0 +1,91 @@ +/** @file + Library for the use of the DHT11, a temperature and humidity sensor + Shigenori Inoue, September 10, 2014 + */ +#ifndef __DHT11__ +#define __DHT11__ +#include "mbed.h" + +/** Example: + * @code + * #include "mbed.h" + * #include "DHT11.h" + * + * DHT11 d; + * + * main() + * { + * int s; + * s = d.readData(); + * if (s != 0) { + * printf("Error!\r\n"); + * } + * else { + * printf("T:%d, H:%d\r\n", d.readTemperature(), d.readHumidity()); + * } + * } + * @endcode + */ + +class DHT11 +{ +public: + /** Create a DHT11 interface + * @param pin 1-wire-like serial I/O port of DHT11 + */ + DHT11(PinName pin); + ~DHT11(); + + /** Reading the data from the DHT11 */ + int readData(void); + + /** Reading the data from the DHT11 + * @return Error code + * 0: OK. + * 1: Reading the data too often. + * 2: 1-wire bus is busy. + * 3: DHT11 does not respond. + * 4: DHT11 is not ready. + * 5: Checksum is incorrect. + * 6: Timeout + */ + + /** Reading the humidity from the data + * @return Humidity in % if readData() returns no error. Otherwise, returns 0xffffffff. + */ + int readHumidity(void); + + /** Reading the humidity from the data + * @return Temperature in Celcius if readData() returns no error. Otherwise, returns 0xffffffff. + */ + int readTemperature(void); + + enum ErrorDHT11 { + OK = 0, + TOO_FAST_READ = 1, + BUS_BUSY = 2, + NOT_PRESENT = 3, + NOT_READY = 4, + CHKSUM_ERR = 5, + WATCHDOG_ERR = 6, + }; + +private: + PinName _pin; + DigitalInOut io; + InterruptIn io_irq; + Timer t; + uint32_t t_pulse_us; + bool first_time; + uint64_t data; + uint32_t chksum; + uint32_t cnt; + uint32_t wdt; + bool eod; + ErrorDHT11 err; + void init(void); + void pos_edge(void); + void neg_edge(void); +}; + +#endif \ No newline at end of file