diff --git a/examples/DhtTemperatureAndHumiditySensor/DhtTemperatureAndHumiditySensor.ino b/examples/DhtTemperatureAndHumiditySensor/DhtTemperatureAndHumiditySensor.ino new file mode 100644 index 0000000..32a1d80 --- /dev/null +++ b/examples/DhtTemperatureAndHumiditySensor/DhtTemperatureAndHumiditySensor.ino @@ -0,0 +1,152 @@ +/** + * The MySensors Arduino library handles the wireless radio link and protocol + * between your home built sensors/actuators and HA controller of choice. + * The sensors forms a self healing radio network with optional repeaters. Each + * repeater and gateway builds a routing tables in EEPROM which keeps track of the + * network topology allowing messages to be routed to nodes. + * + * Created by Henrik Ekblad + * Copyright (C) 2013-2015 Sensnology AB + * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors + * + * Documentation: http://www.mysensors.org + * Support Forum: http://forum.mysensors.org + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + ******************************* + * + * REVISION HISTORY + * Version 1.0: Henrik EKblad + * Version 1.1 - 2016-07-20: Converted to MySensors v2.0 and added various improvements - Torben Woltjen (mozzbozz) + * + * DESCRIPTION + * This sketch provides an example of how to implement a humidity/temperature + * sensor using a DHT11/DHT-22. + * + * For more information, please visit: + * http://www.mysensors.org/build/humidity + * + */ + +// Enable debug prints +#define MY_DEBUG + +// Enable and select radio type attached +#define MY_RADIO_NRF24 +//#define MY_RADIO_RFM69 +//#define MY_RS485 + +#include +#include +#include + +// Set this to the pin you connected the DHT's data pin to +#define DHT_DATA_PIN 2 + +// Set this offset if the sensor has a permanent small offset to the real temperatures +#define SENSOR_TEMP_OFFSET 0 + +// Sleep time between sensor updates (in milliseconds) +// Must be >1000ms for DHT22 and >2000ms for DHT11 +static const uint64_t UPDATE_INTERVAL = 60000; + +// Force sending an update of the temperature after n sensor reads, so a controller showing the +// timestamp of the last update doesn't show something like 3 hours in the unlikely case, that +// the value didn't change since; +// i.e. the sensor would force sending an update every UPDATE_INTERVAL*FORCE_UPDATE_N_READS [ms] +static const uint8_t FORCE_UPDATE_N_READS = 10; + +#define CHILD_ID_HUM 0 +#define CHILD_ID_TEMP 1 + +float lastTemp; +float lastHum; +uint8_t nNoUpdatesTemp; +uint8_t nNoUpdatesHum; +boolean metric = true; + +MyMessage msgHum(CHILD_ID_HUM, V_HUM); +MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP); +DHT dht; + + +void presentation() +{ + // Send the sketch version information to the gateway + sendSketchInfo("TemperatureAndHumidity", "1.1"); + + // Register all sensors to gw (they will be created as child devices) + present(CHILD_ID_HUM, S_HUM); + present(CHILD_ID_TEMP, S_TEMP); + + metric = getConfig().isMetric; +} + + +void setup() +{ + dht.setup(DHT_DATA_PIN); // set data pin of DHT sensor + if (UPDATE_INTERVAL <= dht.getMinimumSamplingPeriod()) { + Serial.println("Warning: UPDATE_INTERVAL is smaller than supported by the sensor!"); + } + // Sleep for the time of the minimum sampling period to give the sensor time to power up + // (otherwise, timeout errors might occure for the first reading) + sleep(dht.getMinimumSamplingPeriod()); +} + + +void loop() +{ + // Force reading sensor, so it works also after sleep() + dht.readSensor(true); + + // Get temperature from DHT library + float temperature = dht.getTemperature(); + if (isnan(temperature)) { + Serial.println("Failed reading temperature from DHT!"); + } else if (temperature != lastTemp || nNoUpdatesTemp == FORCE_UPDATE_N_READS) { + // Only send temperature if it changed since the last measurement or if we didn't send an update for n times + lastTemp = temperature; + if (!metric) { + temperature = dht.toFahrenheit(temperature); + } + // Reset no updates counter + nNoUpdatesTemp = 0; + temperature += SENSOR_TEMP_OFFSET; + send(msgTemp.set(temperature, 1)); + + #ifdef MY_DEBUG + Serial.print("T: "); + Serial.println(temperature); + #endif + } else { + // Increase no update counter if the temperature stayed the same + nNoUpdatesTemp++; + } + + // Get humidity from DHT library + float humidity = dht.getHumidity(); + if (isnan(humidity)) { + Serial.println("Failed reading humidity from DHT"); + } else if (humidity != lastHum || nNoUpdatesHum == FORCE_UPDATE_N_READS) { + // Only send humidity if it changed since the last measurement or if we didn't send an update for n times + lastHum = humidity; + // Reset no updates counter + nNoUpdatesHum = 0; + send(msgHum.set(humidity, 1)); + + #ifdef MY_DEBUG + Serial.print("H: "); + Serial.println(humidity); + #endif + } else { + // Increase no update counter if the humidity stayed the same + nNoUpdatesHum++; + } + + // Sleep for a while to save energy + sleep(UPDATE_INTERVAL); +} diff --git a/examples/HumiditySensor/HumiditySensor.ino b/examples/HumiditySensor/HumiditySensor.ino deleted file mode 100644 index 1d28795..0000000 --- a/examples/HumiditySensor/HumiditySensor.ino +++ /dev/null @@ -1,104 +0,0 @@ -/** - * The MySensors Arduino library handles the wireless radio link and protocol - * between your home built sensors/actuators and HA controller of choice. - * The sensors forms a self healing radio network with optional repeaters. Each - * repeater and gateway builds a routing tables in EEPROM which keeps track of the - * network topology allowing messages to be routed to nodes. - * - * Created by Henrik Ekblad - * Copyright (C) 2013-2015 Sensnology AB - * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors - * - * Documentation: http://www.mysensors.org - * Support Forum: http://forum.mysensors.org - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - ******************************* - * - * REVISION HISTORY - * Version 1.0 - Henrik EKblad - * - * DESCRIPTION - * This sketch provides an example how to implement a humidity/temperature - * sensor using DHT11/DHT-22 - * http://www.mysensors.org/build/humidity - */ - -// Enable debug prints -//#define MY_DEBUG - -// Enable and select radio type attached -#define MY_RADIO_NRF24 -//#define MY_RADIO_RFM69 - -#include -#include -#include - -#define CHILD_ID_HUM 0 -#define CHILD_ID_TEMP 1 -#define HUMIDITY_SENSOR_DIGITAL_PIN 3 -unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds) - -DHT dht; -float lastTemp; -float lastHum; -boolean metric = true; -MyMessage msgHum(CHILD_ID_HUM, V_HUM); -MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP); - -void setup() -{ - dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); - - metric = getConfig().isMetric; -} - -void presentation() -{ - // Send the Sketch Version Information to the Gateway - sendSketchInfo("Humidity", "1.0"); - - // Register all sensors to gw (they will be created as child devices) - present(CHILD_ID_HUM, S_HUM); - present(CHILD_ID_TEMP, S_TEMP); -} - -void loop() -{ - delay(dht.getMinimumSamplingPeriod()); - - // Fetch temperatures from DHT sensor - float temperature = dht.getTemperature(); - if (isnan(temperature)) { - Serial.println("Failed reading temperature from DHT"); - } else if (temperature != lastTemp) { - lastTemp = temperature; - if (!metric) { - temperature = dht.toFahrenheit(temperature); - } - send(msgTemp.set(temperature, 1)); - #ifdef MY_DEBUG - Serial.print("T: "); - Serial.println(temperature); - #endif - } - - // Fetch humidity from DHT sensor - float humidity = dht.getHumidity(); - if (isnan(humidity)) { - Serial.println("Failed reading humidity from DHT"); - } else if (humidity != lastHum) { - lastHum = humidity; - send(msgHum.set(humidity, 1)); - #ifdef MY_DEBUG - Serial.print("H: "); - Serial.println(humidity); - #endif - } - - sleep(SLEEP_TIME); //sleep a bit -} diff --git a/libraries/DHT/DHT.cpp b/libraries/DHT/DHT.cpp index 1584d6a..a630396 100644 --- a/libraries/DHT/DHT.cpp +++ b/libraries/DHT/DHT.cpp @@ -24,6 +24,7 @@ 2013-06-10: Initial version 2013-06-12: Refactored code 2013-07-01: Add a resetTimer method + 2016-07-20: Add force parameter - Torben Woltjen (mozzbozz) ******************************************************************/ #include "DHT.h" @@ -108,13 +109,15 @@ const char *DHT::getStatusString() { #endif -void DHT::readSensor() +void DHT::readSensor(bool force) { // Make sure we don't poll the sensor too often // - Max sample rate DHT11 is 1 Hz (duty cicle 1000 ms) // - Max sample rate DHT22 is 0.5 Hz (duty cicle 2000 ms) + // If 'force' is true, the user has to take care of this -> this way, the + // microcontroller can be set to sleep where it doesn't increase millis(). unsigned long startTime = millis(); - if ( (unsigned long)(startTime - lastReadTime) < (model == DHT11 ? 999L : 1999L) ) { + if ( !force && (unsigned long)(startTime - lastReadTime) < (model == DHT11 ? 999L : 1999L) ) { return; } lastReadTime = startTime; diff --git a/libraries/DHT/DHT.h b/libraries/DHT/DHT.h index 9e24518..c26eeb1 100644 --- a/libraries/DHT/DHT.h +++ b/libraries/DHT/DHT.h @@ -24,6 +24,7 @@ 2013-06-10: Initial version 2013-06-12: Refactored code 2013-07-01: Add a resetTimer method + 2016-07-20: Add force parameter - Torben Woltjen (mozzbozz) ******************************************************************/ #ifndef dht_h @@ -58,6 +59,7 @@ class DHT void setup(uint8_t pin, DHT_MODEL_t model=AUTO_DETECT); void resetTimer(); + void readSensor(bool force=false); float getTemperature(); float getHumidity(); @@ -66,7 +68,7 @@ class DHT DHT_MODEL_t getModel() { return model; } - int getMinimumSamplingPeriod() { return model == DHT11 ? 1000 : 2000; } + unsigned int getMinimumSamplingPeriod() { return model == DHT11 ? 1000 : 2000; } int8_t getNumberOfDecimalsTemperature() { return model == DHT11 ? 0 : 1; }; int8_t getLowerBoundTemperature() { return model == DHT11 ? 0 : -40; }; @@ -80,8 +82,6 @@ class DHT static float toCelsius(float fromFahrenheit) { return (fromFahrenheit - 32.0) / 1.8; }; protected: - void readSensor(); - float temperature; float humidity;