Adding Door sensor to Multisensor not working...



  • Greetings All,

    I previously had a working sketch for a multi-sensor. I have since tried to add a door switch to the sketch but i can't get it working at all. All the other sensors seem to be working. Any advice you can provide would be greatly appreciated.

    // Enable debug prints
    #define MY_DEBUG
    #define MY_NODE_ID 233
    #define MY_PARENT_NODE_ID 0
    #define MY_PARENT_NODE_IS_STATIC
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    
    #include <MySensors.h>
    #include <SPI.h>
    #include <DHT.h>
    #include <Bounce2.h>
    
    unsigned long SLEEP_TIME = 120000; // Sleep time between reports (in milliseconds)
    #define DIGITAL_INPUT_SENSOR 3   // The digital input you attached your motion sensor.  (Only 2 and 3 generates interrupt!)
    #define CHILD_ID_MOTION 1   // Id of the sensor child
    #define CHILD_ID_HUM 2
    #define CHILD_ID_TEMP 3
    #define CHILD_ID_DOOR 4
    
    // Set this to the pin you connected the DHT's data pin to
    #define DHT_DATA_PIN 5
    
    // Set this offset if the sensor has a permanent small offset to the real temperatures
    #define SENSOR_TEMP_OFFSET 0
    
    #define BUTTON_PIN  7  // Arduino Digital I/O pin for button/reed switch
    
    // 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;
    
    Bounce debouncer = Bounce(); 
    int oldValue=-1;
    
    float lastTemp;
    float lastHum;
    uint8_t nNoUpdatesTemp;
    uint8_t nNoUpdatesHum;
    bool metric = true;
    
    MyMessage msgHum(CHILD_ID_HUM, V_HUM), msgDoor(CHILD_ID_DOOR, V_TRIPPED), msgTemp(CHILD_ID_TEMP, V_TEMP), msg(CHILD_ID_MOTION, V_TRIPPED);
    DHT dht;
    
    
    void presentation()  
    { 
      // Send the sketch version information to the gateway
      sendSketchInfo("TemperatureHumidityMotionAndDoor", "1.2");
    
      // Register all sensors to gw (they will be created as child devices)
      present(CHILD_ID_HUM, S_HUM);
      present(CHILD_ID_TEMP, S_TEMP);
      present(CHILD_ID_MOTION, S_MOTION);
      present(CHILD_ID_DOOR, S_DOOR); 
    
      metric = getControllerConfig().isMetric;
    }
    
    
    void setup()
    {
      dht.setup(DHT_DATA_PIN); // set data pin of DHT sensor
      if (1200000 <= dht.getMinimumSamplingPeriod()) {
        Serial.println("Warning: UPDATE_INTERVAL is smaller than supported by the sensor!");
        pinMode(DIGITAL_INPUT_SENSOR, INPUT);      // sets the motion sensor digital pin as input
          // Setup the button
        pinMode(BUTTON_PIN,INPUT_PULLUP);
         // Activate internal pull-up
        digitalWrite(BUTTON_PIN,HIGH);
    
         // After setting up the button, setup debouncer
        debouncer.attach(BUTTON_PIN);
        debouncer.interval(5);
      }
      // 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++;
      }
    
      debouncer.update();
      // Get the update value
      int value = debouncer.read();
    
      if (value != oldValue) {
         // Send in the new value
         send(msgDoor.set(value==HIGH ? 1 : 0));
         oldValue = value;
    
        #ifdef MY_DEBUG
        Serial.print("D: ");
        Serial.println(value);
        #endif
      }
    
      // Read digital motion value
        bool tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;
    
        Serial.println(tripped);
        send(msg.set(tripped?"1":"0"));  // Send tripped value to gw
    
    
      // Sleep until interrupt comes in on motion sensor. Send update every two minute.
       sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, SLEEP_TIME); 
    }
    

    Thanks!



  • @shadex12 said in Adding Door sensor to Multisensor not working...:

    BUTTON_PIN

    Are you trying to add a motion sensor or a reed switch? What is BUTTON_PIN?
    What is the log saying?
    Try to substitute the following

    sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, SLEEP_TIME);
    

    with

    sleep(DIGITAL_INPUT_SENSOR-2, CHANGE, 0);
    


  • @alexsh1

    Thanks for the response. I should have been more clear. I currently have motion, temperature and humidity. I am trying to add a reed switch to use as a door sensor.

    With the code a I posted above motion temp and humidity all work fine but I cannot get any output from the reed switch. I have tested the switch itself and it is fine, so I know it is my code. I am not much of a coder so I mostly sticking stuff together from the examples and trying to learn and improve but I really don't know what I am doing.

    BUTTON_PIN I believe is where i define which pin on the Arduino to connect the reed switch to.

    The serial output shows that the reed switch registers with the gateway and I can see it in Home Assisstant, but it never updates or outputs anything in the logs again after this line:

    189 TSF:MSG:SEND,233-233-0-0,s=4,c=0,t=0,pt=0,l=0,sg=0,ft=0,st=OK:

    I made the change to the code as you suggested but it didn't seem to any effect, positive or negative.



  • Hi!
    This is how I see it:
    You sleep most of the time so both the motion sensor and the door sensor will have to generate an interrupt in order for the sensor to transmit.

    The Arduino only has two interrupts, 0 and 1. Pin 2 generates interrupt 0 and pin 3 generates interrupt 1.

    The motion sensor is attached to pin 3 which generates interrupt 1 (3-2 = 1) but only pins 3 and 2 are able to generate interrupts. You have attached your door sensor to BUTTON_PIN = pin 7 but pin 7 cannot generate an interrupt. This is why you never see this triggered.

    Try attaching the door sensor to pin 2 and re-use the code for the motion sensor, transmitting the message msgDoor.

    You will have to change the sleep message also to handle two interrupts. This is the constructor for the sleep message, taken from the 2.x API-definition:
    int8_t sleep(uint8_t interrupt1, uint8_t mode1, uint8_t interrupt2, uint8_t mode2, unsigned long ms=0);



  • @bgunnarb Spot on!

    @ShadeX12 You have to re-wire your Reed sensor to pins 2 or 3



  • Thanks a lot everyone for the responses. I have got a little further. I am now able to get readings from the door sensor...sort of.

    Everything works fine with the sensor if the door switch is close. As soon as the switch is open, it flips to open the close over and over again a spams the gateway with the messages.

    Here's what I've got for code. I suspect maybe something is wrong with the loop.

    /**
     * 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 <henrik.ekblad@mysensors.org>
     * 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
     * Motion Sensor example using HC-SR501
     * http://www.mysensors.org/build/motion
     *
     */
    
    // Enable debug prints
    #define MY_DEBUG
    #define MY_NODE_ID 233
    #define MY_PARENT_NODE_ID 0
    #define MY_PARENT_NODE_IS_STATIC
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    
    #include <MySensors.h>
    #include <SPI.h>
    #include <DHT.h>
    #include <Bounce2.h>
    
    unsigned long SLEEP_TIME = 120000; // Sleep time between reports (in milliseconds)
    #define DIGITAL_INPUT_SENSOR 2   // The digital input you attached your motion sensor.  (Only 2 and 3 generates interrupt!)
    #define DIGITAL_INPUT_SENSOR2 3 // The input for door sensor
    #define CHILD_ID_MOTION 1   // Id of the sensor child
    #define CHILD_ID_HUM 2
    #define CHILD_ID_TEMP 3
    #define CHILD_ID_DOOR 4
    
    // Set this to the pin you connected the DHT's data pin to
    #define DHT_DATA_PIN 4
    
    // Set this offset if the sensor has a permanent small offset to the real temperatures
    #define SENSOR_TEMP_OFFSET 0
    
    
    
    // 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;
    
    
    float lastTemp;
    float lastHum;
    uint8_t nNoUpdatesTemp;
    uint8_t nNoUpdatesHum;
    bool metric = true;
    
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    // Initialize motion message
    MyMessage msg(CHILD_ID_MOTION, V_TRIPPED);
    MyMessage msgDoor(CHILD_ID_DOOR, V_TRIPPED);
    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);
      present(CHILD_ID_MOTION, S_MOTION);
      present(CHILD_ID_DOOR, S_DOOR); 
      metric = getControllerConfig().isMetric;
    }
    
    
    void setup()
    {
      dht.setup(DHT_DATA_PIN); // set data pin of DHT sensor
      if (1200000 <= dht.getMinimumSamplingPeriod()) {
        Serial.println("Warning: UPDATE_INTERVAL is smaller than supported by the sensor!");
        pinMode(DIGITAL_INPUT_SENSOR, INPUT);      // sets the motion sensor digital pin as input
        pinMode(DIGITAL_INPUT_SENSOR2, INPUT);      // sets the door sensor digital pin as input
        digitalWrite(DIGITAL_INPUT_SENSOR2,HIGH);   // Activate internal pull-up
      }
      // 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++;
      }
    
      // Read digital motion value
        bool tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;
    
        Serial.println(tripped);
        send(msg.set(tripped?"1":"0"));  // Send tripped value to gw
    
        
      // Read digital door value
        bool tripped2 = digitalRead(DIGITAL_INPUT_SENSOR2) == HIGH;
    
        Serial.println(tripped2);
        send(msgDoor.set(tripped2?"1":"0"));  // Send tripped value to gw
    
    
    
      // Sleep until interrupt comes in on motion sensor. Send update every two minute.
      sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, digitalPinToInterrupt(DIGITAL_INPUT_SENSOR2), CHANGE, SLEEP_TIME); 
    }
    
    
    

  • Mod

    @shadex12 see if setting the door sensors to INPUT_PULLUP instead of INPUT helps.

    My guess is that the pin is floating.

    Edit: sorry, I see now that the pin is set to high which does the same thing as setting pullup. Ignore my advice 🙂



  • Okay I figured this out!

    The problem was actually with where I was defining the pins. They where withing the if statement for the DHT warning. I have moved them outside that statement and it seems to be working fine.

    /**
     * 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 <henrik.ekblad@mysensors.org>
     * 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
     * Motion Sensor example using HC-SR501
     * http://www.mysensors.org/build/motion
     *
     */
    
    // Enable debug prints
    #define MY_DEBUG
    #define MY_NODE_ID 233
    #define MY_PARENT_NODE_ID 0
    #define MY_PARENT_NODE_IS_STATIC
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    
    #include <MySensors.h>
    #include <SPI.h>
    #include <DHT.h>
    #include <Bounce2.h>
    
    unsigned long SLEEP_TIME = 120000; // Sleep time between reports (in milliseconds)
    #define DIGITAL_INPUT_SENSOR 2   // The digital input you attached your motion sensor.  (Only 2 and 3 generates interrupt!)
    #define DIGITAL_INPUT_SENSOR2 3 // The input for door sensor
    #define CHILD_ID_MOTION 1   // Id of the sensor child
    #define CHILD_ID_HUM 2
    #define CHILD_ID_TEMP 3
    #define CHILD_ID_DOOR 4
    
    // Set this to the pin you connected the DHT's data pin to
    #define DHT_DATA_PIN 4
    
    // Set this offset if the sensor has a permanent small offset to the real temperatures
    #define SENSOR_TEMP_OFFSET 0
    
    
    
    // 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;
    
    
    float lastTemp;
    float lastHum;
    uint8_t nNoUpdatesTemp;
    uint8_t nNoUpdatesHum;
    bool metric = true;
    
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    // Initialize motion message
    MyMessage msg(CHILD_ID_MOTION, V_TRIPPED);
    MyMessage msgDoor(CHILD_ID_DOOR, V_TRIPPED);
    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);
      present(CHILD_ID_MOTION, S_MOTION);
      present(CHILD_ID_DOOR, S_DOOR); 
      metric = getControllerConfig().isMetric;
    }
    
    
    void setup()
    {
      dht.setup(DHT_DATA_PIN); // set data pin of DHT sensor
      if (1200000 <= 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());
      pinMode(DIGITAL_INPUT_SENSOR, INPUT);      // sets the motion sensor digital pin as input
      pinMode(DIGITAL_INPUT_SENSOR2, INPUT);      // sets the door sensor digital pin as input
      digitalWrite(DIGITAL_INPUT_SENSOR2,HIGH);   // Activate internal pull-up
    }
    
    
    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++;
      }
    
      // Read digital motion value
        bool tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;
    
        Serial.println(tripped);
        send(msg.set(tripped?"1":"0"));  // Send tripped value to gw
    
        
      // Read digital door value
        bool tripped2 = digitalRead(DIGITAL_INPUT_SENSOR2) == HIGH;
    
        Serial.println(tripped2);
        send(msgDoor.set(tripped2?"1":"0"));  // Send tripped value to gw
    
    
    
      // Sleep until interrupt comes in on motion sensor. Send update every two minute.
      sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, digitalPinToInterrupt(DIGITAL_INPUT_SENSOR2), CHANGE, SLEEP_TIME); 
    }
    

    Thanks again for all your help everyone!


Log in to reply
 

Suggested Topics

  • 3
  • 2
  • 1
  • 6
  • 6
  • 5

12
Online

11.4k
Users

11.1k
Topics

112.7k
Posts