1
1
//
2
2
// FILE: dht.cpp
3
3
// AUTHOR: Rob Tillaart
4
- // VERSION: 0.1.14
4
+ // VERSION: 0.1.15
5
5
// PURPOSE: DHT Temperature & Humidity Sensor library for Arduino
6
6
// URL: http://arduino.cc/playground/Main/DHTLib
7
7
//
8
8
// HISTORY:
9
+ // 0.1.15 reduced # micros calls 2->1 in inner loop.
9
10
// 0.1.14 replace digital read with faster (~3x) code => more robust low MHz machines.
10
11
// 0.1.13 fix negative temperature
11
12
// 0.1.12 support DHT33 and DHT44 initial version
@@ -44,8 +45,8 @@ int dht::read11(uint8_t pin)
44
45
int rv = _readSensor (pin, DHTLIB_DHT11_WAKEUP);
45
46
if (rv != DHTLIB_OK)
46
47
{
47
- humidity = DHTLIB_INVALID_VALUE; // invalid value, or is NaN prefered?
48
- temperature = DHTLIB_INVALID_VALUE; // invalid value
48
+ humidity = DHTLIB_INVALID_VALUE;
49
+ temperature = DHTLIB_INVALID_VALUE;
49
50
return rv;
50
51
}
51
52
@@ -56,8 +57,10 @@ int dht::read11(uint8_t pin)
56
57
// TEST CHECKSUM
57
58
// bits[1] && bits[3] both 0
58
59
uint8_t sum = bits[0 ] + bits[2 ];
59
- if (bits[4 ] != sum) return DHTLIB_ERROR_CHECKSUM;
60
-
60
+ if (bits[4 ] != sum)
61
+ {
62
+ return DHTLIB_ERROR_CHECKSUM;
63
+ }
61
64
return DHTLIB_OK;
62
65
}
63
66
@@ -111,61 +114,75 @@ int dht::_readSensor(uint8_t pin, uint8_t wakeupDelay)
111
114
// replace digitalRead() with Direct Port Reads.
112
115
// reduces footprint ~100 bytes => portability issue?
113
116
// direct port read is about 3x faster
114
- uint8_t bit = digitalPinToBitMask (pin);
115
- uint8_t port = digitalPinToPort (pin);
117
+ uint8_t bit = digitalPinToBitMask (pin);
118
+ uint8_t port = digitalPinToPort (pin);
116
119
volatile uint8_t *PIR = portInputRegister (port);
117
120
118
121
// EMPTY BUFFER
119
122
for (uint8_t i = 0 ; i < 5 ; i++) bits[i] = 0 ;
120
123
121
124
// REQUEST SAMPLE
122
125
pinMode (pin, OUTPUT);
123
- digitalWrite (pin, LOW); // T-be
126
+ digitalWrite (pin, LOW); // T-be
124
127
delay (wakeupDelay);
125
- digitalWrite (pin, HIGH); // T-go
126
- delayMicroseconds (40 );
128
+ digitalWrite (pin, HIGH); // T-go
127
129
pinMode (pin, INPUT);
128
130
131
+ uint16_t loopCount = DHTLIB_TIMEOUT*2 ; // 200uSec max
132
+ // while(digitalRead(pin) == HIGH)
133
+ while ((*PIR & bit) != LOW )
134
+ {
135
+ if (--loopCount == 0 ) return DHTLIB_ERROR_TIMEOUT;
136
+ }
137
+
129
138
// GET ACKNOWLEDGE or TIMEOUT
130
- uint16_t loopCntLOW = DHTLIB_TIMEOUT;
139
+ loopCount = DHTLIB_TIMEOUT;
140
+ // while(digitalRead(pin) == LOW)
131
141
while ((*PIR & bit) == LOW ) // T-rel
132
142
{
133
- if (--loopCntLOW == 0 ) return DHTLIB_ERROR_TIMEOUT;
143
+ if (--loopCount == 0 ) return DHTLIB_ERROR_TIMEOUT;
134
144
}
135
145
136
- uint16_t loopCntHIGH = DHTLIB_TIMEOUT;
146
+ loopCount = DHTLIB_TIMEOUT;
147
+ // while(digitalRead(pin) == HIGH)
137
148
while ((*PIR & bit) != LOW ) // T-reh
138
149
{
139
- if (--loopCntHIGH == 0 ) return DHTLIB_ERROR_TIMEOUT;
150
+ if (--loopCount == 0 ) return DHTLIB_ERROR_TIMEOUT;
140
151
}
141
152
153
+ uint8_t state = LOW;
154
+ uint8_t pstate = LOW;
155
+ loopCount = DHTLIB_TIMEOUT;
156
+ uint32_t t1 = micros ();
157
+
142
158
// READ THE OUTPUT - 40 BITS => 5 BYTES
143
- for (uint8_t i = 40 ; i != 0 ; i-- )
159
+ for (uint8_t i = 40 ; i != 0 ; )
144
160
{
145
- loopCntLOW = DHTLIB_TIMEOUT;
146
- while ((*PIR & bit) == LOW )
147
- {
148
- if (--loopCntLOW == 0 ) return DHTLIB_ERROR_TIMEOUT;
149
- }
150
-
151
- uint32_t t = micros ();
152
-
153
- loopCntHIGH = DHTLIB_TIMEOUT;
154
- while ((*PIR & bit) != LOW )
155
- {
156
- if (--loopCntHIGH == 0 ) return DHTLIB_ERROR_TIMEOUT;
157
- }
158
-
159
- if ((micros () - t) > 40 )
160
- {
161
- bits[idx] |= mask;
162
- }
163
- mask >>= 1 ;
164
- if (mask == 0 ) // next byte?
161
+ // WAIT FOR FALLING EDGE
162
+ state = (*PIR & bit);
163
+ if (state == LOW && pstate != LOW)
165
164
{
166
- mask = 128 ;
167
- idx++;
165
+ uint32_t t2 = micros ();
166
+ if ((t2-t1) > 100 ) // long -> one
167
+ {
168
+ bits[idx] |= mask;
169
+ }
170
+ mask >>= 1 ;
171
+ if (mask == 0 ) // next byte
172
+ {
173
+ mask = 128 ;
174
+ idx++;
175
+ }
176
+ // next bit
177
+ --i;
178
+ // update time admin
179
+ t1 = t2;
180
+ // reset timeout flag
181
+ loopCount = DHTLIB_TIMEOUT;
168
182
}
183
+ pstate = state;
184
+ // Check timeout
185
+ if (--loopCount == 0 ) return DHTLIB_ERROR_TIMEOUT;
169
186
}
170
187
pinMode (pin, OUTPUT);
171
188
digitalWrite (pin, HIGH);
0 commit comments