The code from https://github.com/vpcola/Nucleo
DHT/DHT.cpp@0:5464d5e415e5, 2014-10-08 (annotated)
- Committer:
- sinrab
- Date:
- Wed Oct 08 11:00:24 2014 +0000
- Revision:
- 0:5464d5e415e5
The code from https://github.com/vpcola/Nucleo
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
sinrab | 0:5464d5e415e5 | 1 | #include "DHT.h" |
sinrab | 0:5464d5e415e5 | 2 | |
sinrab | 0:5464d5e415e5 | 3 | |
sinrab | 0:5464d5e415e5 | 4 | #define DHT_DATA_BIT_COUNT 41 |
sinrab | 0:5464d5e415e5 | 5 | |
sinrab | 0:5464d5e415e5 | 6 | DHT::DHT(PinName pin,int DHTtype) |
sinrab | 0:5464d5e415e5 | 7 | : _mutex() |
sinrab | 0:5464d5e415e5 | 8 | { |
sinrab | 0:5464d5e415e5 | 9 | _pin = pin; |
sinrab | 0:5464d5e415e5 | 10 | _DHTtype = DHTtype; |
sinrab | 0:5464d5e415e5 | 11 | _firsttime=true; |
sinrab | 0:5464d5e415e5 | 12 | } |
sinrab | 0:5464d5e415e5 | 13 | |
sinrab | 0:5464d5e415e5 | 14 | DHT::~DHT() { |
sinrab | 0:5464d5e415e5 | 15 | } |
sinrab | 0:5464d5e415e5 | 16 | |
sinrab | 0:5464d5e415e5 | 17 | int DHT::readData() |
sinrab | 0:5464d5e415e5 | 18 | { |
sinrab | 0:5464d5e415e5 | 19 | |
sinrab | 0:5464d5e415e5 | 20 | |
sinrab | 0:5464d5e415e5 | 21 | int err = ERROR_NONE; |
sinrab | 0:5464d5e415e5 | 22 | Timer tmr; |
sinrab | 0:5464d5e415e5 | 23 | |
sinrab | 0:5464d5e415e5 | 24 | DigitalInOut data_pin(_pin); |
sinrab | 0:5464d5e415e5 | 25 | // We make sure we are the only ones |
sinrab | 0:5464d5e415e5 | 26 | // reading data right now. |
sinrab | 0:5464d5e415e5 | 27 | _mutex.lock(); |
sinrab | 0:5464d5e415e5 | 28 | |
sinrab | 0:5464d5e415e5 | 29 | // BUFFER TO RECEIVE |
sinrab | 0:5464d5e415e5 | 30 | uint8_t cnt = 7; |
sinrab | 0:5464d5e415e5 | 31 | uint8_t idx = 0; |
sinrab | 0:5464d5e415e5 | 32 | |
sinrab | 0:5464d5e415e5 | 33 | tmr.stop(); |
sinrab | 0:5464d5e415e5 | 34 | tmr.reset(); |
sinrab | 0:5464d5e415e5 | 35 | |
sinrab | 0:5464d5e415e5 | 36 | // EMPTY BUFFER |
sinrab | 0:5464d5e415e5 | 37 | for(int i=0; i< 5; i++) DHT_data[i] = 0; |
sinrab | 0:5464d5e415e5 | 38 | |
sinrab | 0:5464d5e415e5 | 39 | // REQUEST SAMPLE |
sinrab | 0:5464d5e415e5 | 40 | data_pin.output(); |
sinrab | 0:5464d5e415e5 | 41 | data_pin.write(0); |
sinrab | 0:5464d5e415e5 | 42 | wait_ms(18); |
sinrab | 0:5464d5e415e5 | 43 | data_pin.write(1); |
sinrab | 0:5464d5e415e5 | 44 | wait_us(40); |
sinrab | 0:5464d5e415e5 | 45 | data_pin.input(); |
sinrab | 0:5464d5e415e5 | 46 | |
sinrab | 0:5464d5e415e5 | 47 | // ACKNOWLEDGE or TIMEOUT |
sinrab | 0:5464d5e415e5 | 48 | unsigned int loopCnt = 10000; |
sinrab | 0:5464d5e415e5 | 49 | |
sinrab | 0:5464d5e415e5 | 50 | while(!data_pin.read())if(!loopCnt--) |
sinrab | 0:5464d5e415e5 | 51 | { |
sinrab | 0:5464d5e415e5 | 52 | _mutex.unlock(); |
sinrab | 0:5464d5e415e5 | 53 | return ERROR_DATA_TIMEOUT; |
sinrab | 0:5464d5e415e5 | 54 | } |
sinrab | 0:5464d5e415e5 | 55 | |
sinrab | 0:5464d5e415e5 | 56 | loopCnt = 10000; |
sinrab | 0:5464d5e415e5 | 57 | |
sinrab | 0:5464d5e415e5 | 58 | while(data_pin.read())if(!loopCnt--) |
sinrab | 0:5464d5e415e5 | 59 | { |
sinrab | 0:5464d5e415e5 | 60 | _mutex.unlock(); |
sinrab | 0:5464d5e415e5 | 61 | return ERROR_DATA_TIMEOUT; |
sinrab | 0:5464d5e415e5 | 62 | } |
sinrab | 0:5464d5e415e5 | 63 | |
sinrab | 0:5464d5e415e5 | 64 | // READ OUTPUT - 40 BITS => 5 BYTES or TIMEOUT |
sinrab | 0:5464d5e415e5 | 65 | for(int i=0; i<40; i++){ |
sinrab | 0:5464d5e415e5 | 66 | |
sinrab | 0:5464d5e415e5 | 67 | loopCnt = 10000; |
sinrab | 0:5464d5e415e5 | 68 | |
sinrab | 0:5464d5e415e5 | 69 | while(!data_pin.read())if(loopCnt-- == 0) |
sinrab | 0:5464d5e415e5 | 70 | { |
sinrab | 0:5464d5e415e5 | 71 | _mutex.unlock(); |
sinrab | 0:5464d5e415e5 | 72 | return ERROR_DATA_TIMEOUT; |
sinrab | 0:5464d5e415e5 | 73 | } |
sinrab | 0:5464d5e415e5 | 74 | |
sinrab | 0:5464d5e415e5 | 75 | //unsigned long t = micros(); |
sinrab | 0:5464d5e415e5 | 76 | tmr.start(); |
sinrab | 0:5464d5e415e5 | 77 | |
sinrab | 0:5464d5e415e5 | 78 | loopCnt = 10000; |
sinrab | 0:5464d5e415e5 | 79 | |
sinrab | 0:5464d5e415e5 | 80 | while(data_pin.read())if(!loopCnt--) |
sinrab | 0:5464d5e415e5 | 81 | { |
sinrab | 0:5464d5e415e5 | 82 | _mutex.unlock(); |
sinrab | 0:5464d5e415e5 | 83 | return ERROR_DATA_TIMEOUT; |
sinrab | 0:5464d5e415e5 | 84 | } |
sinrab | 0:5464d5e415e5 | 85 | |
sinrab | 0:5464d5e415e5 | 86 | if(tmr.read_us() > 40) DHT_data[idx] |= (1 << cnt); |
sinrab | 0:5464d5e415e5 | 87 | |
sinrab | 0:5464d5e415e5 | 88 | tmr.stop(); |
sinrab | 0:5464d5e415e5 | 89 | tmr.reset(); |
sinrab | 0:5464d5e415e5 | 90 | |
sinrab | 0:5464d5e415e5 | 91 | if(cnt == 0){ // next byte? |
sinrab | 0:5464d5e415e5 | 92 | |
sinrab | 0:5464d5e415e5 | 93 | cnt = 7; // restart at MSB |
sinrab | 0:5464d5e415e5 | 94 | idx++; // next byte! |
sinrab | 0:5464d5e415e5 | 95 | |
sinrab | 0:5464d5e415e5 | 96 | }else cnt--; |
sinrab | 0:5464d5e415e5 | 97 | |
sinrab | 0:5464d5e415e5 | 98 | } |
sinrab | 0:5464d5e415e5 | 99 | |
sinrab | 0:5464d5e415e5 | 100 | // WRITE TO RIGHT VARS |
sinrab | 0:5464d5e415e5 | 101 | uint8_t sum = (DHT_data[0] + DHT_data[1] + DHT_data[2] + DHT_data[3]) & 0xFF; |
sinrab | 0:5464d5e415e5 | 102 | |
sinrab | 0:5464d5e415e5 | 103 | if(DHT_data[4] != sum) |
sinrab | 0:5464d5e415e5 | 104 | { |
sinrab | 0:5464d5e415e5 | 105 | _mutex.unlock(); |
sinrab | 0:5464d5e415e5 | 106 | return ERROR_CHECKSUM; |
sinrab | 0:5464d5e415e5 | 107 | } |
sinrab | 0:5464d5e415e5 | 108 | |
sinrab | 0:5464d5e415e5 | 109 | _lastTemperature= CalcTemperature(); |
sinrab | 0:5464d5e415e5 | 110 | _lastHumidity= CalcHumidity(); |
sinrab | 0:5464d5e415e5 | 111 | |
sinrab | 0:5464d5e415e5 | 112 | _mutex.unlock(); |
sinrab | 0:5464d5e415e5 | 113 | return err; |
sinrab | 0:5464d5e415e5 | 114 | } |
sinrab | 0:5464d5e415e5 | 115 | |
sinrab | 0:5464d5e415e5 | 116 | |
sinrab | 0:5464d5e415e5 | 117 | float DHT::ReadHumidity() { |
sinrab | 0:5464d5e415e5 | 118 | return _lastHumidity; |
sinrab | 0:5464d5e415e5 | 119 | } |
sinrab | 0:5464d5e415e5 | 120 | |
sinrab | 0:5464d5e415e5 | 121 | float DHT::ConvertCelciustoFarenheit(float celsius) { |
sinrab | 0:5464d5e415e5 | 122 | return celsius * 9 / 5 + 32; |
sinrab | 0:5464d5e415e5 | 123 | } |
sinrab | 0:5464d5e415e5 | 124 | |
sinrab | 0:5464d5e415e5 | 125 | float DHT::ConvertCelciustoKelvin(float celsius) { |
sinrab | 0:5464d5e415e5 | 126 | return celsius + 273.15; |
sinrab | 0:5464d5e415e5 | 127 | } |
sinrab | 0:5464d5e415e5 | 128 | |
sinrab | 0:5464d5e415e5 | 129 | // dewPoint function NOAA |
sinrab | 0:5464d5e415e5 | 130 | // reference: http://wahiduddin.net/calc/density_algorithms.htm |
sinrab | 0:5464d5e415e5 | 131 | float DHT::CalcdewPoint(float celsius, float humidity) { |
sinrab | 0:5464d5e415e5 | 132 | float A0= 373.15/(273.15 + celsius); |
sinrab | 0:5464d5e415e5 | 133 | float SUM = -7.90298 * (A0-1); |
sinrab | 0:5464d5e415e5 | 134 | SUM += 5.02808 * log10(A0); |
sinrab | 0:5464d5e415e5 | 135 | SUM += -1.3816e-7 * (pow(10, (11.344*(1-1/A0)))-1) ; |
sinrab | 0:5464d5e415e5 | 136 | SUM += 8.1328e-3 * (pow(10,(-3.49149*(A0-1)))-1) ; |
sinrab | 0:5464d5e415e5 | 137 | SUM += log10(1013.246); |
sinrab | 0:5464d5e415e5 | 138 | float VP = pow(10, SUM-3) * humidity; |
sinrab | 0:5464d5e415e5 | 139 | float T = log(VP/0.61078); // temp var |
sinrab | 0:5464d5e415e5 | 140 | return (241.88 * T) / (17.558-T); |
sinrab | 0:5464d5e415e5 | 141 | } |
sinrab | 0:5464d5e415e5 | 142 | |
sinrab | 0:5464d5e415e5 | 143 | // delta max = 0.6544 wrt dewPoint() |
sinrab | 0:5464d5e415e5 | 144 | // 5x faster than dewPoint() |
sinrab | 0:5464d5e415e5 | 145 | // reference: http://en.wikipedia.org/wiki/Dew_point |
sinrab | 0:5464d5e415e5 | 146 | float DHT::CalcdewPointFast(float celsius, float humidity) |
sinrab | 0:5464d5e415e5 | 147 | { |
sinrab | 0:5464d5e415e5 | 148 | float a = 17.271; |
sinrab | 0:5464d5e415e5 | 149 | float b = 237.7; |
sinrab | 0:5464d5e415e5 | 150 | float temp = (a * celsius) / (b + celsius) + log(humidity/100); |
sinrab | 0:5464d5e415e5 | 151 | float Td = (b * temp) / (a - temp); |
sinrab | 0:5464d5e415e5 | 152 | return Td; |
sinrab | 0:5464d5e415e5 | 153 | } |
sinrab | 0:5464d5e415e5 | 154 | |
sinrab | 0:5464d5e415e5 | 155 | float DHT::ReadTemperature(eScale Scale) { |
sinrab | 0:5464d5e415e5 | 156 | if (Scale == FARENHEIT) |
sinrab | 0:5464d5e415e5 | 157 | return ConvertCelciustoFarenheit(_lastTemperature); |
sinrab | 0:5464d5e415e5 | 158 | else if (Scale == KELVIN) |
sinrab | 0:5464d5e415e5 | 159 | return ConvertCelciustoKelvin(_lastTemperature); |
sinrab | 0:5464d5e415e5 | 160 | else |
sinrab | 0:5464d5e415e5 | 161 | return _lastTemperature; |
sinrab | 0:5464d5e415e5 | 162 | } |
sinrab | 0:5464d5e415e5 | 163 | |
sinrab | 0:5464d5e415e5 | 164 | float DHT::CalcTemperature() { |
sinrab | 0:5464d5e415e5 | 165 | int v; |
sinrab | 0:5464d5e415e5 | 166 | |
sinrab | 0:5464d5e415e5 | 167 | switch (_DHTtype) { |
sinrab | 0:5464d5e415e5 | 168 | case DHT11: |
sinrab | 0:5464d5e415e5 | 169 | v = DHT_data[2]; |
sinrab | 0:5464d5e415e5 | 170 | return float(v); |
sinrab | 0:5464d5e415e5 | 171 | case DHT22: |
sinrab | 0:5464d5e415e5 | 172 | v = DHT_data[2] & 0x7F; |
sinrab | 0:5464d5e415e5 | 173 | v *= 256; |
sinrab | 0:5464d5e415e5 | 174 | v += DHT_data[3]; |
sinrab | 0:5464d5e415e5 | 175 | v /= 10; |
sinrab | 0:5464d5e415e5 | 176 | if (DHT_data[2] & 0x80) |
sinrab | 0:5464d5e415e5 | 177 | v *= -1; |
sinrab | 0:5464d5e415e5 | 178 | return float(v); |
sinrab | 0:5464d5e415e5 | 179 | } |
sinrab | 0:5464d5e415e5 | 180 | return 0; |
sinrab | 0:5464d5e415e5 | 181 | } |
sinrab | 0:5464d5e415e5 | 182 | |
sinrab | 0:5464d5e415e5 | 183 | float DHT::CalcHumidity() { |
sinrab | 0:5464d5e415e5 | 184 | int v; |
sinrab | 0:5464d5e415e5 | 185 | |
sinrab | 0:5464d5e415e5 | 186 | switch (_DHTtype) { |
sinrab | 0:5464d5e415e5 | 187 | case DHT11: |
sinrab | 0:5464d5e415e5 | 188 | v = DHT_data[0]; |
sinrab | 0:5464d5e415e5 | 189 | return float(v); |
sinrab | 0:5464d5e415e5 | 190 | case DHT22: |
sinrab | 0:5464d5e415e5 | 191 | v = DHT_data[0]; |
sinrab | 0:5464d5e415e5 | 192 | v *= 256; |
sinrab | 0:5464d5e415e5 | 193 | v += DHT_data[1]; |
sinrab | 0:5464d5e415e5 | 194 | v /= 10; |
sinrab | 0:5464d5e415e5 | 195 | return float(v); |
sinrab | 0:5464d5e415e5 | 196 | } |
sinrab | 0:5464d5e415e5 | 197 | return 0; |
sinrab | 0:5464d5e415e5 | 198 | } |
sinrab | 0:5464d5e415e5 | 199 | |
sinrab | 0:5464d5e415e5 | 200 |