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 12:1ad0612823e9, committed 2014-10-13
- Comitter:
- s_inoue_mbed
- Date:
- Mon Oct 13 14:18:58 2014 +0000
- Parent:
- 11:e91c151d1798
- Commit message:
- First version
Changed in this revision
diff -r e91c151d1798 -r 1ad0612823e9 AM2303.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/AM2303.cpp Mon Oct 13 14:18:58 2014 +0000 @@ -0,0 +1,192 @@ +/* Copyright (c) 2014 Shigenori Inoue, MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "AM2303.h" + +// Constructor +AM2303::AM2303(PinName pin) : io(pin, PIN_INPUT, OpenDrain, 1), io_irq(pin) +{ + io_irq.rise(this, &AM2303::pos_edge); + io_irq.fall(this, &AM2303::neg_edge); + io_irq.disable_irq(); + io_irq.mode(OpenDrain); + t.start(); + first_time = true; +} + +// Destructor +AM2303::~AM2303(void) {} + +// Constants +const int AM2303::t_tol_start = 100; +const int AM2303::t_tol_pulse = 10; + +// Reading the data bits from the AM2303 +int AM2303::readData(void) +{ + // Checking the measurement frequency + if (t.read_ms() < 2000 && first_time == false) { + t.reset(); + return READ_TOO_OFTEN; + } + + // Initialize + init(); + + // Checking the data bus + if (io == 0) { + t.reset(); + return BUS_BUSY; + } + + // Sending start signal, low signal for around 10 ms + t.reset(); + io.output(); + io = 0; + do { + } while (t.read_us() < 1000 + t_tol_start); + io.input(); + io = 1; + + // Waiting for the start of the response signal + t.reset(); + do { + if (t.read_us() > 100) { + t.reset(); + return NOT_PRESENT; + } + } while (io == 1); + + // Wainting for the start of the ready signal + t.reset(); + do { + if (t.read_us() > 100) { + t.reset(); + return NOT_READY; + } + } while (io == 0); + + // Wainting for the end of the ready signal + t.reset(); + do { + if (t.read_us() > 100) { + t.reset(); + return WATCHDOG_ERR; + } + } while (io == 1); + + // Starting the pulse width sensing + // by the use of interruptions + io_irq.enable_irq(); + + do { + wait_us(100); + if (wdt > 50) { + t.reset(); + 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 & 0xff) != (data & 0x00000000ff)) { + t.reset(); + return CHKSUM_ERR; + } else { + t.reset(); + first_time = false; + return OK; + } +} + +// Extracting humidity data from the received data +float AM2303::readHumidity(void) +{ + return static_cast<float>((data & 0xffff000000) >> 24) / 10; +} + +// Extracting temperature data from the received data +float AM2303::readTemperature(void) +{ + return static_cast<float>((data & 0x0000ffff00) >> 8) / 10; +} + +// Initialization of variables +void AM2303::init(void) +{ + t_pulse_us = 0; + data = 0; + chksum = 0; + cnt = 0; + wdt = 0; + eod = false; + t.reset(); +} + +void AM2303::pos_edge(void) +{ + // Disabling the interruptions + io_irq.disable_irq(); + + // Initializing the Timer + t.reset(); + + // Enabling the interruptions + io_irq.enable_irq(); +} + +void AM2303::neg_edge(void) +{ + // Disabling the interruptions + io_irq.disable_irq(); + + // Reading the positive pulse width + t_pulse_us = t.read_us(); + + // Detecting 0 if the pulse width ranges around 25 us + if (25 - t_tol_pulse <= t_pulse_us && t_pulse_us <= 30 + t_tol_pulse) { + // 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 70 us + else if (70 - t_tol_pulse <= t_pulse_us && t_pulse_us <= 70 + t_tol_pulse) { + // 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
diff -r e91c151d1798 -r 1ad0612823e9 AM2303.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/AM2303.h Mon Oct 13 14:18:58 2014 +0000 @@ -0,0 +1,106 @@ +/* Copyright (c) 2014 Shigenori Inoue, MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef __AM2303__ +#define __AM2303__ +#include "mbed.h" + +/** Example: + * @code + * #include "mbed.h" + * #include "AM2303.h" + * + * AM2303 d; + * + * main() + * { + * int s; + * s = h.readData(); + * if (s != AM2303::OK) { + * printf("Error!\r\n"); + * } + * else { + * printf("T:%f, H:%f\r\n", h.readTemperature(), h.readHumidity()); + * } + * } + * @endcode + */ + +class AM2303 +{ +public: + /** Create a AM2303 interface + * @param pin 1-wire-like serial I/O port of AM2303 + */ + AM2303(PinName pin); + ~AM2303(); + + /** Reading the data from the AM2303 + * @return Error code + * 0: OK. + * 1: Reading the data too often. + * 2: 1-wire bus is busy. + * 3: AM2303 does not respond. + * 4: AM2303 is not ready. + * 5: Checksum is incorrect. + * 6: Timeout. + */ + int readData(void); + + /** Reading the humidity from the data + * @return Humidity in %, + * regardless of the error from readData() + */ + float readHumidity(void); + + /** Reading the temperature from the data + * @return Temperature in Celcius, + * regardless of the error from readData() + */ + float readTemperature(void); + + enum ErrorAM2303 { + OK = 0, + READ_TOO_OFTEN = 1, + BUS_BUSY = 2, + NOT_PRESENT = 3, + NOT_READY = 4, + CHKSUM_ERR = 5, + WATCHDOG_ERR = 6, + }; + uint64_t data; + +private: + DigitalInOut io; + InterruptIn io_irq; + Timer t; + uint32_t t_pulse_us; + const static int t_tol_start; + const static int t_tol_pulse; + bool first_time; + /* uint64_t data; */ + uint32_t chksum; + uint32_t cnt; + uint32_t wdt; + bool eod; + void init(void); + void pos_edge(void); + void neg_edge(void); +}; + +#endif \ No newline at end of file
diff -r e91c151d1798 -r 1ad0612823e9 DHT11.cpp --- a/DHT11.cpp Thu Sep 25 14:13:10 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,192 +0,0 @@ -/* Copyright (c) 2014 Shigenori Inoue, MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, - * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#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(); - t.start(); - first_time = true; -} - -// Destructor -DHT11::~DHT11(void) {} - -// Constants -const int DHT11::t_tol_start = 2; -const int DHT11::t_tol_pulse = 10; - -// Reading the data bits from the DHT11 -int DHT11::readData(void) -{ - // Checking the measurement frequency - if (t.read_ms() < 2000 && first_time == false) { - t.reset(); - return READ_TOO_OFTEN; - } - - // Initialize - init(); - - // Checking the data bus - if (io == 0) { - t.reset(); - return BUS_BUSY; - } - - // Sending start signal, low signal for around 10 ms - t.reset(); - io.output(); - io = 0; - do { - } while (t.read_ms() < 20 + t_tol_start); - io.input(); - io = 1; - - - // Waiting for the start of the response signal - t.reset(); - do { - if (t.read_us() > 100) { - t.reset(); - return NOT_PRESENT; - } - } while (io == 1); - - // Wainting for the start of the ready signal - t.reset(); - do { - if (t.read_us() > 100) { - t.reset(); - return NOT_READY; - } - } while (io == 0); - - // Wainting for the end of the ready signal - t.reset(); - do { - if (t.read_us() > 100) { - t.reset(); - return WATCHDOG_ERR; - } - } while (io == 1); - - // Starting the pulse width sensing - // by the use of interruptions - io_irq.enable_irq(); - - do { - wait_us(100); - if (wdt > 50) { - t.reset(); - 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)) { - t.reset(); - return CHKSUM_ERR; - } else { - t.reset(); - first_time = false; - return OK; - } -} - -// Extracting humidity data from the received data -int DHT11::readHumidity(void) -{ - return (data & 0xff00000000) >> 32; -} - -// Extracting temperature data from the received data -int DHT11::readTemperature(void) -{ - return (data & 0x0000ff0000) >> 16; -} - -// Initialization of variables -void DHT11::init(void) -{ - t_pulse_us = 0; - data = 0; - chksum = 0; - cnt = 0; - wdt = 0; - eod = false; - t.reset(); -} - -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 positive pulse width - t_pulse_us = t.read_us(); - - // Detecting 0 if the pulse width ranges around 25 us - if (25 - t_tol_pulse <= t_pulse_us && t_pulse_us <= 30 + t_tol_pulse) { - // 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 70 us - else if (70 - t_tol_pulse <= t_pulse_us && t_pulse_us <= 70 + t_tol_pulse) { - // 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
diff -r e91c151d1798 -r 1ad0612823e9 DHT11.h --- a/DHT11.h Thu Sep 25 14:13:10 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,105 +0,0 @@ -/* Copyright (c) 2014 Shigenori Inoue, MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, - * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#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 != DHT11::OK) { - * 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 - * @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. - */ - int readData(void); - - /** Reading the humidity from the data - * @return Humidity in %, - * regardless of the error from readData() - */ - int readHumidity(void); - - /** Reading the temperature from the data - * @return Temperature in Celcius, - * regardless of the error from readData() - */ - int readTemperature(void); - - enum ErrorDHT11 { - OK = 0, - READ_TOO_OFTEN = 1, - BUS_BUSY = 2, - NOT_PRESENT = 3, - NOT_READY = 4, - CHKSUM_ERR = 5, - WATCHDOG_ERR = 6, - }; - -private: - DigitalInOut io; - InterruptIn io_irq; - Timer t; - uint32_t t_pulse_us; - const static int t_tol_start; - const static int t_tol_pulse; - bool first_time; - uint64_t data; - uint32_t chksum; - uint32_t cnt; - uint32_t wdt; - bool eod; - void init(void); - void pos_edge(void); - void neg_edge(void); -}; - -#endif \ No newline at end of file