Skip to content

Commit 922cdaa

Browse files
committed
DHT - Using official Adafruit Library, included Heat Index (feels like) sensor
1 parent cedd69d commit 922cdaa

File tree

1 file changed

+206
-71
lines changed

1 file changed

+206
-71
lines changed
Lines changed: 206 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
/**
23
* The MySensors Arduino library handles the wireless radio link and protocol
34
* between your home built sensors/actuators and HA controller of choice.
@@ -21,38 +22,49 @@
2122
* REVISION HISTORY
2223
* Version 1.0: Henrik EKblad
2324
* 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)
2428
*
2529
* 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*
2832
*
2933
* For more information, please visit:
30-
* http://www.mysensors.org/build/humidity
34+
* http://www.mysensors.org/build/TemperatureAndHumidity
3135
*
3236
*/
37+
#define SN "TemperatureAndHumidity"
38+
#define SV "2.2"
39+
40+
3341

3442
// Enable debug prints
35-
#define MY_DEBUG
43+
//#define MY_DEBUG
3644

3745
// Enable and select radio type attached
3846
#define MY_RADIO_NRF24
3947
//#define MY_RADIO_RFM69
4048
//#define MY_RS485
41-
42-
#include <SPI.h>
43-
#include <MySensors.h>
44-
#include <DHT.h>
4549

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
4854

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)
5259

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;
5668

5769
// Force sending an update of the temperature after n sensor reads, so a controller showing the
5870
// 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;
6274

6375
#define CHILD_ID_HUM 0
6476
#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
6584

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;
6696
float lastTemp;
6797
float lastHum;
68-
uint8_t nNoUpdatesTemp;
69-
uint8_t nNoUpdatesHum;
98+
uint8_t nNoUpdates = FORCE_UPDATE_N_READS; // send data on start-up
7099
bool metric = true;
100+
float temperature;
101+
float humidity;
102+
float temperatureHI;
103+
104+
71105

72106
MyMessage msgHum(CHILD_ID_HUM, V_HUM);
73107
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+
75149

76150

77151
void presentation()
78152
{
79153
// Send the sketch version information to the gateway
80-
sendSketchInfo("TemperatureAndHumidity", "1.1");
81-
154+
sendSketchInfo(SN, SV);
82155
// 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");
86161
metric = getControllerConfig().isMetric;
87162
}
88163

89164

90165
void setup()
91166
{
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;
99203
}
100204

101205

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;
114206

115-
// apply the offset before converting to something different than Celsius degrees
116-
temperature += SENSOR_TEMP_OFFSET;
117207

118-
if (!metric) {
119-
temperature = dht.toFahrenheit(temperature);
120-
}
121-
// Reset no updates counter
122-
nNoUpdatesTemp = 0;
123-
send(msgTemp.set(temperature, 1));
124208

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;
125238
#ifdef MY_DEBUG
126-
Serial.print("T: ");
127-
Serial.println(temperature);
239+
Serial.print("Humidity: ");
240+
Serial.print(humidity);
241+
Serial.println("%");
128242
#endif
129-
} else {
130-
// Increase no update counter if the temperature stayed the same
131-
nNoUpdatesTemp++;
132243
}
133244

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;
140247
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+
}
144260

145261
#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+
152282
}
153283

284+
nNoUpdates++;
285+
154286
// Sleep for a while to save energy
287+
digitalWrite(DHTPOWERPIN, LOW);
288+
wait(300); // waiting for potential presentation requests
155289
sleep(UPDATE_INTERVAL);
290+
156291
}

0 commit comments

Comments
 (0)