Plantilla para crear la libreria DHT para la plataforma FRDM
DHT22.cpp@1:5b20ff4fd227, 2011-07-04 (annotated)
- Committer:
- hwkit
- Date:
- Mon Jul 04 07:35:03 2011 +0000
- Revision:
- 1:5b20ff4fd227
- Parent:
- 0:547e68daeb1b
- Child:
- 2:340957cc8fef
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
hwkit | 0:547e68daeb1b | 1 | /* |
hwkit | 0:547e68daeb1b | 2 | DHT22.cpp - DHT22 sensor library |
hwkit | 0:547e68daeb1b | 3 | Developed by Ben Adams = 2011 |
hwkit | 0:547e68daeb1b | 4 | |
hwkit | 0:547e68daeb1b | 5 | This library is free software; you can redistribute it and / or |
hwkit | 0:547e68daeb1b | 6 | modify it under the terms of the GNU Leser General Public |
hwkit | 0:547e68daeb1b | 7 | License as published by the Free Software Foundation; either |
hwkit | 0:547e68daeb1b | 8 | version 2.1 of the License, or (at your option) any later version. |
hwkit | 0:547e68daeb1b | 9 | |
hwkit | 0:547e68daeb1b | 10 | This library is distributed in the hope that it will be useful, |
hwkit | 0:547e68daeb1b | 11 | but WITHOUT ANY WARRENTY; without even the implied warranty of |
hwkit | 0:547e68daeb1b | 12 | MERCHANTABILITY or FITNESS FOR A PATRICULAR PURPOSE. See the GNU |
hwkit | 0:547e68daeb1b | 13 | Lesser General Public License for more details. |
hwkit | 0:547e68daeb1b | 14 | |
hwkit | 0:547e68daeb1b | 15 | You should have received a copy of the GNU Lesser General Public |
hwkit | 0:547e68daeb1b | 16 | License along with this library; if not, write to the Free Software |
hwkit | 0:547e68daeb1b | 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
hwkit | 0:547e68daeb1b | 18 | |
hwkit | 0:547e68daeb1b | 19 | |
hwkit | 0:547e68daeb1b | 20 | Humidity and Temperature Sensor DHT22 info found at |
hwkit | 0:547e68daeb1b | 21 | http://www.sparkfun.com/products/10167 |
hwkit | 0:547e68daeb1b | 22 | |
hwkit | 0:547e68daeb1b | 23 | Version 0.4: 24-Jan-2011 by Ben Adams |
hwkit | 0:547e68daeb1b | 24 | Added return code constants to keywords.txt |
hwkit | 0:547e68daeb1b | 25 | Return DHT_ERROR_CHECKSUM on check sum mismatch |
hwkit | 0:547e68daeb1b | 26 | |
hwkit | 0:547e68daeb1b | 27 | Version 0.3: 17-Jan-2011 by Ben Adams |
hwkit | 0:547e68daeb1b | 28 | This version reads data |
hwkit | 0:547e68daeb1b | 29 | Needs check sum code added at the end of readData |
hwkit | 0:547e68daeb1b | 30 | |
hwkit | 0:547e68daeb1b | 31 | Version 0.2: 16-Jan-2011 by Ben Adams |
hwkit | 0:547e68daeb1b | 32 | Changed coding style to match other Arduino Libraries. |
hwkit | 0:547e68daeb1b | 33 | This version will not read data either! |
hwkit | 0:547e68daeb1b | 34 | |
hwkit | 0:547e68daeb1b | 35 | */ |
hwkit | 0:547e68daeb1b | 36 | |
hwkit | 0:547e68daeb1b | 37 | #include "DHT22.h" |
hwkit | 0:547e68daeb1b | 38 | |
hwkit | 1:5b20ff4fd227 | 39 | |
hwkit | 0:547e68daeb1b | 40 | // This should be 40, but the sensor is adding an extra bit at the start |
hwkit | 0:547e68daeb1b | 41 | #define DHT22_DATA_BIT_COUNT 41 |
hwkit | 0:547e68daeb1b | 42 | |
hwkit | 1:5b20ff4fd227 | 43 | Serial pc(USBTX, USBRX); // Tx, Rx Using USB Virtual Serial Port |
hwkit | 1:5b20ff4fd227 | 44 | // Read Data From /etc/ttyACM* (linux port) |
hwkit | 1:5b20ff4fd227 | 45 | |
hwkit | 0:547e68daeb1b | 46 | DHT22::DHT22(PinName Data) { |
hwkit | 0:547e68daeb1b | 47 | _data = Data; // Set Data Pin |
hwkit | 1:5b20ff4fd227 | 48 | _lastReadTime = time(NULL); |
hwkit | 0:547e68daeb1b | 49 | _lastHumidity = 0; |
hwkit | 0:547e68daeb1b | 50 | _lastTemperature = DHT22_ERROR_VALUE; |
hwkit | 0:547e68daeb1b | 51 | } |
hwkit | 0:547e68daeb1b | 52 | |
hwkit | 0:547e68daeb1b | 53 | DHT22::~DHT22() { |
hwkit | 0:547e68daeb1b | 54 | } |
hwkit | 0:547e68daeb1b | 55 | |
hwkit | 0:547e68daeb1b | 56 | DHT22_ERROR DHT22::readData() { |
hwkit | 0:547e68daeb1b | 57 | int i, retryCount; |
hwkit | 1:5b20ff4fd227 | 58 | int currentTemperature=0; |
hwkit | 1:5b20ff4fd227 | 59 | int currentHumidity=0; |
hwkit | 1:5b20ff4fd227 | 60 | unsigned int checkSum = 0, csPart1, csPart2, csPart3, csPart4; |
hwkit | 0:547e68daeb1b | 61 | unsigned int bitTimes[DHT22_DATA_BIT_COUNT]; |
hwkit | 1:5b20ff4fd227 | 62 | time_t currentTime = time(NULL); |
hwkit | 0:547e68daeb1b | 63 | |
hwkit | 0:547e68daeb1b | 64 | DigitalInOut DATA(_data); |
hwkit | 0:547e68daeb1b | 65 | |
hwkit | 1:5b20ff4fd227 | 66 | |
hwkit | 0:547e68daeb1b | 67 | for (i = 0; i < DHT22_DATA_BIT_COUNT; i++) { |
hwkit | 0:547e68daeb1b | 68 | bitTimes[i] = 0; |
hwkit | 0:547e68daeb1b | 69 | } |
hwkit | 1:5b20ff4fd227 | 70 | |
hwkit | 0:547e68daeb1b | 71 | if (currentTime - _lastReadTime < 2) { |
hwkit | 1:5b20ff4fd227 | 72 | // Caller needs to wait 2 seconds between each call to read Data |
hwkit | 1:5b20ff4fd227 | 73 | pc.printf("Current Time: %s\n",currentTime); |
hwkit | 1:5b20ff4fd227 | 74 | pc.printf("Last Read Time: %s\n", _lastReadTime); |
hwkit | 0:547e68daeb1b | 75 | return DHT_ERROR_TOOQUICK; |
hwkit | 0:547e68daeb1b | 76 | } |
hwkit | 0:547e68daeb1b | 77 | _lastReadTime = currentTime; |
hwkit | 0:547e68daeb1b | 78 | retryCount = 0; |
hwkit | 0:547e68daeb1b | 79 | // Pin needs to start HIGH, wait unit it is HIGH with a timeout |
hwkit | 0:547e68daeb1b | 80 | do { |
hwkit | 0:547e68daeb1b | 81 | if (retryCount > 125) { |
hwkit | 0:547e68daeb1b | 82 | return DHT_BUS_HUNG; |
hwkit | 0:547e68daeb1b | 83 | } |
hwkit | 0:547e68daeb1b | 84 | retryCount ++; |
hwkit | 0:547e68daeb1b | 85 | wait_us(2); |
hwkit | 0:547e68daeb1b | 86 | } while (DATA==1); |
hwkit | 0:547e68daeb1b | 87 | // Send the activate pulse |
hwkit | 0:547e68daeb1b | 88 | DATA = 0; // MCU send out start signal to DHT22 |
hwkit | 0:547e68daeb1b | 89 | wait_us(1100); // 1.1 ms |
hwkit | 0:547e68daeb1b | 90 | // Find the start of the ACK Pulse |
hwkit | 0:547e68daeb1b | 91 | retryCount = 0; |
hwkit | 0:547e68daeb1b | 92 | do { |
hwkit | 0:547e68daeb1b | 93 | if (retryCount > 25) {// (Spec is 20 to 40 us, 25*2 == 50us |
hwkit | 0:547e68daeb1b | 94 | return DHT_ERROR_NOT_PRESENT; |
hwkit | 0:547e68daeb1b | 95 | } |
hwkit | 0:547e68daeb1b | 96 | retryCount ++; |
hwkit | 0:547e68daeb1b | 97 | wait_us(2); |
hwkit | 0:547e68daeb1b | 98 | } while (DATA==1); |
hwkit | 0:547e68daeb1b | 99 | // Find the end of the ACK Pulse |
hwkit | 0:547e68daeb1b | 100 | retryCount = 0; |
hwkit | 0:547e68daeb1b | 101 | do { |
hwkit | 0:547e68daeb1b | 102 | if (retryCount > 50) {// (Spec is 80 us, 50 * 2 == 100us) |
hwkit | 0:547e68daeb1b | 103 | return DHT_ERROR_ACK_TOO_LONG; |
hwkit | 0:547e68daeb1b | 104 | } |
hwkit | 0:547e68daeb1b | 105 | retryCount++; |
hwkit | 0:547e68daeb1b | 106 | wait_us(2); |
hwkit | 0:547e68daeb1b | 107 | } while (DATA==0); |
hwkit | 0:547e68daeb1b | 108 | // Read the 40 bit data stream |
hwkit | 0:547e68daeb1b | 109 | for (i=0; i < DHT22_DATA_BIT_COUNT; i++) { |
hwkit | 0:547e68daeb1b | 110 | retryCount = 0; |
hwkit | 0:547e68daeb1b | 111 | do { |
hwkit | 0:547e68daeb1b | 112 | if (retryCount > 35) { // spec is 50 u, 35*2 = 70 us |
hwkit | 0:547e68daeb1b | 113 | return DHT_ERROR_SYNC_TIMEOUT; |
hwkit | 0:547e68daeb1b | 114 | } |
hwkit | 0:547e68daeb1b | 115 | retryCount ++; |
hwkit | 0:547e68daeb1b | 116 | wait_us(2); |
hwkit | 0:547e68daeb1b | 117 | } while (DATA==1); |
hwkit | 0:547e68daeb1b | 118 | // Measure the width of the data pulse |
hwkit | 0:547e68daeb1b | 119 | retryCount = 0; |
hwkit | 0:547e68daeb1b | 120 | do { |
hwkit | 0:547e68daeb1b | 121 | if (retryCount > 50) { // spec is 80us, 50*2 == 100us |
hwkit | 0:547e68daeb1b | 122 | return DHT_ERROR_DATA_TIMEOUT; |
hwkit | 0:547e68daeb1b | 123 | } |
hwkit | 0:547e68daeb1b | 124 | retryCount++; |
hwkit | 0:547e68daeb1b | 125 | wait_us(2); |
hwkit | 0:547e68daeb1b | 126 | } while (DATA==0); |
hwkit | 0:547e68daeb1b | 127 | bitTimes[i] = retryCount; |
hwkit | 0:547e68daeb1b | 128 | } |
hwkit | 0:547e68daeb1b | 129 | |
hwkit | 0:547e68daeb1b | 130 | // Now bitTimes have the number of retries (us *2) |
hwkit | 0:547e68daeb1b | 131 | // that were needed to find the end of each data bit |
hwkit | 0:547e68daeb1b | 132 | // Spec: 0 is 26 to 28 us |
hwkit | 0:547e68daeb1b | 133 | // Spec: 1 is 70 us |
hwkit | 0:547e68daeb1b | 134 | // bitTimes[x] <= 11 is a 0 |
hwkit | 0:547e68daeb1b | 135 | // bitTimes[x] > 11 is a 1 |
hwkit | 0:547e68daeb1b | 136 | // Note: the bits are offset by one from the data sheet, not sure why |
hwkit | 0:547e68daeb1b | 137 | for (i=0; i<16; i++) { |
hwkit | 0:547e68daeb1b | 138 | if (bitTimes[i+1] > 11) { |
hwkit | 0:547e68daeb1b | 139 | currentHumidity |= ( 1 << (15-i)); |
hwkit | 0:547e68daeb1b | 140 | } |
hwkit | 0:547e68daeb1b | 141 | } |
hwkit | 0:547e68daeb1b | 142 | |
hwkit | 0:547e68daeb1b | 143 | for (i=0; i<16; i ++) { |
hwkit | 0:547e68daeb1b | 144 | if (bitTimes[i+17] > 11) { |
hwkit | 0:547e68daeb1b | 145 | currentTemperature |= (1 <<(15-i)); |
hwkit | 0:547e68daeb1b | 146 | } |
hwkit | 0:547e68daeb1b | 147 | } |
hwkit | 0:547e68daeb1b | 148 | |
hwkit | 0:547e68daeb1b | 149 | for (i=0; i<8; i++) { |
hwkit | 0:547e68daeb1b | 150 | if (bitTimes[i+33]>11) { |
hwkit | 0:547e68daeb1b | 151 | checkSum |= (1 << (7-i)); |
hwkit | 0:547e68daeb1b | 152 | } |
hwkit | 0:547e68daeb1b | 153 | } |
hwkit | 0:547e68daeb1b | 154 | _lastHumidity = (float(currentHumidity & 0x7FFF) / 10.0); |
hwkit | 0:547e68daeb1b | 155 | if (currentTemperature &= 0x8000) { |
hwkit | 0:547e68daeb1b | 156 | currentTemperature &= 0x7FFF; |
hwkit | 0:547e68daeb1b | 157 | _lastTemperature = (float(currentTemperature) / 10.0) * -1.0; |
hwkit | 0:547e68daeb1b | 158 | } else { |
hwkit | 0:547e68daeb1b | 159 | _lastTemperature = float(currentTemperature) / 10.0; |
hwkit | 0:547e68daeb1b | 160 | } |
hwkit | 0:547e68daeb1b | 161 | |
hwkit | 0:547e68daeb1b | 162 | // Calculate Check Sum |
hwkit | 0:547e68daeb1b | 163 | csPart1 = currentHumidity >> 8; |
hwkit | 0:547e68daeb1b | 164 | csPart2 = currentHumidity & 0xFF; |
hwkit | 0:547e68daeb1b | 165 | csPart3 = currentTemperature >> 8; |
hwkit | 0:547e68daeb1b | 166 | csPart4 = currentTemperature & 0xFF; |
hwkit | 0:547e68daeb1b | 167 | if (checkSum == ((csPart1 + csPart2 + csPart3 + csPart4) & 0xFF)) { |
hwkit | 0:547e68daeb1b | 168 | return DHT_ERROR_NONE; |
hwkit | 0:547e68daeb1b | 169 | } |
hwkit | 0:547e68daeb1b | 170 | return DHT_ERROR_CHECKSUM; |
hwkit | 0:547e68daeb1b | 171 | } |
hwkit | 0:547e68daeb1b | 172 | |
hwkit | 0:547e68daeb1b | 173 | float DHT22::getTemperatureC() { |
hwkit | 0:547e68daeb1b | 174 | return _lastTemperature; |
hwkit | 0:547e68daeb1b | 175 | } |
hwkit | 0:547e68daeb1b | 176 | |
hwkit | 0:547e68daeb1b | 177 | float DHT22::getHumidity() { |
hwkit | 0:547e68daeb1b | 178 | return _lastHumidity; |
hwkit | 0:547e68daeb1b | 179 | } |