Combining DHT and Binary sensor update issue
-
Having an issue trying to figure how to get instant response from the binary inputs (reed switch) whilst also having a DHT in the mix.
The issue is that the binary change only gets sent when the temp or humidity is sent.
Running the code with out the DHT in there work flawlessly. and state changes are sent immediately
I assume is has to do with the Wait function in the loop, but with out that wait you poll the DHT too much and it wont read any data.
Set up is NodeMCU as MQTT gateway. running 2.0
Thanks
#include <ESP8266WiFi.h> #include <MySensors.h> #include <SPI.h> #include <Bounce2.h> #include <DHT.h> // DHT22 // Set this to the pin you connected the DHT's data pin to #define DHT_DATA_PIN 12 // 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 4 #define CHILD_ID_TEMP 5 float lastTemp; float lastHum; uint8_t nNoUpdatesTemp; uint8_t nNoUpdatesHum; bool metric = true; // Setting multiple child ID's for each switch and it's GPIO pin //Switch 1 #define CHILD_ID_1 1 #define BUTTON_PIN_1 4 // Arduino Digital I/O pin for button/reed switch //Switch 2 #define CHILD_ID_2 2 #define BUTTON_PIN_2 5 // Arduino Digital I/O pin for button/reed switch //Switch 3 #define CHILD_ID_3 3 #define BUTTON_PIN_3 10 // Arduino Digital I/O pin for button/reed switch //Switch 1 Bounce debouncer_1 = Bounce(); int oldValue_1=-1; //Switch 2 Bounce debouncer_2 = Bounce(); int oldValue_2=-1; //Switch 3 Bounce debouncer_3 = Bounce(); int oldValue_3=-1; // Setting mysensor message string (ChildID, V type) MyMessage msg1(CHILD_ID_1,V_TRIPPED); MyMessage msg2(CHILD_ID_2,V_TRIPPED); MyMessage msg3(CHILD_ID_3,V_TRIPPED); MyMessage msgHum(CHILD_ID_HUM, V_HUM); MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP); DHT dht; //Presenting each child ID void presentation() { // Register binary input sensor to gw (they will be created as child devices) //Switch present(CHILD_ID_1, S_DOOR); present(CHILD_ID_2, S_DOOR); present(CHILD_ID_3, S_DOOR); //DHT present(CHILD_ID_HUM, S_HUM); present(CHILD_ID_TEMP, S_TEMP); metric = getControllerConfig().isMetric; } //Setting up each GPIO pin as an input and turning on internal pull up resistor 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()); // Setup button 1 pinMode(BUTTON_PIN_1,INPUT); // Activate internal pull-up digitalWrite(BUTTON_PIN_1,HIGH); // After setting up the button, setup debouncer debouncer_1.attach(BUTTON_PIN_1); debouncer_1.interval(5); // Setup button 2 pinMode(BUTTON_PIN_2,INPUT); // Activate internal pull-up digitalWrite(BUTTON_PIN_2,HIGH); // After setting up the button, setup debouncer debouncer_2.attach(BUTTON_PIN_2); debouncer_2.interval(5); // Setup button 3 pinMode(BUTTON_PIN_3,INPUT); // Activate internal pull-up digitalWrite(BUTTON_PIN_3,HIGH); // After setting up the button, setup debouncer debouncer_3.attach(BUTTON_PIN_3); debouncer_3.interval(5); } void loop() { //DHT // 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++; } // Switch 1 debouncer_1.update(); // Get the update value int value_1 = debouncer_1.read(); if (value_1 != oldValue_1) { // Send in the new value send(msg1.set(value_1==HIGH ? 1 : 0)); oldValue_1 = value_1; } // Switch 2 debouncer_2.update(); // Get the update value int value_2 = debouncer_2.read(); if (value_2 != oldValue_2) { // Send in the new value send(msg2.set(value_2==HIGH ? 1 : 0)); oldValue_2 = value_2; } // Switch 3 debouncer_3.update(); // Get the update value int value_3 = debouncer_3.read(); if (value_3 != oldValue_3) { // Send in the new value send(msg3.set(value_3==HIGH ? 1 : 0)); oldValue_3 = value_3; } // Sleep for a while to save energy wait(UPDATE_INTERVAL); }```
-
@Bryden You will either have to use some interrupt functionality (wich is pretty hard to code when using other than just pins 2 and/or 3.
Easier to understand is not to make the loop() wait and instead only reading the DHT-Values when a certain time has passed. See eg. the Servo example (also for the necessary preparation):
if (attachedServo && millis() - timeOfLastChange > DETACH_DELAY) { myservo.detach(); attachedServo = false; }
-
Thought it might be a little harder than my pay grade.
might implement it a little later
-
@Bryden It's not rocket science, just inserting an additional variable and putting the dht measuring part in some if (){}-functionality.
You may try...#include <ESP8266WiFi.h> #include <MySensors.h> #include <SPI.h> #include <Bounce2.h> #include <DHT.h> // DHT22 // Set this to the pin you connected the DHT's data pin to #define DHT_DATA_PIN 12 // 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 4 #define CHILD_ID_TEMP 5 float lastTemp; float lastHum; //this is needed to store some time info = last time we got DHT values in millis uint16_t lastDHTTime = 0; uint8_t nNoUpdatesTemp; uint8_t nNoUpdatesHum; bool metric = true; // Setting multiple child ID's for each switch and it's GPIO pin //Switch 1 #define CHILD_ID_1 1 #define BUTTON_PIN_1 4 // Arduino Digital I/O pin for button/reed switch //Switch 2 #define CHILD_ID_2 2 #define BUTTON_PIN_2 5 // Arduino Digital I/O pin for button/reed switch //Switch 3 #define CHILD_ID_3 3 #define BUTTON_PIN_3 10 // Arduino Digital I/O pin for button/reed switch //Switch 1 Bounce debouncer_1 = Bounce(); int oldValue_1=-1; //Switch 2 Bounce debouncer_2 = Bounce(); int oldValue_2=-1; //Switch 3 Bounce debouncer_3 = Bounce(); int oldValue_3=-1; // Setting mysensor message string (ChildID, V type) MyMessage msg1(CHILD_ID_1,V_TRIPPED); MyMessage msg2(CHILD_ID_2,V_TRIPPED); MyMessage msg3(CHILD_ID_3,V_TRIPPED); MyMessage msgHum(CHILD_ID_HUM, V_HUM); MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP); DHT dht; //Presenting each child ID void presentation() { // Register binary input sensor to gw (they will be created as child devices) //Switch present(CHILD_ID_1, S_DOOR); present(CHILD_ID_2, S_DOOR); present(CHILD_ID_3, S_DOOR); //DHT present(CHILD_ID_HUM, S_HUM); present(CHILD_ID_TEMP, S_TEMP); metric = getControllerConfig().isMetric; } //Setting up each GPIO pin as an input and turning on internal pull up resistor 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()); // Setup button 1 pinMode(BUTTON_PIN_1,INPUT); // Activate internal pull-up digitalWrite(BUTTON_PIN_1,HIGH); // After setting up the button, setup debouncer debouncer_1.attach(BUTTON_PIN_1); debouncer_1.interval(5); // Setup button 2 pinMode(BUTTON_PIN_2,INPUT); // Activate internal pull-up digitalWrite(BUTTON_PIN_2,HIGH); // After setting up the button, setup debouncer debouncer_2.attach(BUTTON_PIN_2); debouncer_2.interval(5); // Setup button 3 pinMode(BUTTON_PIN_3,INPUT); // Activate internal pull-up digitalWrite(BUTTON_PIN_3,HIGH); // After setting up the button, setup debouncer debouncer_3.attach(BUTTON_PIN_3); debouncer_3.interval(5); } void loop() { //DHT // Force reading sensor, so it works also after sleep() if (millis() - lastDHTTime > UPDATE_INTERVAL) { lastDHTTime=millis(); 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++; } } // Switch 1 debouncer_1.update(); // Get the update value int value_1 = debouncer_1.read(); if (value_1 != oldValue_1) { // Send in the new value send(msg1.set(value_1==HIGH ? 1 : 0)); oldValue_1 = value_1; } // Switch 2 debouncer_2.update(); // Get the update value int value_2 = debouncer_2.read(); if (value_2 != oldValue_2) { // Send in the new value send(msg2.set(value_2==HIGH ? 1 : 0)); oldValue_2 = value_2; } // Switch 3 debouncer_3.update(); // Get the update value int value_3 = debouncer_3.read(); if (value_3 != oldValue_3) { // Send in the new value send(msg3.set(value_3==HIGH ? 1 : 0)); oldValue_3 = value_3; } // Sleep for a while to save energy //wait(UPDATE_INTERVAL); //replaced by if (millis() ...) }