Garage Door + Other Sensors



  • Hello,
    I have successfully created many sensors based on the information learned on this forum. However, I can't get my latest project to work.

    I am trying to make a series of sensors which will tell me the status of the garage door, if the garage light is on, if there is anyone in the garage, and then a relay allowing me to remotely trigger the garage door. The code is below.

    Two problems:

    • I can get the door sensors, light sensor, and motion sensor to appear in Vera, but the light sensor is registering the motion sensor activity.
      *I can't get the relay to register in Vera.

    The code compiles and uploads without issue. Any ideas on where to look to resolve the two issues? Thanks in advance.

    /**
     * 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
     * Combo sketch built from original motion sensor sketch combined with code from the Relay actuator sketch
     * 2x Motion Sensors to be used as garage doors status usualy with reed switches
     * 2x Relays to control garage doors
    
     * NOTE! this sketch automaticaly turns the relays back off after a door control has been sent to it
     * How long the relays are on is defined vith the variable "RELAY_ONTIME" the default is 300 milliseconds
     * http://www.mysensors.org/build/relay
     */
    
    /*
    arduino Pro mini 5V 16MHz ????
    */
    
    #define MY_RADIO_NRF24
    #define MY_DEBUG    // Enables debug messages in the serial log
    
    // Set MY_NODE_ID to something unique in your sensor network (1-254)
    // or set to AUTO if you want gw to assign a MY_NODE_ID for you.
    
    #define MY_NODE_ID AUTO
    #define SN "DualGarageDoor"
    #define SV "1.5"
    
    //#define MY_RF24_CE_PIN 9    // Radio specific settings for RF24
    //#define MY_RF24_CS_PIN 10 // Radio specific settings for RF24 (you'll find similar config for RFM69)
    //#define MY_RF24_PA_LEVEL RF24_PA_MAX
    
    #include <MyConfig.h>
    #include <MySensors.h>
    #include <SPI.h>
    
    // Enable repeater functionality for this node
    #define MY_REPEATER_FEATURE
    
    #define DIGITAL_INPUT_SENSOR 3   // The digital input you attached your motion sensor.  (Only 2 and 3 generates interrupt!)
    #define DIGITAL_INPUT_SENSORA 4   // The digital input you attached your motion sensor.  (Only 2 and 3 generates interrupt!)
    #define DIGITAL_INPUT_SENSORB 5   // The digital input you attached your motion sensor.  (Only 2 and 3 generates interrupt!)
    //#define INTERRUPT DIGITAL_INPUT_SENSORA-2 // Usually the interrupt = pin -2 (on uno/nano anyway)
    #define CHILD_ID_PIR 4   // Id of the sensor child
    #define CHILD_ID_RELAY 3  //Id of relay
    #define CHILD_ID_DOORA 1   // Id of the sensor child
    #define CHILD_ID_DOORB 2   // Id of the sensor child
    #define CHILD_ID_LIGHT 0  //light sensor
    #define LIGHT_SENSOR_ANALOG_PIN 0 //light sensor
    
    
    #define RELAY_PIN  6  // Arduino Digital I/O pin number for first relay 
    #define NUMBER_OF_RELAYS 1 // Total number of attached relays
    //define what is on and off for the relay
    #define RELAY_ON 1
    #define RELAY_OFF 0
    
    //define what is on and off for the reed switches
    #define DOOR_CLOSED 0
    #define DOOR_OPEN 1
    
    int RELAY_ONTIME = 300; //delay before turning relay back off (300 milliseconds)
    int lastLightLevel; //light sensor
    
    boolean oldValueA = 0;
    boolean oldValueB = 0;
    boolean trippedA = 0;
    boolean trippedB = 0;
    
    uint32_t SLEEP_TIME = 10000; // Sleep time between reads (in milliseconds)
    
    MyMessage msg1(CHILD_ID_DOORA, V_LOCK_STATUS);
    MyMessage msg2(CHILD_ID_DOORB, V_LOCK_STATUS);
    MyMessage msg(CHILD_ID_LIGHT, V_LIGHT_LEVEL); //light sensor
    MyMessage msg3(CHILD_ID_PIR, V_TRIPPED); //PIR
    
    void before()
    {
      for (int sensor=1, pin=RELAY_PIN; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
        // Then set relay pins in output mode
        pinMode(pin, OUTPUT);
        // Set relay to last known state (using eeprom storage)
        digitalWrite(pin, loadState(sensor)?RELAY_ON:RELAY_OFF);
      }
    }
    
    void setup()
    {
      
      pinMode(DIGITAL_INPUT_SENSORA, INPUT);      // sets the motion sensor digital pin as input
      pinMode(DIGITAL_INPUT_SENSORB, INPUT);      // sets the motion sensor digital pin as input
    
      // Activate internal pull-up
      digitalWrite(DIGITAL_INPUT_SENSORA, HIGH);
      digitalWrite(DIGITAL_INPUT_SENSORB, HIGH);
      
      digitalWrite(RELAY_PIN, RELAY_OFF);
      pinMode(RELAY_PIN, OUTPUT);
    
      pinMode(DIGITAL_INPUT_SENSOR, INPUT);      // sets the motion sensor digital pin as input
      
    }
    
    void presentation()
    {
      // Send the Sketch Version Information to the Gateway
      Serial.println("Presentation");
      
      sendSketchInfo(SN, SV);
    
      for (int sensor=1, pin=RELAY_PIN; sensor<=NUMBER_OF_RELAYS; sensor++, pin++)
    
      {
        // Register all sensors to gw (they will be created as child devices)
      
      present(CHILD_ID_DOORA, S_LOCK);
      present(CHILD_ID_DOORB, S_LOCK);
      present(sensor, S_BINARY);
      present(CHILD_ID_LIGHT, S_LIGHT_LEVEL);
      present(CHILD_ID_PIR, S_MOTION);
      }
      
      {
      trippedA = digitalRead(DIGITAL_INPUT_SENSORA);
      trippedB = digitalRead(DIGITAL_INPUT_SENSORB);
      //Serial.print("Door A status: ");
      //Serial.println(trippedA);
      //Serial.print("Door B status: ");
      //Serial.println(trippedB);
      send(msg1.set(trippedA ? DOOR_CLOSED : DOOR_OPEN));
      send(msg2.set(trippedB ? DOOR_CLOSED : DOOR_OPEN));
      
      oldValueA = trippedA;
      oldValueB = trippedB;
      }
    }
    
    
    void loop()
    {
      // Read digital reed switch value
      trippedA = digitalRead(DIGITAL_INPUT_SENSORA);
      trippedB = digitalRead(DIGITAL_INPUT_SENSORB);
    
    
      // Send value only if changed
      if(trippedA != oldValueA)
      {
        //Serial.print("Door A status: ");
        //Serial.println(trippedA);
        send(msg1.set(trippedA ? DOOR_CLOSED : DOOR_OPEN));
        //gw.sendVariable(CHILD_ID_DOORA, V_LOCK_STATUS, trippedA?DOOR_CLOSED:DOOR_OPEN);  // Send value change to gw
        delay(1000);
        oldValueA = trippedA;
      }
    
      // Send value only if changed
      if(trippedB != oldValueB)
      {
        //Serial.print("Door B status: ");
        //Serial.println(trippedB);
        send(msg2.set(trippedB ? DOOR_CLOSED : DOOR_OPEN));
        //gw.sendVariable(CHILD_ID_DOORB, V_LOCK_STATUS, trippedB?DOOR_CLOSED:DOOR_OPEN);  // Send value change to gw
        delay(1000);
        oldValueB = trippedB;
      }
    
      int16_t lightLevel = (1023-analogRead(LIGHT_SENSOR_ANALOG_PIN))/10.23;
      //Serial.println(lightLevel);
      if (abs(lightLevel - lastLightLevel)>20)  {
        send(msg.set(lightLevel));
        lastLightLevel = lightLevel;
      }
    
      {
      // 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);
      }
      sleep(SLEEP_TIME);
    }
    
    
    void receive(const MyMessage &message)
    {
      // We only expect one type of message from controller. But we better check anyway.
      if (message.type==V_STATUS) {
        // Change relay state
        digitalWrite(message.sensor-1+RELAY_PIN, message.getBool()?RELAY_ON:RELAY_OFF);
        // Store state in eeprom
        saveState(message.sensor, message.getBool());
        // Write some debug info
        Serial.print("Incoming change for sensor:");
        Serial.print(message.sensor);
        Serial.print(", New status: ");
        Serial.println(message.getBool());
      }
    }
    

  • Mod

    Start counting your child ids from 10 as the child ID 1 (CHILD_ID_DOORA) is conflicting with the relay. Move the children presentations outside the "for" cycle and leave there just the relay presentation.



  • @gohan Thanks gohan. All the sensors now register in Vera and are collecting data accurately. However, the relay doesn't respond at all. Still trying to figure that out.


  • Mod

    Don't use delay or sleep functions when using relays or any other actuator that needs a command from the controller; use wait instead. In addition i saw 2 sleep functions called at the end of loop, I think there is one too much and needs to be replaced with wait. If you want to menage Pir/door sensors with interrupts you can use the normal attachpintointerrupt function since the node is not sleeping.



  • I would suggest using interrupts for the motion sensors. This way you only need to actively monitor light sensor. Everything else will only happen and take up processing power when it is actually needed.


  • Mod

    That is what I wrote earlier 🙂



  • So you did 😂 I somehow managed to miss that part.



  • @thucar @gohan

    Thank you both. Everything is working as designed now. For now, I am just going to stick with the code below. I will put the interrupts in on the next version.

    /**
     * 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
     * Combo sketch built from original motion sensor sketch combined with code from the Relay actuator sketch
     * 2x Motion Sensors to be used as garage doors status usualy with reed switches
     * 2x Relays to control garage doors
    
     * NOTE! this sketch automaticaly turns the relays back off after a door control has been sent to it
     * How long the relays are on is defined vith the variable "RELAY_ONTIME" the default is 300 milliseconds
     * http://www.mysensors.org/build/relay
     */
    
    /*
    arduino Pro mini 5V 16MHz ????
    */
    
    #define MY_RADIO_NRF24
    #define MY_DEBUG    // Enables debug messages in the serial log
    
    // Set MY_NODE_ID to something unique in your sensor network (1-254)
    // or set to AUTO if you want gw to assign a MY_NODE_ID for you.
    
    #define MY_NODE_ID AUTO
    #define SN "DualGarageDoor"
    #define SV "1.5"
    
    //#define MY_RF24_CE_PIN 9    // Radio specific settings for RF24
    //#define MY_RF24_CS_PIN 10 // Radio specific settings for RF24 (you'll find similar config for RFM69)
    //#define MY_RF24_PA_LEVEL RF24_PA_MAX
    
    #include <MyConfig.h>
    #include <MySensors.h>
    #include <SPI.h>
    
    // Enable repeater functionality for this node
    #define MY_REPEATER_FEATURE
    
    #define DIGITAL_INPUT_SENSOR 3   // The digital input for PIR.
    #define DIGITAL_INPUT_SENSORA 4   // The digital input for Door 1
    #define DIGITAL_INPUT_SENSORB 5   // The digital input for Door 2
    #define LIGHT_SENSOR_ANALOG_PIN 0 //light sensor
    //#define INTERRUPT DIGITAL_INPUT_SENSORA-2 // Usually the interrupt = pin -2 (on uno/nano anyway)
    #define CHILD_ID_PIR 40   // Id of the sensor child
    #define CHILD_ID_RELAY 30  //Id of relay
    #define CHILD_ID_DOORA 21   // Id of the sensor child
    #define CHILD_ID_DOORB 20   // Id of the sensor child
    #define CHILD_ID_LIGHT 10  //light sensor
    
    #define RELAY_PIN  6  // Arduino Digital I/O pin number for first relay 
    #define NUMBER_OF_RELAYS 1 // Total number of attached relays
    //define what is on and off for the relay
    #define RELAY_ON 1
    #define RELAY_OFF 0
    
    //define what is on and off for the reed switches
    #define DOOR_CLOSED 0
    #define DOOR_OPEN 1
    
    int RELAY_ONTIME = 1000; //delay before turning relay back off
    int lastLightLevel; //light sensor
    
    boolean oldValueA = 0;
    boolean oldValueB = 0;
    boolean trippedA = 0;
    boolean trippedB = 0;
    
    uint32_t SLEEP_TIME = 10000; // Sleep time between reads (in milliseconds)
    
    MyMessage msg1(CHILD_ID_DOORA, V_LOCK_STATUS);
    MyMessage msg2(CHILD_ID_DOORB, V_LOCK_STATUS);
    MyMessage msg4(CHILD_ID_LIGHT, V_LIGHT_LEVEL); //light sensor
    MyMessage msg3(CHILD_ID_PIR, V_TRIPPED); //PIR
    
    void before()
    {
      for (int sensor=1, pin=RELAY_PIN; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
        // Then set relay pins in output mode
        pinMode(pin, OUTPUT);
        // Set relay to last known state (using eeprom storage)
        digitalWrite(pin, loadState(sensor)?RELAY_ON:RELAY_OFF);
      }
    }
    
    void setup()
    {
      
      pinMode(DIGITAL_INPUT_SENSORA, INPUT);      // sets the motion sensor digital pin as input
      pinMode(DIGITAL_INPUT_SENSORB, INPUT);      // sets the motion sensor digital pin as input
    
      // Activate internal pull-up
      digitalWrite(DIGITAL_INPUT_SENSORA, HIGH);
      digitalWrite(DIGITAL_INPUT_SENSORB, HIGH);
      
      digitalWrite(RELAY_PIN, RELAY_OFF);
      pinMode(RELAY_PIN, OUTPUT);
    
      pinMode(DIGITAL_INPUT_SENSOR, INPUT);      // sets the motion sensor digital pin as input
      
    }
    
    void presentation()
    {
      // Send the Sketch Version Information to the Gateway
      Serial.println("Presentation");
      
      sendSketchInfo(SN, SV);
    
      for (int sensor=1, pin=RELAY_PIN; sensor<=NUMBER_OF_RELAYS; sensor++, pin++)
      {
        present(sensor, S_BINARY);
      }
      {
      trippedA = digitalRead(DIGITAL_INPUT_SENSORA);
      trippedB = digitalRead(DIGITAL_INPUT_SENSORB);
      //Serial.print("Door A status: ");
      //Serial.println(trippedA);
      //Serial.print("Door B status: ");
      //Serial.println(trippedB);
      send(msg1.set(trippedA ? DOOR_CLOSED : DOOR_OPEN));
      send(msg2.set(trippedB ? DOOR_CLOSED : DOOR_OPEN));
      
      oldValueA = trippedA;
      oldValueB = trippedB;
      }
    
      {
        // Register all sensors to gw (they will be created as child devices)
      
      present(CHILD_ID_DOORA, S_LOCK);
      present(CHILD_ID_DOORB, S_LOCK);
      present(CHILD_ID_LIGHT, S_LIGHT_LEVEL);
      present(CHILD_ID_PIR, S_MOTION);
      }
    }
    
    
    void loop()
    {
      {
      // Read digital reed switch value
      trippedA = digitalRead(DIGITAL_INPUT_SENSORA);
      trippedB = digitalRead(DIGITAL_INPUT_SENSORB);
    
    
      // Send value only if changed
      if(trippedA != oldValueA)
      {
        //Serial.print("Door A status: ");
        //Serial.println(trippedA);
        send(msg1.set(trippedA ? DOOR_CLOSED : DOOR_OPEN));
        //gw.sendVariable(CHILD_ID_DOORA, V_LOCK_STATUS, trippedA?DOOR_CLOSED:DOOR_OPEN);  // Send value change to gw
        delay(1000);
        oldValueA = trippedA;
      }
    
      // Send value only if changed
      if(trippedB != oldValueB)
      {
        //Serial.print("Door B status: ");
        //Serial.println(trippedB);
        send(msg2.set(trippedB ? DOOR_CLOSED : DOOR_OPEN));
        //gw.sendVariable(CHILD_ID_DOORB, V_LOCK_STATUS, trippedB?DOOR_CLOSED:DOOR_OPEN);  // Send value change to gw
        delay(1000);
        oldValueB = trippedB;
      }
      }
    
      {
        int16_t lightLevel = (1023-analogRead(LIGHT_SENSOR_ANALOG_PIN))/10.23;
      
      //Serial.println(lightLevel);
      if (abs(lightLevel - lastLightLevel)>20)  {
        send(msg4.set(lightLevel));
        lastLightLevel = lightLevel;
      }
      }
      
      {
      // Read digital motion value
      bool tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;
    
      Serial.println(tripped);
      send(msg3.set(tripped?"1":"0"));  // Send tripped value to gw
    
      // Sleep until interrupt comes in on motion sensor. Send update every two minute.
      wait(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, SLEEP_TIME);
      }
    }
    
    
    void receive(const MyMessage &message)
    {
      // We only expect one type of message from controller. But we better check anyway.
      if (message.type==V_STATUS) {
        // Change relay state
        digitalWrite(RELAY_PIN, RELAY_ON);
        wait(RELAY_ONTIME);
        digitalWrite(RELAY_PIN, RELAY_OFF);
        wait(2000);
        
        }
    }
    

 

389
Online

7.6k
Users

8.5k
Topics

91.2k
Posts