Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. My Project
  3. Automated garage door

Automated garage door

Scheduled Pinned Locked Moved My Project
33 Posts 9 Posters 12.9k Views 11 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • dbemowskD Offline
    dbemowskD Offline
    dbemowsk
    wrote on last edited by
    #18

    OK, I finally got around to finishing the first sketch that I am going to test for this.

    /*
    MyGarageDoor for MySensors
    
    Arduino garage door control
    
    June 16,2016
    
    This will allow the MySensors gateway to monitor and control your garage door opener.  This will 
    monitor the internal upper and lower limit switches of the door opener to determine door position 
    for status as well as have a relay switched output that can control either the momentary contact 
    switch connected to the door opener or wired directly to the switch contacts of a door opener 
    remote to activate the door.
    
    This sketch features the following:
    
    * Allows you to monitor the door position and return it's status based on the following:
        1 - When either the upper or lower door limit switches are reached, the door is said to be 
            either fully open or fully closed. When a limit switch is triggered, the lastLimit and 
            currentState variables are set to either OPEN or CLOSED based on the limit switch that was 
            triggered.
        2 - If the upper and lower limit inputs both read high, then the door is said to be in motion.
            The door's direction of motion is determined from the lastLimit variable.  If the lastLimit
            of the door is OPEN, then the currentState variable should be set to CLOSING.  If the 
            lastLimit of the door is CLOSED, then the currentState variable should be set to OPENING.
    * Checks for door obstructions and throws an error by checking the currentState and lastLimit 
      variables when the upper limit is reached.  If the upper limit is triggered and the currentState 
      is set to CLOSING and the lastLimit is set to OPEN, this should indicate that the door reversed 
      when closing and returned to the fully opened position.  The error state should only appear if 
      BOTH the lastLimit and currentState conditions match.  If lastLimit is OPEN and the lastState is 
      OPENING, this would indicate that the door was manually reversed.  This chech should only be 
      needed when the upper limit is reached.
    * Allows you to toggle the opener to either open or close the door.  When the door is toggled, the 
      currentState should be checked and if the state is either OPENING or CLOSING, the currentState 
      should invert telling that the door has changed direction.  This is done to prevent an error if 
      the door is reversed manually when closing.
    
    PARTS LIST:
    * Arduino pro mini
    * nRF24L01 radio module
    * AMS1117 3.3v regulator
    * 0.1uf capacitor
    * 10uf electrolytic capacitor
    * 4.7uf electrolytic capacitor (for radio module)
    * 5v reed relay
    * 2N3904 transistor for relay
    * 1k resistor
    * Two small signal diodes for incoming signals from door opener
    
    Wiring from garage door opener
    Yellow = Upper limit D7
    Brown = Lower limit D8
    Gray = Signal ground
    
    Relay D5
    */
    
    #include <SPI.h>
    #include <MySensor.h>
    #include <SimpleTimer.h>
    
    #define SKETCH_NAME "MyGarageDoor"
    #define SKETCH_VERSION "1.0"
    
    #define CHILD_ID 0
    
    #define UPPER_LIMIT_SENSOR 7  //Pin used for input from the garage door upper limit sensor
    #define LOWER_LIMIT_SENSOR 8  //Pin used for input from the garage door lower limit sensor
    #define DOOR_ACTUATOR_RELAY 5 //Pin used to toggle the door actuator relay
    #define RELAY_ON 1            // GPIO value to write to turn on attached relay
    #define RELAY_OFF 0           // GPIO value to write to turn off attached relay
    
    #define TOGGLE_INTERVAL 2000  //Tells how many milliseconds the relay will be held closed
    
    #define CLOSED 0
    #define OPEN 1
    #define CLOSING 2
    #define OPENING 3
    
    //const char *currentState[] = { "Closed", "Open", "Closing", "Opening" };
    
    int cState;     //Current state of the door
    int lState;     //Last state of the door
    int lLimit = 0; //The last full limit position of the door (open or closed)
    
    boolean obstruction = false; //Used for the error condition when the door is unexpectedly reversed
    
    SimpleTimer timer; //The timer object used for toggling the door opener
    
    MySensor gw;
    MyMessage msg(CHILD_ID, V_VAR1);
    
    /**
     * setup - Initialize the garage door sensor
     */
    void setup() { 
      pinMode(UPPER_LIMIT_SENSOR, INPUT);
      pinMode(LOWER_LIMIT_SENSOR, INPUT);
      pinMode(DOOR_ACTUATOR_RELAY, OUTPUT);
    
      Serial.println( SKETCH_NAME ); 
      gw.begin( incomingMessage, AUTO );
      
      gw.sendSketchInfo( SKETCH_NAME, SKETCH_VERSION );
      
      // Register the garage door sensor with the gateway
      gw.present( CHILD_ID, S_BINARY );
    
      //Get the current door state
      getState();
    }
    
    
    void loop() {
      // Alway process incoming messages whenever possible
      gw.process();
    
      //For every cycle while the door is opening or closing, we'll get the state of the door to see 
      //when the door has reached it's upper or lower limit.  Once the door has reached it's fully
      //open or fully closed position, we'll set the last limit to the current state
      if ( (cState == OPENING) || (cState == CLOSING) ) {
        getState();
        if ( (cState == OPEN) || (cState == CLOSED) ) {
          setLastLimit( cState );
        }
    
        //Here we check if the state has changed and update the gateway with the change.  We do this 
        //after all processing of the state because we need to know if there was an obstruction
        if (lState != cState) {
          gw.send( msg.set( obstruction == true ? -1 : cState ) );  //"obstr" : currentState[cState]);
        }
      }
    }
    
    void incomingMessage( const MyMessage &message ) {
      //We only expect one type of message from controller. But we better check anyway.
      if ( (message.type == V_STATUS) && (message.getBool() == RELAY_ON) ) {
         //Toggle the door opener
         toggleDoor();
      }
    }
    
    /**
     *toggleDoor - Used to activate the garage door opener
     */
    void toggleDoor() {
      digitalWrite( DOOR_ACTUATOR_RELAY, RELAY_ON );
      timer.setTimeout( TOGGLE_INTERVAL, relayOff );
    }
    
    /**
     *relayOff - Used to turn off the door opener relay after the TOGGLE_INTERVAL
     */
    void relayOff() {
      digitalWrite( DOOR_ACTUATOR_RELAY, RELAY_OFF );
    }
    
    /**
     *getState - Used to get the current state of the garage door.  This will set the cState variable
                 to either OPEN, CLOSED, OPENING and CLOSING
     */
    void getState() {
      int upper = digitalRead( UPPER_LIMIT_SENSOR ); //read the upper sensor
      int lower = digitalRead( LOWER_LIMIT_SENSOR ); //read the lower sensor
    
      //Save the last state of the door for later tests
      lState = cState;
    
      //Check if the door is open
      if ((upper == HIGH) && (lower == LOW)) {
        //Set the current state to open
        cState = OPEN;
      //Check if the door is closed
      } else if ((upper == LOW) && (lower == HIGH)) {
        //Set the current state to closed
        cState = CLOSED;
      //Check if the door is in motion
      } else if ((upper == HIGH) && (lower == HIGH)) {
        //If in motion and the last full position of the door was open
        if (lLimit == OPEN) {
          //Set the current state to closing
          cState = CLOSING;
        //If in motion and the last full position of the door was closed
        } else {
          //Set the current state to opening
          cState = OPENING;
        }
      }
    }
    
    void setLastLimit( int limit ) {
      //Here is where we check for our error condition
      if ( (lLimit == OPEN) && (limit == OPEN) && (lState == CLOSING) ) {
        //An obstruction has reversed the door.  No need to set the last limit because it already equals
        //the limit we are trying to set it to
        obstruction = true;
      //If we made it here and the last limit does not equal the limit we are setting then change it.  If
      //the last limit is equal to the limit we are setting then the last state was something other than 
      //closing, so we don't need to do anything.
      } else if ( lLimit != limit ) {
        //Everything okay, set the last limit
        lLimit = limit;
      }
    }
    

    My problem though is that when I compile it I get a warning:
    WARNING: Category '' in library UIPEthernet is not valid. Setting to 'Uncategorized'
    First off, the sketch in no way uses ethernet. Not even sure what UIPEthernet is, The googling I have done on this warning has led me to some posts that say that people using arduino 1.6.6 and I think even 1.6.7 have reverted back to 1.6.5 and their sketches compiled fine. I am running 1.6.9. I have not tried to find a version of 1.6.5 yet to see if that works, but before I do I have questions.
    First, is this a warning I need to worry about? The sketch compiles and uploads to the pro mini fine.
    Second, would there be any issues reverting to 1.6.5 while using MySensors 1.5?
    Third, could the issue be something with the MySensors library?

    Thanks

    1 Reply Last reply
    0
    • dbemowskD Offline
      dbemowskD Offline
      dbemowsk
      wrote on last edited by
      #19

      Garage door circuit
      So here is my circuit. It looks crude right now dangling from my door opener, but I have it working. I have the nRF24 radio on a bit of a pigtail because I am thinking that I may need to mount this somewhere outside the garage door opener housing. If I leave it inside the housing it will be completely enclosed in a metal shield and I am afraid that that may interfere with the radio.

      I had to modify my original sketch that I originally posted here quite a bit. Here is the modified working sketch.

      /*
        MyGarageDoor for MySensors
      
        Arduino garage door control
      
        June 16,2016
      
        This will allow the MySensors gateway to monitor and control your garagedoor opener.  This will
        monitor the internal upper and lower limit switches of the door openerto determine door position
        for status as well as have a relay switched output that can controleither the momentary contact
        switch connected to the door opener or wired directly to the switchcontacts of a door opener
        remote to activate the door.
      
        This sketch features the following:
      
        Allows you to monitor the door position and return it's status based on the following:
          1 - When either the upper or lower door limit switches are reached,the door is said to be
              either fully open or fully closed. When a limit switch is triggered, the lastLimit and
              currentState variables are set to either OPEN or CLOSED based on the limit switch that was
              triggered.
          2 - If the upper and lower limit inputs both read high, then the dooris said to be in motion.
              The door's direction of motion is determined from the lastLimit variable.  If the lastLimit
              of the door is OPEN, then the currentState variable should be setto CLOSING.  If the
              lastLimit of the door is CLOSED, then the currentState variable should be set to OPENING.
        Checks for door obstructions and throws an error by checking the currentState and lastLimit
        variables when the upper limit is reached.  If the upper limit is triggered and the currentState
        is set to CLOSING and the lastLimit is set to OPEN, this should indicate that the door reversed
        when closing and returned to the fully opened position.  The error state should only appear if
        BOTH the lastLimit and currentState conditions match.  If lastLimit isOPEN and the lastState is
        OPENING, this would indicate that the door was manually reversed.  This check should only be
        needed when the upper limit is reached.
        Allows you to toggle the opener to either open or close the door.  When the door is toggled, the
        currentState should be checked and if the state is either OPENING or CLOSING, the currentState
        should invert telling that the door has changed direction.  This is done to prevent an error if
        the door is reversed manually when closing.
      
        PARTS LIST:
        Arduino pro mini
        nRF24L01 radio module
        AMS1117 3.3v regulator
        0.1uf capacitor
        10uf electrolytic capacitor
        4.7uf electrolytic capacitor (for radio module)
        5v reed relay
        2N3904 transistor for relay
        1k resistor
        Two small signal diodes for incoming signals from door opener
      
        Wiring from garage door opener
        Yellow = Upper limit D7
        Brown = Lower limit D8
        Gray = Signal ground
      
        Relay D5
      */
      
      #include <SPI.h>
      #include <MySensor.h>
      #include <SimpleTimer.h>
      
      #define SKETCH_NAME "MyGarageDoor"
      #define SKETCH_VERSION "1.0"
      
      #define CHILD_ID 0
      
      #define UPPER_LIMIT_SENSOR 8  //Pin used for input from the garage door upper limit sensor
      #define LOWER_LIMIT_SENSOR 7  //Pin used for input from the garage door lower limit sensor
      #define DOOR_ACTUATOR_RELAY 5 //Pin used to toggle the door actuator relay
      #define RELAY_ON 1            // GPIO value to write to turn on attached relay
      #define RELAY_OFF 0           // GPIO value to write to turn off attached relay
      
      #define TOGGLE_INTERVAL 1000  //Tells how many milliseconds the relay will be held closed
      
      #define CLOSED 0
      #define OPEN 1
      #define CLOSING 2
      #define OPENING 3
      
      const char *currentState[] = { "Closed", "Open", "Closing", "Opening" };
      
      int cState;     //Current state of the door
      int lState;     //Last state of the door
      int lLimit = 0; //The last full limit position of the door (open or closed)
      
      boolean obstruction = false; //Used for the error condition when the door is unexpectedly reversed
      
      MySensor gw;
      MyMessage msg(CHILD_ID, V_VAR1);
      
      /**
         setup - Initialize the garage door sensor
      */
      void setup() {
      
        pinMode(UPPER_LIMIT_SENSOR, INPUT);
        pinMode(LOWER_LIMIT_SENSOR, INPUT);
        pinMode(DOOR_ACTUATOR_RELAY, OUTPUT);
      
        Serial.println( SKETCH_NAME );
        gw.begin( incomingMessage, AUTO );
      
        gw.sendSketchInfo( SKETCH_NAME, SKETCH_VERSION );
      
        // Register the garage door sensor with the gateway
        gw.present( CHILD_ID, S_BINARY );
      
        //Get the current door state
        getState();
      }
      
      
      void loop() {
      
        // Alway process incoming messages whenever possible
        gw.process();
      
        //Get the state of the door
        getState();
      
        //Here we check if the state has changed and update the gateway with the change.  We do this
        //after all processing of the state because we need to know if there was an obstruction
        if (lState != cState) {
          gw.send( msg.set( obstruction == true ? "OBSTRUCTION" : currentState[cState] ) ); 
      
          //Once the obstruction is checked and sent, we can clear it
          obstruction = false;
      
          //If the current state is full open or full closed we need to set the last limit
          if ( (cState == OPEN) || (cState == CLOSED) ) {
            setLastLimit( cState );
          }
        }
      
        if ( digitalRead( DOOR_ACTUATOR_RELAY ) == 1) {
          relayOff();
        }
      }
      
      void incomingMessage( const MyMessage &message ) {
      
        //We only expect one type of message from controller. But we better check anyway.
        if ( (message.type == V_STATUS) && (message.getBool() == RELAY_ON) ) {
          //Toggle the door opener
          toggleDoor();
        }
      }
      
      /**
        toggleDoor - Used to activate the garage door opener
      */
      void toggleDoor() {
      
        digitalWrite( DOOR_ACTUATOR_RELAY, RELAY_ON );
        //Keep the relay on for the amount of time defined by TOGGLE_INTERVAL
        delay( TOGGLE_INTERVAL );
      }
      
      /**
        relayOff - Used to turn off the door opener relay after the TOGGLE_INTERVAL
      */
      void relayOff() {
      
        digitalWrite( DOOR_ACTUATOR_RELAY, RELAY_OFF );
      }
      
      /**
        getState - Used to get the current state of the garage door.  This will set the cState variable
                   to either OPEN, CLOSED, OPENING and CLOSING
      */
      void getState() {
        int upper = digitalRead( UPPER_LIMIT_SENSOR ); //read the upper sensor
        int lower = digitalRead( LOWER_LIMIT_SENSOR ); //read the lower sensor
      
        //Save the last state of the door for later tests
        lState = cState;
      
        //Check if the door is open
        if ((upper == HIGH) && (lower == LOW)) {
          //Set the current state to open
          cState = OPEN;
          //Check if the door is closed
        } else if ((upper == LOW) && (lower == HIGH)) {
          //Set the current state to closed
          cState = CLOSED;
          //Check if the door is in motion
        } else if ((upper == HIGH) && (lower == HIGH)) {
          //If in motion and the last full position of the door was open
          if (lLimit == OPEN) {
            //Set the current state to closing
            cState = CLOSING;
            //If in motion and the last full position of the door was closed
          } else {
            //Set the current state to opening
            cState = OPENING;
          }
        }
      }
      
      void setLastLimit( int limit ) {
        //Here is where we check for our error condition
        if ( (lLimit == OPEN) && (limit == OPEN) && (lState == CLOSING) ) {
          //An obstruction has reversed the door.  No need to set the last limit because it already equals
          //the limit we are trying to set it to
          obstruction = true;
          //If we made it here and the last limit does not equal the limit we are setting then change it.  If
          //the last limit is equal to the limit we are setting then the last state was something other than
          //closing, so we don't need to do anything.
        } else if ( lLimit != limit ) {
          //Everything okay, set the last limit
          lLimit = limit;
          obstruction = false;
        }
      }
      

      Here are some results as seen by MYSController

      6/25/2016 23:16:22      TX      1;0;1;0;2;1
      6/25/2016 23:16:22      RX      0;0;3;0;9;send: 0-0-1-1 s=0,c=1,t=2,pt=0,l=1,sg=0,st=ok:1
      6/25/2016 23:16:23      RX      0;0;3;0;9;read: 1-1-0 s=0,c=1,t=24,pt=0,l=7,sg=0:Opening
      6/25/2016 23:16:23      RX      1;0;1;0;24;Opening
      6/25/2016 23:16:34      RX      0;0;3;0;9;read: 1-1-0 s=0,c=1,t=24,pt=0,l=4,sg=0:Open
      6/25/2016 23:16:34      RX      1;0;1;0;24;Open
      6/25/2016 23:16:39      TX      1;0;1;0;2;1
      6/25/2016 23:16:39      RX      0;0;3;0;9;send: 0-0-1-1 s=0,c=1,t=2,pt=0,l=1,sg=0,st=ok:1
      6/25/2016 23:16:40      RX      0;0;3;0;9;read: 1-1-0 s=0,c=1,t=24,pt=0,l=7,sg=0:Closing
      6/25/2016 23:16:40      RX      1;0;1;0;24;Closing
      6/25/2016 23:16:50      RX      0;0;3;0;9;read: 1-1-0 s=0,c=1,t=24,pt=0,l=6,sg=0:Closed
      6/25/2016 23:16:50      RX      1;0;1;0;24;Closed
      6/25/2016 23:19:18      TX      1;0;1;0;2;1
      6/25/2016 23:19:18      RX      0;0;3;0;9;send: 0-0-1-1 s=0,c=1,t=2,pt=0,l=1,sg=0,st=ok:1
      6/25/2016 23:19:19      RX      0;0;3;0;9;read: 1-1-0 s=0,c=1,t=24,pt=0,l=7,sg=0:Opening
      6/25/2016 23:19:19      RX      1;0;1;0;24;Opening
      6/25/2016 23:19:29      RX      0;0;3;0;9;read: 1-1-0 s=0,c=1,t=24,pt=0,l=4,sg=0:Open
      6/25/2016 23:19:29      RX      1;0;1;0;24;Open
      6/25/2016 23:19:42      TX      1;0;1;0;2;1
      6/25/2016 23:19:42      RX      0;0;3;0;9;send: 0-0-1-1 s=0,c=1,t=2,pt=0,l=1,sg=0,st=ok:1
      

      Overall I think it turned out good for my first sensor. Now I just need to figure out how to tidy things up and get the garage door opener case put back together with everything inside and somehow protect the wires and things from the gears (only one of real concern). I am thinking a few zip ties.

      The next step will be getting my Orange Pi to work with Domoticz and controlling MySensor devices.

      1 Reply Last reply
      1
      • dbemowskD Offline
        dbemowskD Offline
        dbemowsk
        wrote on last edited by dbemowsk
        #20

        So I finally got a sketch that gives me all of the functions that I need for my garage door. The two main things that I needed were a way to toggle the door opener, and a way to display the current state of the door in Domoticz. Getting to the door to toggle open and closed was easy. The hard part was getting Domoticz to display the state of the door. I was told by @AWI that I needed a V_TEXT variable and a S_TEXT sencode:sor type. He mentioned that these were not available in version 1.5, but they could be added manually in your sketch by adding these lines of code to your sketch:

        // new V_TEXT variable type (development 20150905)
        const int V_TEXT = 47 ;
        // new S_INFO sensor type (development 20150905)
        const int S_INFO = 36 ;
        

        Here is the final working sketch:

         /*
          MyGarageDoor for MySensors
        
          Arduino garage door control
        
          June 16,2016
        
          This will allow the MySensors gateway to monitor and control your garage door opener.  This will
          monitor the internal upper and lower limit switches of the door opener to determine door position
          for status as well as have a relay switched output that can control either the momentary contact
          switch connected to the door opener or wired directly to the switch contacts of a door opener
          remote to activate the door.
        
          This sketch features the following:
        
          Allows you to monitor the door position and return it's status based on the following:
            1 - When either the upper or lower door limit switches are reached, the door is said to be
                either fully open or fully closed. When a limit switch is triggered, the lastLimit and
                currentState variables are set to either OPEN or CLOSED based on the limit switch that was
                triggered.
            2 - If the upper and lower limit inputs both read high, then the door is said to be in motion.
                The door's direction of motion is determined from the lastLimit variable.  If the lastLimit
                of the door is OPEN, then the currentState variable should be set to CLOSING.  If the
                lastLimit of the door is CLOSED, then the currentState variable should be set to OPENING.
          Checks for door obstructions and throws an error by checking the currentState and lastLimit
          variables when the upper limit is reached.  If the upper limit is triggered and the currentState
          is set to CLOSING and the lastLimit is set to OPEN, this should indicate that the door reversed
          when closing and returned to the fully opened position.  The error state should only appear if
          BOTH the lastLimit and currentState conditions match.  If lastLimit is OPEN and the lastState is
          OPENING, this would indicate that the door was manually reversed.  This chech should only be
          needed when the upper limit is reached.
          Allows you to toggle the opener to either open or close the door.  When the door is toggled, the
          currentState should be checked and if the state is either OPENING or CLOSING, the currentState
          should invert telling that the door has changed direction.  This is done to prevent an error if
          the door is reversed manually when closing.
        
          PARTS LIST:
          Arduino pro mini
          nRF24L01 radio module
          AMS1117 3.3v regulator
          0.1uf capacitor
          10uf electrolytic capacitor
          4.7uf electrolytic capacitor (for radio module)
          5v reed relay
          2N3904 transistor for relay
          1k resistor
          Two small signal diodes for incoming signals from door opener
        
          Wiring from garage door opener
          Yellow = Upper limit D7
          Brown = Lower limit D8
          Gray = Signal ground
        
          Relay D5
        
          Version history:
          1.1 : Added the V_TEXT variable and S_INFO sensor type, and created the "Status" child
        */
        
        #include <SPI.h>
        #include <MySensor.h>
        
        #define SKETCH_NAME "MyGarageDoor"
        #define SKETCH_VERSION "1.1"
        
        #define CHILD_ID_OPENER 0
        #define CHILD_ID_STATUS 1
        
        #define UPPER_LIMIT_SENSOR 8  //Pin used for input from the garage door upper limit sensor
        #define LOWER_LIMIT_SENSOR 7  //Pin used for input from the garage door lower limit sensor
        #define DOOR_ACTUATOR_RELAY 5 //Pin used to toggle the door actuator relay
        #define RELAY_ON 1            // GPIO value to write to turn on attached relay
        #define RELAY_OFF 0           // GPIO value to write to turn off attached relay
        
        #define TOGGLE_INTERVAL 1000  //Tells how many milliseconds the relay will be held closed
        
        #define CLOSED 0
        #define OPEN 1
        #define CLOSING 2
        #define OPENING 3
        
        // new V_TEXT variable type (development 20150905)
        const int V_TEXT = 47 ;
        // new S_INFO sensor type (development 20150905)
        const int S_INFO = 36 ;
        
        const char *currentState[] = { "Closed", "Open", "Closing", "Opening" };
        
        //Current state of the door
        int cState;     
        
        //Last state of the door
        int lState;     
        
        //The last full limit position of the door (open or closed)
        int lLimit = 0; 
        
        //Used for the error condition when the door is unexpectedly reversed
        boolean obstruction = false;
        
        MySensor gw;
        MyMessage msgOpener(CHILD_ID_OPENER, V_STATUS);
        MyMessage msgStatus(CHILD_ID_STATUS, V_TEXT);
        
        /**
         * setup - Initialize the garage door sensor
         */
        void setup() {
          
          pinMode(UPPER_LIMIT_SENSOR, INPUT);
          pinMode(LOWER_LIMIT_SENSOR, INPUT);
          pinMode(DOOR_ACTUATOR_RELAY, OUTPUT);
        
          Serial.println( SKETCH_NAME );
          gw.begin( incomingMessage, AUTO );
        
          gw.sendSketchInfo( SKETCH_NAME, SKETCH_VERSION );
        
          // Register the garage door sensor with the gateway
          gw.present( CHILD_ID_OPENER, S_BINARY );
          gw.present( CHILD_ID_STATUS, S_INFO );
        }
        
        /**
         * loop - The main program loop
         */
        void loop() {
          
          // Alway process incoming messages whenever possible
          gw.process();
        
          //Get the state of the door
          getState();
        
          //Here we check if the state has changed and update the gateway with the change.  We do this
          //after all processing of the state because we need to know if there was an obstruction
          if (lState != cState) {
            gw.send( msgStatus.set( obstruction == true ? "OBSTRUCTION" : currentState[cState] ) );  
        
            //Once the obstruction is checked and sent, we can clear it
            obstruction = false;
        
            //If the current state is full open or full closed we need to set the last limit
            if ( (cState == OPEN) || (cState == CLOSED) ) {
              setLastLimit( cState );
            }
          }
        
          //If the relay is on, shut it off
          if ( digitalRead( DOOR_ACTUATOR_RELAY ) == 1) {
            relayOff();                       
          }
        }
        
        /**
         * incomingMessage - Process the incoming messages and watch for an incoming boolean 1
         *                   to toggle the garage door opener.
         */
        void incomingMessage( const MyMessage &message ) {
          
          //We only expect one type of message from controller. But we better check anyway.
          if ( (message.type == V_STATUS) && (message.getBool() == RELAY_ON) ) {
            //Toggle the door opener
            toggleDoor();
          }
        }
        
        /**
         * toggleDoor - Used to activate the garage door opener
         */
        void toggleDoor() {
        
          digitalWrite( DOOR_ACTUATOR_RELAY, RELAY_ON );
          //Keep the relay on for the amount of time defined by TOGGLE_INTERVAL
          delay( TOGGLE_INTERVAL );
        }
        
        /**
         * relayOff - Used to turn off the door opener relay after the TOGGLE_INTERVAL
         */
        void relayOff() {
        
          digitalWrite( DOOR_ACTUATOR_RELAY, RELAY_OFF );
          //Added this to tell the controller that we shut off the relay
          gw.send( msgOpener.set(0) );
        }
        
        /**
         * getState - Used to get the current state of the garage door.  This will set the cState variable
         *            to either OPEN, CLOSED, OPENING and CLOSING
         */
        void getState() {
          int upper = digitalRead( UPPER_LIMIT_SENSOR ); //read the upper sensor
          int lower = digitalRead( LOWER_LIMIT_SENSOR ); //read the lower sensor
        
          //Save the last state of the door for later tests
          lState = cState;
        
          //Check if the door is open
          if ((upper == HIGH) && (lower == LOW)) {
            //Set the current state to open
            cState = OPEN;
            //Check if the door is closed
          } else if ((upper == LOW) && (lower == HIGH)) {
            //Set the current state to closed
            cState = CLOSED;
            //Check if the door is in motion
          } else if ((upper == HIGH) && (lower == HIGH)) {
            //If in motion and the last full position of the door was open
            if (lLimit == OPEN) {
              //Set the current state to closing
              cState = CLOSING;
              //If in motion and the last full position of the door was closed
            } else {
              //Set the current state to opening
              cState = OPENING;
            }
          }
        }
        
        /**
         * setLastLimit - Checks the limit passed with the last limit (lLimit) and sets the last limit
         *                if there was a change.  It also checks the states against the limits and issues 
         *                an obstruction error if the limit and last limit
         *                
         * @param limit  integer limit - The limit to be checked
         */
        void setLastLimit( int limit ) {
          //Here is where we check for our error condition
          if ( (lLimit == OPEN) && (limit == OPEN) && (lState == CLOSING) ) {
            //An obstruction has reversed the door.  No need to set the last limit because it already equals
            //the limit we are trying to set it to
            obstruction = true;
            //If we made it here and the last limit does not equal the limit we are setting then change it.  If
            //the last limit is equal to the limit we are setting then the last state was something other than
            //closing, so we don't need to do anything.
          } else if ( lLimit != limit ) {
            //Everything okay, set the last limit
            lLimit = limit;
            obstruction = false;
          }
        }
        
        D 1 Reply Last reply
        0
        • dbemowskD Offline
          dbemowskD Offline
          dbemowsk
          wrote on last edited by
          #21
          This post is deleted!
          1 Reply Last reply
          0
          • dbemowskD dbemowsk

            So I finally got a sketch that gives me all of the functions that I need for my garage door. The two main things that I needed were a way to toggle the door opener, and a way to display the current state of the door in Domoticz. Getting to the door to toggle open and closed was easy. The hard part was getting Domoticz to display the state of the door. I was told by @AWI that I needed a V_TEXT variable and a S_TEXT sencode:sor type. He mentioned that these were not available in version 1.5, but they could be added manually in your sketch by adding these lines of code to your sketch:

            // new V_TEXT variable type (development 20150905)
            const int V_TEXT = 47 ;
            // new S_INFO sensor type (development 20150905)
            const int S_INFO = 36 ;
            

            Here is the final working sketch:

             /*
              MyGarageDoor for MySensors
            
              Arduino garage door control
            
              June 16,2016
            
              This will allow the MySensors gateway to monitor and control your garage door opener.  This will
              monitor the internal upper and lower limit switches of the door opener to determine door position
              for status as well as have a relay switched output that can control either the momentary contact
              switch connected to the door opener or wired directly to the switch contacts of a door opener
              remote to activate the door.
            
              This sketch features the following:
            
              Allows you to monitor the door position and return it's status based on the following:
                1 - When either the upper or lower door limit switches are reached, the door is said to be
                    either fully open or fully closed. When a limit switch is triggered, the lastLimit and
                    currentState variables are set to either OPEN or CLOSED based on the limit switch that was
                    triggered.
                2 - If the upper and lower limit inputs both read high, then the door is said to be in motion.
                    The door's direction of motion is determined from the lastLimit variable.  If the lastLimit
                    of the door is OPEN, then the currentState variable should be set to CLOSING.  If the
                    lastLimit of the door is CLOSED, then the currentState variable should be set to OPENING.
              Checks for door obstructions and throws an error by checking the currentState and lastLimit
              variables when the upper limit is reached.  If the upper limit is triggered and the currentState
              is set to CLOSING and the lastLimit is set to OPEN, this should indicate that the door reversed
              when closing and returned to the fully opened position.  The error state should only appear if
              BOTH the lastLimit and currentState conditions match.  If lastLimit is OPEN and the lastState is
              OPENING, this would indicate that the door was manually reversed.  This chech should only be
              needed when the upper limit is reached.
              Allows you to toggle the opener to either open or close the door.  When the door is toggled, the
              currentState should be checked and if the state is either OPENING or CLOSING, the currentState
              should invert telling that the door has changed direction.  This is done to prevent an error if
              the door is reversed manually when closing.
            
              PARTS LIST:
              Arduino pro mini
              nRF24L01 radio module
              AMS1117 3.3v regulator
              0.1uf capacitor
              10uf electrolytic capacitor
              4.7uf electrolytic capacitor (for radio module)
              5v reed relay
              2N3904 transistor for relay
              1k resistor
              Two small signal diodes for incoming signals from door opener
            
              Wiring from garage door opener
              Yellow = Upper limit D7
              Brown = Lower limit D8
              Gray = Signal ground
            
              Relay D5
            
              Version history:
              1.1 : Added the V_TEXT variable and S_INFO sensor type, and created the "Status" child
            */
            
            #include <SPI.h>
            #include <MySensor.h>
            
            #define SKETCH_NAME "MyGarageDoor"
            #define SKETCH_VERSION "1.1"
            
            #define CHILD_ID_OPENER 0
            #define CHILD_ID_STATUS 1
            
            #define UPPER_LIMIT_SENSOR 8  //Pin used for input from the garage door upper limit sensor
            #define LOWER_LIMIT_SENSOR 7  //Pin used for input from the garage door lower limit sensor
            #define DOOR_ACTUATOR_RELAY 5 //Pin used to toggle the door actuator relay
            #define RELAY_ON 1            // GPIO value to write to turn on attached relay
            #define RELAY_OFF 0           // GPIO value to write to turn off attached relay
            
            #define TOGGLE_INTERVAL 1000  //Tells how many milliseconds the relay will be held closed
            
            #define CLOSED 0
            #define OPEN 1
            #define CLOSING 2
            #define OPENING 3
            
            // new V_TEXT variable type (development 20150905)
            const int V_TEXT = 47 ;
            // new S_INFO sensor type (development 20150905)
            const int S_INFO = 36 ;
            
            const char *currentState[] = { "Closed", "Open", "Closing", "Opening" };
            
            //Current state of the door
            int cState;     
            
            //Last state of the door
            int lState;     
            
            //The last full limit position of the door (open or closed)
            int lLimit = 0; 
            
            //Used for the error condition when the door is unexpectedly reversed
            boolean obstruction = false;
            
            MySensor gw;
            MyMessage msgOpener(CHILD_ID_OPENER, V_STATUS);
            MyMessage msgStatus(CHILD_ID_STATUS, V_TEXT);
            
            /**
             * setup - Initialize the garage door sensor
             */
            void setup() {
              
              pinMode(UPPER_LIMIT_SENSOR, INPUT);
              pinMode(LOWER_LIMIT_SENSOR, INPUT);
              pinMode(DOOR_ACTUATOR_RELAY, OUTPUT);
            
              Serial.println( SKETCH_NAME );
              gw.begin( incomingMessage, AUTO );
            
              gw.sendSketchInfo( SKETCH_NAME, SKETCH_VERSION );
            
              // Register the garage door sensor with the gateway
              gw.present( CHILD_ID_OPENER, S_BINARY );
              gw.present( CHILD_ID_STATUS, S_INFO );
            }
            
            /**
             * loop - The main program loop
             */
            void loop() {
              
              // Alway process incoming messages whenever possible
              gw.process();
            
              //Get the state of the door
              getState();
            
              //Here we check if the state has changed and update the gateway with the change.  We do this
              //after all processing of the state because we need to know if there was an obstruction
              if (lState != cState) {
                gw.send( msgStatus.set( obstruction == true ? "OBSTRUCTION" : currentState[cState] ) );  
            
                //Once the obstruction is checked and sent, we can clear it
                obstruction = false;
            
                //If the current state is full open or full closed we need to set the last limit
                if ( (cState == OPEN) || (cState == CLOSED) ) {
                  setLastLimit( cState );
                }
              }
            
              //If the relay is on, shut it off
              if ( digitalRead( DOOR_ACTUATOR_RELAY ) == 1) {
                relayOff();                       
              }
            }
            
            /**
             * incomingMessage - Process the incoming messages and watch for an incoming boolean 1
             *                   to toggle the garage door opener.
             */
            void incomingMessage( const MyMessage &message ) {
              
              //We only expect one type of message from controller. But we better check anyway.
              if ( (message.type == V_STATUS) && (message.getBool() == RELAY_ON) ) {
                //Toggle the door opener
                toggleDoor();
              }
            }
            
            /**
             * toggleDoor - Used to activate the garage door opener
             */
            void toggleDoor() {
            
              digitalWrite( DOOR_ACTUATOR_RELAY, RELAY_ON );
              //Keep the relay on for the amount of time defined by TOGGLE_INTERVAL
              delay( TOGGLE_INTERVAL );
            }
            
            /**
             * relayOff - Used to turn off the door opener relay after the TOGGLE_INTERVAL
             */
            void relayOff() {
            
              digitalWrite( DOOR_ACTUATOR_RELAY, RELAY_OFF );
              //Added this to tell the controller that we shut off the relay
              gw.send( msgOpener.set(0) );
            }
            
            /**
             * getState - Used to get the current state of the garage door.  This will set the cState variable
             *            to either OPEN, CLOSED, OPENING and CLOSING
             */
            void getState() {
              int upper = digitalRead( UPPER_LIMIT_SENSOR ); //read the upper sensor
              int lower = digitalRead( LOWER_LIMIT_SENSOR ); //read the lower sensor
            
              //Save the last state of the door for later tests
              lState = cState;
            
              //Check if the door is open
              if ((upper == HIGH) && (lower == LOW)) {
                //Set the current state to open
                cState = OPEN;
                //Check if the door is closed
              } else if ((upper == LOW) && (lower == HIGH)) {
                //Set the current state to closed
                cState = CLOSED;
                //Check if the door is in motion
              } else if ((upper == HIGH) && (lower == HIGH)) {
                //If in motion and the last full position of the door was open
                if (lLimit == OPEN) {
                  //Set the current state to closing
                  cState = CLOSING;
                  //If in motion and the last full position of the door was closed
                } else {
                  //Set the current state to opening
                  cState = OPENING;
                }
              }
            }
            
            /**
             * setLastLimit - Checks the limit passed with the last limit (lLimit) and sets the last limit
             *                if there was a change.  It also checks the states against the limits and issues 
             *                an obstruction error if the limit and last limit
             *                
             * @param limit  integer limit - The limit to be checked
             */
            void setLastLimit( int limit ) {
              //Here is where we check for our error condition
              if ( (lLimit == OPEN) && (limit == OPEN) && (lState == CLOSING) ) {
                //An obstruction has reversed the door.  No need to set the last limit because it already equals
                //the limit we are trying to set it to
                obstruction = true;
                //If we made it here and the last limit does not equal the limit we are setting then change it.  If
                //the last limit is equal to the limit we are setting then the last state was something other than
                //closing, so we don't need to do anything.
              } else if ( lLimit != limit ) {
                //Everything okay, set the last limit
                lLimit = limit;
                obstruction = false;
              }
            }
            
            D Offline
            D Offline
            Dringie
            wrote on last edited by
            #22

            @dbemowsk Thanks for sharing

            1 Reply Last reply
            0
            • dbemowskD Offline
              dbemowskD Offline
              dbemowsk
              wrote on last edited by
              #23

              @Dringie The only thing I think that I am going to add for now is to turn this on as a repeater node. I have this wired for power with an old modified wall brick cell phone charger that was 5 volts, so it will be powered all the time. I think it is a good place for a repeater anyway. If you find any problems or can suggest any improvements, I am all ears.

              1 Reply Last reply
              0
              • D Offline
                D Offline
                Dringie
                wrote on last edited by
                #24

                I will also use signing when I get round to building this node.

                Waiting for the signing chips from China.

                I might add a relay for lights, so the lights come on at night when opened. (Night lua code to be used in domoticz).

                Postman feature is something I'm going over in my head. E.g.. When postman delivers a parcel I can remotely open the garage slightly and it close again after 30 secs. Not sure if I want to write code in the node or in Domoticz. I think the node would be more fail proof.

                dbemowskD 1 Reply Last reply
                0
                • D Dringie

                  I will also use signing when I get round to building this node.

                  Waiting for the signing chips from China.

                  I might add a relay for lights, so the lights come on at night when opened. (Night lua code to be used in domoticz).

                  Postman feature is something I'm going over in my head. E.g.. When postman delivers a parcel I can remotely open the garage slightly and it close again after 30 secs. Not sure if I want to write code in the node or in Domoticz. I think the node would be more fail proof.

                  dbemowskD Offline
                  dbemowskD Offline
                  dbemowsk
                  wrote on last edited by
                  #25

                  @Dringie What type of garage door opener do you have?

                  D 1 Reply Last reply
                  0
                  • dbemowskD dbemowsk

                    @Dringie What type of garage door opener do you have?

                    D Offline
                    D Offline
                    Dringie
                    wrote on last edited by
                    #26

                    @dbemowsk

                    Hormann motor, 3 section up and over door. I have placed position magnet sensors on the door runner.

                    My door works like yours with obstacles.

                    I will wire my node straight into the motor.

                    For the postman feature, I was going to add an extra reed switch on the runner to stop the door at a low hight.

                    1 Reply Last reply
                    0
                    • dbemowskD Offline
                      dbemowskD Offline
                      dbemowsk
                      wrote on last edited by
                      #27

                      I had some problems using magnetic reed switches with my old HA setup. My main problem was that when the door would open, it would not always stop in the same spot. It was close to that spot, but enough off where the magnet wouldn't register. That was why I dug into the opener to find the limit switches. Going that route has been a ton more reliable since I am getting the state right from where the door opener tells the door to stop.See my very first pic in this post.

                      1 Reply Last reply
                      0
                      • cliffordbakerC Offline
                        cliffordbakerC Offline
                        cliffordbaker
                        wrote on last edited by
                        #28

                        The idea of using relay is good as relay control one electrical circuit by opening and closing contacts in another circuit. In the programing model try to give a trigger input. This would work.

                        1 Reply Last reply
                        0
                        • dbemowskD Offline
                          dbemowskD Offline
                          dbemowsk
                          wrote on last edited by
                          #29

                          For those interested, I have updated my sketch for my garage door controller to MySensors 2.0.

                           /*
                            MyGarageDoor for MySensors
                          
                            Arduino garage door control
                          
                            Originally built for MySensors 1.5 June 16,2016
                            Updated to MySensors 2.0 October 21, 2016
                          
                            This will allow the MySensors gateway to monitor and control your garage door opener.  This will
                            monitor the internal upper and lower limit switches of the door opener to determine door position
                            for status as well as have a relay switched output that can control either the momentary contact
                            switch connected to the door opener or wired directly to the switch contacts of a door opener
                            remote to activate the door.
                          
                            This sketch features the following:
                          
                            Allows you to monitor the door position and return it's status based on the following:
                              1 - When either the upper or lower door limit switches are reached, the door is said to be
                                  either fully open or fully closed. When a limit switch is triggered, the lastLimit and
                                  currentState variables are set to either OPEN or CLOSED based on the limit switch that was
                                  triggered.
                              2 - If the upper and lower limit inputs both read high, then the door is said to be in motion.
                                  The door's direction of motion is determined from the lastLimit variable.  If the lastLimit
                                  of the door is OPEN, then the currentState variable should be set to CLOSING.  If the
                                  lastLimit of the door is CLOSED, then the currentState variable should be set to OPENING.
                            Checks for door obstructions and throws an error by checking the currentState and lastLimit
                            variables when the upper limit is reached.  If the upper limit is triggered and the currentState
                            is set to CLOSING and the lastLimit is set to OPEN, this should indicate that the door reversed
                            when closing and returned to the fully opened position.  The error state should only appear if
                            BOTH the lastLimit and currentState conditions match.  If lastLimit is OPEN and the lastState is
                            OPENING, this would indicate that the door was manually reversed.  This chech should only be
                            needed when the upper limit is reached.
                            Allows you to toggle the opener to either open or close the door.  When the door is toggled, the
                            currentState should be checked and if the state is either OPENING or CLOSING, the currentState
                            should invert telling that the door has changed direction.  This is done to prevent an error if
                            the door is reversed manually when closing.
                          
                            PARTS LIST:
                            Arduino pro mini
                            nRF24L01 radio module
                            AMS1117 3.3v regulator
                            0.1uf capacitor
                            10uf electrolytic capacitor
                            4.7uf electrolytic capacitor (for radio module)
                            5v reed relay
                            2N3904 transistor for relay
                            1k resistor
                            Two small signal diodes for incoming signals from door opener
                          
                            Wiring from garage door opener
                            Yellow = Upper limit D7
                            Brown = Lower limit D8
                            Gray = Signal ground
                          
                            Relay D5
                          
                            Version history:
                            1.1 : Added the V_TEXT variable and S_INFO sensor type, and created the "Status" child
                            1.2 : Added the heartbeat signal to tell the controller that the sensor is still alive.
                                  Scripting or other code must be used on the HA controller side to react to the 
                                  heartbeat signal and take appropriate action.
                            2.0 : Converted to MySensors 2.0
                          */
                          
                          //Set up the nRF24L01+
                          #define MY_RADIO_NRF24
                          
                          #include <SPI.h>
                          #include <MySensors.h>
                          #include <SimpleTimer.h>
                          
                          #define SKETCH_NAME "MyGarageDoor"
                          #define SKETCH_VERSION "1.2"
                          
                          #define CHILD_ID_OPENER 0
                          #define CHILD_ID_STATUS 1
                          
                          #define UPPER_LIMIT_SENSOR 6  //Pin used for input from the garage door upper limit sensor
                          #define LOWER_LIMIT_SENSOR 7  //Pin used for input from the garage door lower limit sensor
                          #define DOOR_ACTUATOR_RELAY 5 //Pin used to toggle the door actuator relay
                          #define RELAY_ON 1            // GPIO value to write to turn on attached relay
                          #define RELAY_OFF 0           // GPIO value to write to turn off attached relay
                          
                          #define TOGGLE_INTERVAL 1500  //Tells how many milliseconds the relay will be held closed
                          #define HEARTBEAT_INTERVAL 120000 //Number of miliseconds before the next heartbeat
                          
                          #define CLOSED 0
                          #define OPEN 1
                          #define CLOSING 2
                          #define OPENING 3
                          
                          #define OBSTR_MAX 20
                          
                          const char *currentState[] = { 
                                                       "Closed", 
                                                       "Open", 
                                                       "Closing", 
                                                       "Opening" 
                                                       };
                          
                          //Current state of the door
                          int cState;     
                          
                          //Last state of the door
                          int lState;     
                          
                          //The last full limit position of the door (open or closed)
                          int lLimit = 0; 
                          
                          //Used for the error condition when the door is unexpectedly reversed
                          boolean obstruction = false;
                          
                          int obstruction_count = 0;
                          
                          // the timer object used for the heartbeat
                          SimpleTimer heartbeat;
                          
                          MyMessage msgOpener(CHILD_ID_OPENER, V_STATUS);
                          MyMessage msgStatus(CHILD_ID_STATUS, V_TEXT);
                          
                          /**
                           * presentation - Present the garage door sensor
                           */
                          void presentation() {
                            
                            sendSketchInfo( SKETCH_NAME, SKETCH_VERSION );
                            
                            // Register the garage door sensor with the gateway
                            present( CHILD_ID_OPENER, S_BINARY );
                            present( CHILD_ID_STATUS, S_INFO );
                            
                          } //End presentation
                          
                          /**
                           * setup - Initialize the garage door sensor
                           */
                          void setup() {
                          
                            // Set up the pins for reading the upper and lower limit sensors
                            pinMode(UPPER_LIMIT_SENSOR, INPUT);
                            pinMode(LOWER_LIMIT_SENSOR, INPUT);
                            // Set up the pin to control the door opener
                            pinMode(DOOR_ACTUATOR_RELAY, OUTPUT);
                          
                            Serial.println( SKETCH_NAME );
                          
                            // Set the heartbeat timer to send the current state at the set interval
                            heartbeat.setInterval(HEARTBEAT_INTERVAL, sendCurrentState);
                            
                          } //End setup
                          
                          /**
                           * loop - The main program loop
                           */
                          void loop() {
                          
                            //Get the state of the door
                            getState();
                          
                            //Here we check if the state has changed and update the gateway with the change.  We do this
                            //after all processing of the state because we need to know if there was an obstruction
                            if ((lState != cState) || obstruction == true) {
                              sendCurrentState();
                          
                              obstruction_count ++;
                              if (obstruction_count >= OBSTR_MAX) {
                                //Once the obstruction is checked and sent, we can clear it
                                obstruction = false;
                              }
                          
                              //If the current state is full open or full closed we need to set the last limit
                              if ( (cState == OPEN) || (cState == CLOSED) ) {
                                setLastLimit( cState );
                              }
                            }
                          
                            //If the relay is on, shut it off
                            if ( digitalRead( DOOR_ACTUATOR_RELAY ) == 1) {
                              relayOff();                       
                            }
                            
                            heartbeat.run();
                            
                          } //End loop
                          
                          /**
                           * receive - Process the incoming messages and watch for an incoming boolean 1
                           *           to toggle the garage door opener.
                           */
                          void receive( const MyMessage &message ) {
                            
                            //We only expect one type of message from controller. But we better check anyway.
                            if ( (message.type == V_STATUS) && (message.getBool() == RELAY_ON) ) {
                              //Toggle the door opener
                              toggleDoor();
                            }
                            
                          } //End receive
                          
                          /**
                           * sendCurrentState - Sends the current state back to the gateway
                           */
                          void sendCurrentState() {
                            
                              send( msgStatus.set( obstruction == true ? "OBSTRUCTION" : currentState[cState] ) ); 
                              
                          } //End sendCurrentState
                          
                          /**
                           * toggleDoor - Used to activate the garage door opener
                           */
                          void toggleDoor() {
                          
                            digitalWrite( DOOR_ACTUATOR_RELAY, RELAY_ON );
                            //Keep the relay on for the amount of time defined by TOGGLE_INTERVAL
                            delay( TOGGLE_INTERVAL );
                            
                          } //End toggleDoor
                          
                          /**
                           * relayOff - Used to turn off the door opener relay after the TOGGLE_INTERVAL
                           */
                          void relayOff() {
                          
                            digitalWrite( DOOR_ACTUATOR_RELAY, RELAY_OFF );
                            //Added this to tell the controller that we shut off the relay
                            send( msgOpener.set(0) );
                            
                          } //End relayOff
                          
                          /**
                           * getState - Used to get the current state of the garage door.  This will set the cState variable
                           *            to either OPEN, CLOSED, OPENING and CLOSING
                           */
                          void getState() {
                          
                            //read the upper sensor
                            int upper = digitalRead( UPPER_LIMIT_SENSOR ); 
                            //read the lower sensor
                            int lower = digitalRead( LOWER_LIMIT_SENSOR ); 
                          
                            //Save the last state of the door for later tests
                            lState = cState;
                          
                            //Check if the door is open
                            if ((upper == HIGH) && (lower == LOW)) {
                              //Set the current state to open
                              cState = OPEN;
                              //Check if the door is closed
                            } else if ((upper == LOW) && (lower == HIGH)) {
                              //Set the current state to closed
                              cState = CLOSED;
                              //Check if the door is in motion
                            } else if ((upper == HIGH) && (lower == HIGH)) {
                              //If in motion and the last full position of the door was open
                              if (lLimit == OPEN) {
                                //Set the current state to closing
                                cState = CLOSING;
                                //If in motion and the last full position of the door was closed
                              } else {
                                //Set the current state to opening
                                cState = OPENING;
                              }
                            }
                            
                          } //End getState
                          
                          /**
                           * setLastLimit - Checks the limit passed with the last limit (lLimit) and sets the last limit
                           *                if there was a change.  It also checks the states against the limits and issues 
                           *                an obstruction error if the limit and last limit
                           *                
                           * @param limit  integer limit - The limit to be checked
                           */
                          void setLastLimit( int limit ) {
                            
                            //Here is where we check for our error condition
                            if ( (lLimit == OPEN) && (limit == OPEN) && (lState == CLOSING) ) {
                              //An obstruction has reversed the door.  No need to set the last limit because it already equals
                              //the limit we are trying to set it to
                              obstruction = true;
                              //If we made it here and the last limit does not equal the limit we are setting then change it.  If
                              //the last limit is equal to the limit we are setting then the last state was something other than
                              //closing, so we don't need to do anything.
                            } else if ( lLimit != limit ) {
                              //Everything okay, set the last limit
                              lLimit = limit;
                              obstruction = false;
                            }
                            
                          } //End setLastLimit
                          
                          S 1 Reply Last reply
                          2
                          • dbemowskD dbemowsk

                            For those interested, I have updated my sketch for my garage door controller to MySensors 2.0.

                             /*
                              MyGarageDoor for MySensors
                            
                              Arduino garage door control
                            
                              Originally built for MySensors 1.5 June 16,2016
                              Updated to MySensors 2.0 October 21, 2016
                            
                              This will allow the MySensors gateway to monitor and control your garage door opener.  This will
                              monitor the internal upper and lower limit switches of the door opener to determine door position
                              for status as well as have a relay switched output that can control either the momentary contact
                              switch connected to the door opener or wired directly to the switch contacts of a door opener
                              remote to activate the door.
                            
                              This sketch features the following:
                            
                              Allows you to monitor the door position and return it's status based on the following:
                                1 - When either the upper or lower door limit switches are reached, the door is said to be
                                    either fully open or fully closed. When a limit switch is triggered, the lastLimit and
                                    currentState variables are set to either OPEN or CLOSED based on the limit switch that was
                                    triggered.
                                2 - If the upper and lower limit inputs both read high, then the door is said to be in motion.
                                    The door's direction of motion is determined from the lastLimit variable.  If the lastLimit
                                    of the door is OPEN, then the currentState variable should be set to CLOSING.  If the
                                    lastLimit of the door is CLOSED, then the currentState variable should be set to OPENING.
                              Checks for door obstructions and throws an error by checking the currentState and lastLimit
                              variables when the upper limit is reached.  If the upper limit is triggered and the currentState
                              is set to CLOSING and the lastLimit is set to OPEN, this should indicate that the door reversed
                              when closing and returned to the fully opened position.  The error state should only appear if
                              BOTH the lastLimit and currentState conditions match.  If lastLimit is OPEN and the lastState is
                              OPENING, this would indicate that the door was manually reversed.  This chech should only be
                              needed when the upper limit is reached.
                              Allows you to toggle the opener to either open or close the door.  When the door is toggled, the
                              currentState should be checked and if the state is either OPENING or CLOSING, the currentState
                              should invert telling that the door has changed direction.  This is done to prevent an error if
                              the door is reversed manually when closing.
                            
                              PARTS LIST:
                              Arduino pro mini
                              nRF24L01 radio module
                              AMS1117 3.3v regulator
                              0.1uf capacitor
                              10uf electrolytic capacitor
                              4.7uf electrolytic capacitor (for radio module)
                              5v reed relay
                              2N3904 transistor for relay
                              1k resistor
                              Two small signal diodes for incoming signals from door opener
                            
                              Wiring from garage door opener
                              Yellow = Upper limit D7
                              Brown = Lower limit D8
                              Gray = Signal ground
                            
                              Relay D5
                            
                              Version history:
                              1.1 : Added the V_TEXT variable and S_INFO sensor type, and created the "Status" child
                              1.2 : Added the heartbeat signal to tell the controller that the sensor is still alive.
                                    Scripting or other code must be used on the HA controller side to react to the 
                                    heartbeat signal and take appropriate action.
                              2.0 : Converted to MySensors 2.0
                            */
                            
                            //Set up the nRF24L01+
                            #define MY_RADIO_NRF24
                            
                            #include <SPI.h>
                            #include <MySensors.h>
                            #include <SimpleTimer.h>
                            
                            #define SKETCH_NAME "MyGarageDoor"
                            #define SKETCH_VERSION "1.2"
                            
                            #define CHILD_ID_OPENER 0
                            #define CHILD_ID_STATUS 1
                            
                            #define UPPER_LIMIT_SENSOR 6  //Pin used for input from the garage door upper limit sensor
                            #define LOWER_LIMIT_SENSOR 7  //Pin used for input from the garage door lower limit sensor
                            #define DOOR_ACTUATOR_RELAY 5 //Pin used to toggle the door actuator relay
                            #define RELAY_ON 1            // GPIO value to write to turn on attached relay
                            #define RELAY_OFF 0           // GPIO value to write to turn off attached relay
                            
                            #define TOGGLE_INTERVAL 1500  //Tells how many milliseconds the relay will be held closed
                            #define HEARTBEAT_INTERVAL 120000 //Number of miliseconds before the next heartbeat
                            
                            #define CLOSED 0
                            #define OPEN 1
                            #define CLOSING 2
                            #define OPENING 3
                            
                            #define OBSTR_MAX 20
                            
                            const char *currentState[] = { 
                                                         "Closed", 
                                                         "Open", 
                                                         "Closing", 
                                                         "Opening" 
                                                         };
                            
                            //Current state of the door
                            int cState;     
                            
                            //Last state of the door
                            int lState;     
                            
                            //The last full limit position of the door (open or closed)
                            int lLimit = 0; 
                            
                            //Used for the error condition when the door is unexpectedly reversed
                            boolean obstruction = false;
                            
                            int obstruction_count = 0;
                            
                            // the timer object used for the heartbeat
                            SimpleTimer heartbeat;
                            
                            MyMessage msgOpener(CHILD_ID_OPENER, V_STATUS);
                            MyMessage msgStatus(CHILD_ID_STATUS, V_TEXT);
                            
                            /**
                             * presentation - Present the garage door sensor
                             */
                            void presentation() {
                              
                              sendSketchInfo( SKETCH_NAME, SKETCH_VERSION );
                              
                              // Register the garage door sensor with the gateway
                              present( CHILD_ID_OPENER, S_BINARY );
                              present( CHILD_ID_STATUS, S_INFO );
                              
                            } //End presentation
                            
                            /**
                             * setup - Initialize the garage door sensor
                             */
                            void setup() {
                            
                              // Set up the pins for reading the upper and lower limit sensors
                              pinMode(UPPER_LIMIT_SENSOR, INPUT);
                              pinMode(LOWER_LIMIT_SENSOR, INPUT);
                              // Set up the pin to control the door opener
                              pinMode(DOOR_ACTUATOR_RELAY, OUTPUT);
                            
                              Serial.println( SKETCH_NAME );
                            
                              // Set the heartbeat timer to send the current state at the set interval
                              heartbeat.setInterval(HEARTBEAT_INTERVAL, sendCurrentState);
                              
                            } //End setup
                            
                            /**
                             * loop - The main program loop
                             */
                            void loop() {
                            
                              //Get the state of the door
                              getState();
                            
                              //Here we check if the state has changed and update the gateway with the change.  We do this
                              //after all processing of the state because we need to know if there was an obstruction
                              if ((lState != cState) || obstruction == true) {
                                sendCurrentState();
                            
                                obstruction_count ++;
                                if (obstruction_count >= OBSTR_MAX) {
                                  //Once the obstruction is checked and sent, we can clear it
                                  obstruction = false;
                                }
                            
                                //If the current state is full open or full closed we need to set the last limit
                                if ( (cState == OPEN) || (cState == CLOSED) ) {
                                  setLastLimit( cState );
                                }
                              }
                            
                              //If the relay is on, shut it off
                              if ( digitalRead( DOOR_ACTUATOR_RELAY ) == 1) {
                                relayOff();                       
                              }
                              
                              heartbeat.run();
                              
                            } //End loop
                            
                            /**
                             * receive - Process the incoming messages and watch for an incoming boolean 1
                             *           to toggle the garage door opener.
                             */
                            void receive( const MyMessage &message ) {
                              
                              //We only expect one type of message from controller. But we better check anyway.
                              if ( (message.type == V_STATUS) && (message.getBool() == RELAY_ON) ) {
                                //Toggle the door opener
                                toggleDoor();
                              }
                              
                            } //End receive
                            
                            /**
                             * sendCurrentState - Sends the current state back to the gateway
                             */
                            void sendCurrentState() {
                              
                                send( msgStatus.set( obstruction == true ? "OBSTRUCTION" : currentState[cState] ) ); 
                                
                            } //End sendCurrentState
                            
                            /**
                             * toggleDoor - Used to activate the garage door opener
                             */
                            void toggleDoor() {
                            
                              digitalWrite( DOOR_ACTUATOR_RELAY, RELAY_ON );
                              //Keep the relay on for the amount of time defined by TOGGLE_INTERVAL
                              delay( TOGGLE_INTERVAL );
                              
                            } //End toggleDoor
                            
                            /**
                             * relayOff - Used to turn off the door opener relay after the TOGGLE_INTERVAL
                             */
                            void relayOff() {
                            
                              digitalWrite( DOOR_ACTUATOR_RELAY, RELAY_OFF );
                              //Added this to tell the controller that we shut off the relay
                              send( msgOpener.set(0) );
                              
                            } //End relayOff
                            
                            /**
                             * getState - Used to get the current state of the garage door.  This will set the cState variable
                             *            to either OPEN, CLOSED, OPENING and CLOSING
                             */
                            void getState() {
                            
                              //read the upper sensor
                              int upper = digitalRead( UPPER_LIMIT_SENSOR ); 
                              //read the lower sensor
                              int lower = digitalRead( LOWER_LIMIT_SENSOR ); 
                            
                              //Save the last state of the door for later tests
                              lState = cState;
                            
                              //Check if the door is open
                              if ((upper == HIGH) && (lower == LOW)) {
                                //Set the current state to open
                                cState = OPEN;
                                //Check if the door is closed
                              } else if ((upper == LOW) && (lower == HIGH)) {
                                //Set the current state to closed
                                cState = CLOSED;
                                //Check if the door is in motion
                              } else if ((upper == HIGH) && (lower == HIGH)) {
                                //If in motion and the last full position of the door was open
                                if (lLimit == OPEN) {
                                  //Set the current state to closing
                                  cState = CLOSING;
                                  //If in motion and the last full position of the door was closed
                                } else {
                                  //Set the current state to opening
                                  cState = OPENING;
                                }
                              }
                              
                            } //End getState
                            
                            /**
                             * setLastLimit - Checks the limit passed with the last limit (lLimit) and sets the last limit
                             *                if there was a change.  It also checks the states against the limits and issues 
                             *                an obstruction error if the limit and last limit
                             *                
                             * @param limit  integer limit - The limit to be checked
                             */
                            void setLastLimit( int limit ) {
                              
                              //Here is where we check for our error condition
                              if ( (lLimit == OPEN) && (limit == OPEN) && (lState == CLOSING) ) {
                                //An obstruction has reversed the door.  No need to set the last limit because it already equals
                                //the limit we are trying to set it to
                                obstruction = true;
                                //If we made it here and the last limit does not equal the limit we are setting then change it.  If
                                //the last limit is equal to the limit we are setting then the last state was something other than
                                //closing, so we don't need to do anything.
                              } else if ( lLimit != limit ) {
                                //Everything okay, set the last limit
                                lLimit = limit;
                                obstruction = false;
                              }
                              
                            } //End setLastLimit
                            
                            S Offline
                            S Offline
                            stevefury
                            wrote on last edited by
                            #30

                            @dbemowsk hi, first off all, very nice job, i read your setup and i like what you did, but im not ready yet to master this c++ like you and i am trying to compile your sketch but i have some faults, with heartbeat interval, and maybe you can show me the way?

                            thanks

                            S 1 Reply Last reply
                            0
                            • S stevefury

                              @dbemowsk hi, first off all, very nice job, i read your setup and i like what you did, but im not ready yet to master this c++ like you and i am trying to compile your sketch but i have some faults, with heartbeat interval, and maybe you can show me the way?

                              thanks

                              S Offline
                              S Offline
                              stevefury
                              wrote on last edited by
                              #31

                              @stevefury said in Automated garage door:

                              @dbemowsk hi, first off all, very nice job, i read your setup and i like what you did, but im not ready yet to master this c++ like you and i am trying to compile your sketch but i have some faults, with heartbeat interval, and maybe you can show me the way?

                              thanks

                              nobody???

                              skywatchS 1 Reply Last reply
                              0
                              • S stevefury

                                @stevefury said in Automated garage door:

                                @dbemowsk hi, first off all, very nice job, i read your setup and i like what you did, but im not ready yet to master this c++ like you and i am trying to compile your sketch but i have some faults, with heartbeat interval, and maybe you can show me the way?

                                thanks

                                nobody???

                                skywatchS Online
                                skywatchS Online
                                skywatch
                                wrote on last edited by
                                #32

                                @stevefury said in Automated garage door:

                                ... but i have some faults, with heartbeat interval,

                                Some faults? Ah well then, that's easy to fix!

                                nobody???

                                All the psychic team are on holiday, so you will have to help those who might be willing to help you. So.....

                                1. Post the code (in full) that you have problems with (use code tags </>).
                                2. Post the detailed messages for the errors you enounter.
                                3. Tell us exactly what is wrong and/or why you think it is wrong and what you are expecting.
                                zboblamontZ 1 Reply Last reply
                                1
                                • skywatchS skywatch

                                  @stevefury said in Automated garage door:

                                  ... but i have some faults, with heartbeat interval,

                                  Some faults? Ah well then, that's easy to fix!

                                  nobody???

                                  All the psychic team are on holiday, so you will have to help those who might be willing to help you. So.....

                                  1. Post the code (in full) that you have problems with (use code tags </>).
                                  2. Post the detailed messages for the errors you enounter.
                                  3. Tell us exactly what is wrong and/or why you think it is wrong and what you are expecting.
                                  zboblamontZ Offline
                                  zboblamontZ Offline
                                  zboblamont
                                  wrote on last edited by
                                  #33

                                  @skywatch :sweat_smile:

                                  1 Reply Last reply
                                  1
                                  Reply
                                  • Reply as topic
                                  Log in to reply
                                  • Oldest to Newest
                                  • Newest to Oldest
                                  • Most Votes


                                  18

                                  Online

                                  11.7k

                                  Users

                                  11.2k

                                  Topics

                                  113.1k

                                  Posts


                                  Copyright 2025 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
                                  • Login

                                  • Don't have an account? Register

                                  • Login or register to search.
                                  • First post
                                    Last post
                                  0
                                  • MySensors
                                  • OpenHardware.io
                                  • Categories
                                  • Recent
                                  • Tags
                                  • Popular