1
+
1
2
/* *
2
3
* The MySensors Arduino library handles the wireless radio link and protocol
3
4
* between your home built sensors/actuators and HA controller of choice.
21
22
* REVISION HISTORY
22
23
* Version 1.0: Henrik EKblad
23
24
* Version 1.1 - 2016-07-20: Converted to MySensors v2.0 and added various improvements - Torben Woltjen (mozzbozz)
25
+ * Version 2.0 - 2018-09-25: Converted to DHTU Adafruit library
26
+ * Version 2.1 - 2018-10-06: Clearer code and... if something changed... every sensor data are sent to gateway
27
+ * Version 2.2 - 2018-12-27: Heat Index calculation included in sketch (based on Adafruit official library)
24
28
*
25
29
* DESCRIPTION
26
- * This sketch provides an example of how to implement a humidity/temperature
27
- * sensor using a DHT11/DHT-22.
30
+ * This sketch provides an example of how to implement a humidity/temperature sensor using a DHT11/DHT21/DHT22.
31
+ * It inlcudes Heat Index *sensor*
28
32
*
29
33
* For more information, please visit:
30
- * http://www.mysensors.org/build/humidity
34
+ * http://www.mysensors.org/build/TemperatureAndHumidity
31
35
*
32
36
*/
37
+ #define SN " TemperatureAndHumidity"
38
+ #define SV " 2.2"
39
+
40
+
33
41
34
42
// Enable debug prints
35
- #define MY_DEBUG
43
+ // #define MY_DEBUG
36
44
37
45
// Enable and select radio type attached
38
46
#define MY_RADIO_NRF24
39
47
// #define MY_RADIO_RFM69
40
48
// #define MY_RS485
41
-
42
- #include < SPI.h>
43
- #include < MySensors.h>
44
- #include < DHT.h>
45
49
46
- // Set this to the pin you connected the DHT's data pin to
47
- #define DHT_DATA_PIN 3
50
+ // Uncomment (and update) if you want to force Node Id
51
+ // #define MY_NODE_ID 1
52
+
53
+ #define MY_BAUD_RATE 38400
48
54
49
- // Set this offset if the sensor has a permanent small offset to the real temperatures.
50
- // In Celsius degrees (as measured by the device)
51
- #define SENSOR_TEMP_OFFSET 0
55
+ // Uncomment the type of sensor in use:
56
+ // #define DHTTYPE DHT11 // DHT 11
57
+ #define DHTTYPE DHT22 // DHT 22 (AM2302)
58
+ // #define DHTTYPE DHT21 // DHT 21 (AM2301)
52
59
53
- // Sleep time between sensor updates (in milliseconds)
54
- // Must be >1000ms for DHT22 and >2000ms for DHT11
55
- static const uint64_t UPDATE_INTERVAL = 60000 ;
60
+
61
+ // Set this to the pin you connected the DHT's data and power pins to; connect wires in coherent pins
62
+ #define DHTDATAPIN 3
63
+ #define DHTPOWERPIN 8
64
+
65
+
66
+ // Sleep time between sensor updates (in milliseconds) to add to sensor delay (read from sensor data; tipically: 1s)
67
+ static const uint64_t UPDATE_INTERVAL = 60000 ;
56
68
57
69
// Force sending an update of the temperature after n sensor reads, so a controller showing the
58
70
// timestamp of the last update doesn't show something like 3 hours in the unlikely case, that
@@ -62,95 +74,218 @@ static const uint8_t FORCE_UPDATE_N_READS = 10;
62
74
63
75
#define CHILD_ID_HUM 0
64
76
#define CHILD_ID_TEMP 1
77
+ #define CHILD_ID_TEMP_HI 2
78
+
79
+ // Set this offset if the sensors have permanent small offsets to the real temperatures/humidity.
80
+ // In Celsius degrees or moisture percent
81
+ #define SENSOR_HUM_OFFSET 0 // used for temperature data and heat index computation
82
+ #define SENSOR_TEMP_OFFSET 0 // used for humidity data
83
+ #define SENSOR_TEMP_HI_OFFSET 0 // used for heat index data
65
84
85
+
86
+
87
+ #include < MySensors.h>
88
+ #include < Adafruit_Sensor.h>
89
+ #include < DHT_U.h>
90
+
91
+ DHT_Unified dhtu (DHTDATAPIN, DHTTYPE);
92
+ // See guide for details on Adafruit sensor wiring and usage:
93
+ // https://learn.adafruit.com/dht/overview
94
+
95
+ uint32_t delayMS;
66
96
float lastTemp;
67
97
float lastHum;
68
- uint8_t nNoUpdatesTemp;
69
- uint8_t nNoUpdatesHum;
98
+ uint8_t nNoUpdates = FORCE_UPDATE_N_READS; // send data on start-up
70
99
bool metric = true ;
100
+ float temperature;
101
+ float humidity;
102
+ float temperatureHI;
103
+
104
+
71
105
72
106
MyMessage msgHum (CHILD_ID_HUM, V_HUM);
73
107
MyMessage msgTemp (CHILD_ID_TEMP, V_TEMP);
74
- DHT dht;
108
+ MyMessage msgTempHI (CHILD_ID_TEMP_HI, V_TEMP);
109
+
110
+
111
+
112
+ float computeHeatIndex (float temperature, float percentHumidity) {
113
+ // Based on Adafruit DHT official library (https://github.com/adafruit/DHT-sensor-library/blob/master/DHT.cpp)
114
+ // Using both Rothfusz and Steadman's equations
115
+ // http://www.wpc.ncep.noaa.gov/html/heatindex_equation.shtml
116
+
117
+ float hi;
118
+
119
+ temperature = temperature + SENSOR_TEMP_OFFSET; // include TEMP_OFFSET in HeatIndex computation too
120
+ temperature = 1.8 *temperature+32 ; // convertion to *F
121
+
122
+ hi = 0.5 * (temperature + 61.0 + ((temperature - 68.0 ) * 1.2 ) + (percentHumidity * 0.094 ));
123
+
124
+ if (hi > 79 ) {
125
+ hi = -42.379 +
126
+ 2.04901523 * temperature +
127
+ 10.14333127 * percentHumidity +
128
+ -0.22475541 * temperature*percentHumidity +
129
+ -0.00683783 * pow (temperature, 2 ) +
130
+ -0.05481717 * pow (percentHumidity, 2 ) +
131
+ 0.00122874 * pow (temperature, 2 ) * percentHumidity +
132
+ 0.00085282 * temperature*pow (percentHumidity, 2 ) +
133
+ -0.00000199 * pow (temperature, 2 ) * pow (percentHumidity, 2 );
134
+
135
+ if ((percentHumidity < 13 ) && (temperature >= 80.0 ) && (temperature <= 112.0 ))
136
+ hi -= ((13.0 - percentHumidity) * 0.25 ) * sqrt ((17.0 - abs (temperature - 95.0 )) * 0.05882 );
137
+
138
+ else if ((percentHumidity > 85.0 ) && (temperature >= 80.0 ) && (temperature <= 87.0 ))
139
+ hi += ((percentHumidity - 85.0 ) * 0.1 ) * ((87.0 - temperature) * 0.2 );
140
+ }
141
+
142
+ hi = (hi-32 )/1.8 ;
143
+ return hi; // return Heat Index, in *C
144
+ }
145
+
146
+
147
+
148
+
75
149
76
150
77
151
void presentation ()
78
152
{
79
153
// Send the sketch version information to the gateway
80
- sendSketchInfo (" TemperatureAndHumidity" , " 1.1" );
81
-
154
+ sendSketchInfo (SN, SV);
82
155
// Register all sensors to gw (they will be created as child devices)
83
- present (CHILD_ID_HUM, S_HUM);
84
- present (CHILD_ID_TEMP, S_TEMP);
85
-
156
+ present (CHILD_ID_HUM, S_HUM, " Umidity" );
157
+ wait (100 ); // to check: is it needed
158
+ present (CHILD_ID_TEMP, S_TEMP, " Temperature" );
159
+ wait (100 ); // to check: is it needed
160
+ present (CHILD_ID_TEMP_HI, S_TEMP, " Heat Index" );
86
161
metric = getControllerConfig ().isMetric ;
87
162
}
88
163
89
164
90
165
void setup ()
91
166
{
92
- dht.setup (DHT_DATA_PIN); // set data pin of DHT sensor
93
- if (UPDATE_INTERVAL <= dht.getMinimumSamplingPeriod ()) {
94
- Serial.println (" Warning: UPDATE_INTERVAL is smaller than supported by the sensor!" );
95
- }
96
- // Sleep for the time of the minimum sampling period to give the sensor time to power up
97
- // (otherwise, timeout errors might occure for the first reading)
98
- sleep (dht.getMinimumSamplingPeriod ());
167
+ pinMode (DHTPOWERPIN, OUTPUT);
168
+ digitalWrite (DHTPOWERPIN, HIGH);
169
+ // Serial.begin(9600);
170
+ // Initialize device.
171
+ dhtu.begin ();
172
+
173
+
174
+ Serial.println (" DHTxx Unified Sensor Example" );
175
+ // Print temperature sensor details.
176
+ sensor_t sensor;
177
+ dhtu.temperature ().getSensor (&sensor);
178
+ Serial.println (" ------------------------------------" );
179
+ Serial.println (" Temperature" );
180
+ Serial.print (" Sensor: " ); Serial.println (sensor.name );
181
+ Serial.print (" Driver Ver: " ); Serial.println (sensor.version );
182
+ Serial.print (" Unique ID: " ); Serial.println (sensor.sensor_id );
183
+ Serial.print (" Max Value: " ); Serial.print (sensor.max_value ); Serial.println (" *C" );
184
+ Serial.print (" Min Value: " ); Serial.print (sensor.min_value ); Serial.println (" *C" );
185
+ Serial.print (" Resolution: " ); Serial.print (sensor.resolution ); Serial.println (" *C" );
186
+ Serial.print (" Min Delay: " ); Serial.print (sensor.min_delay /1000 ); Serial.println (" ms" );
187
+ Serial.println (" ------------------------------------" );
188
+
189
+ // Print humidity sensor details.
190
+ dhtu.humidity ().getSensor (&sensor);
191
+ Serial.println (" ------------------------------------" );
192
+ Serial.println (" Humidity" );
193
+ Serial.print (" Sensor: " ); Serial.println (sensor.name );
194
+ Serial.print (" Driver Ver: " ); Serial.println (sensor.version );
195
+ Serial.print (" Unique ID: " ); Serial.println (sensor.sensor_id );
196
+ Serial.print (" Max Value: " ); Serial.print (sensor.max_value ); Serial.println (" %" );
197
+ Serial.print (" Min Value: " ); Serial.print (sensor.min_value ); Serial.println (" %" );
198
+ Serial.print (" Resolution: " ); Serial.print (sensor.resolution ); Serial.println (" %" );
199
+ Serial.print (" Min Delay: " ); Serial.print (sensor.min_delay /1000 ); Serial.println (" ms" );
200
+ Serial.println (" ------------------------------------" );
201
+ // Set delay between sensor readings based on sensor details.
202
+ delayMS = sensor.min_delay / 1000 ;
99
203
}
100
204
101
205
102
- void loop ()
103
- {
104
- // Force reading sensor, so it works also after sleep()
105
- dht.readSensor (true );
106
-
107
- // Get temperature from DHT library
108
- float temperature = dht.getTemperature ();
109
- if (isnan (temperature)) {
110
- Serial.println (" Failed reading temperature from DHT!" );
111
- } else if (temperature != lastTemp || nNoUpdatesTemp == FORCE_UPDATE_N_READS) {
112
- // Only send temperature if it changed since the last measurement or if we didn't send an update for n times
113
- lastTemp = temperature;
114
206
115
- // apply the offset before converting to something different than Celsius degrees
116
- temperature += SENSOR_TEMP_OFFSET;
117
207
118
- if (!metric) {
119
- temperature = dht.toFahrenheit (temperature);
120
- }
121
- // Reset no updates counter
122
- nNoUpdatesTemp = 0 ;
123
- send (msgTemp.set (temperature, 1 ));
124
208
209
+
210
+
211
+
212
+ void loop ()
213
+ {
214
+ digitalWrite (DHTPOWERPIN, HIGH);
215
+ delay (delayMS);
216
+ sensors_event_t event;
217
+ // Get temperature event and use its value.
218
+ dhtu.temperature ().getEvent (&event);
219
+ if (isnan (event.temperature )) {
220
+ Serial.println (" Error reading temperature!" );
221
+ }
222
+ else {
223
+ temperature = event.temperature ;
224
+ #ifdef MY_DEBUG
225
+ Serial.print (" Temperature: " );
226
+ Serial.print (temperature);
227
+ Serial.println (" *C" );
228
+ #endif
229
+ }
230
+
231
+ // Get humidity event and use its value.
232
+ dhtu.humidity ().getEvent (&event);
233
+ if (isnan (event.relative_humidity )) {
234
+ Serial.println (" Error reading humidity!" );
235
+ }
236
+ else {
237
+ humidity = event.relative_humidity ;
125
238
#ifdef MY_DEBUG
126
- Serial.print (" T: " );
127
- Serial.println (temperature);
239
+ Serial.print (" Humidity: " );
240
+ Serial.print (humidity);
241
+ Serial.println (" %" );
128
242
#endif
129
- } else {
130
- // Increase no update counter if the temperature stayed the same
131
- nNoUpdatesTemp++;
132
243
}
133
244
134
- // Get humidity from DHT library
135
- float humidity = dht.getHumidity ();
136
- if (isnan (humidity)) {
137
- Serial.println (" Failed reading humidity from DHT" );
138
- } else if (humidity != lastHum || nNoUpdatesHum == FORCE_UPDATE_N_READS) {
139
- // Only send humidity if it changed since the last measurement or if we didn't send an update for n times
245
+ if (fabs (humidity - lastHum)>=0.05 || fabs (temperature - lastTemp)>=0.05 || nNoUpdates >= FORCE_UPDATE_N_READS) {
246
+ lastTemp = temperature;
140
247
lastHum = humidity;
141
- // Reset no updates counter
142
- nNoUpdatesHum = 0 ;
143
- send (msgHum.set (humidity, 1 ));
248
+ temperatureHI = computeHeatIndex (temperature,humidity); // computes Heat Index, in *C
249
+ nNoUpdates = 0 ; // Reset no updates counter
250
+ #ifdef MY_DEBUG
251
+ Serial.print (" Heat Index: " );
252
+ Serial.print (temperatureHI);
253
+ Serial.println (" *C" );
254
+ #endif
255
+
256
+ if (!metric) {
257
+ temperature = 1.8 *temperature+32 ; // convertion to *F
258
+ temperatureHI = 1.8 *temperatureHI+32 ; // convertion to *F
259
+ }
144
260
145
261
#ifdef MY_DEBUG
146
- Serial.print (" H: " );
147
- Serial.println (humidity);
148
- #endif
149
- } else {
150
- // Increase no update counter if the humidity stayed the same
151
- nNoUpdatesHum++;
262
+ wait (100 );
263
+ Serial.print (" Sending temperature: " );
264
+ Serial.print (temperature);
265
+ #endif
266
+ send (msgTemp.set (temperature + SENSOR_TEMP_OFFSET, 2 ));
267
+
268
+ #ifdef MY_DEBUG
269
+ wait (100 );
270
+ Serial.print (" Sending humidity: " );
271
+ Serial.print (humidity);
272
+ #endif
273
+ send (msgHum.set (humidity + SENSOR_HUM_OFFSET, 2 ));
274
+
275
+ #ifdef MY_DEBUG
276
+ wait (100 );
277
+ Serial.print (" Sending HeatIndex: " );
278
+ Serial.print (temperatureHI);
279
+ #endif
280
+ send (msgTempHI.set (temperatureHI + SENSOR_TEMP_HI_OFFSET, 2 ));
281
+
152
282
}
153
283
284
+ nNoUpdates++;
285
+
154
286
// Sleep for a while to save energy
287
+ digitalWrite (DHTPOWERPIN, LOW);
288
+ wait (300 ); // waiting for potential presentation requests
155
289
sleep (UPDATE_INTERVAL);
290
+
156
291
}
0 commit comments