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() ...)
    }
    

Log in to reply
 

Looks like your connection to MySensors Forum was lost, please wait while we try to reconnect.