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 dbemowsk

    @martinhjelmare
    Many thanks for your input on this.

    I kind of see your point that the gateway/controller should not have to care about if the device is opening or closing. One issue in that though is that if a status request is sent say immediately after the door is triggered to close, it may be 10 seconds or more before a determination can be made as to whether the door is open or closed. Do I then make the gateway/controller wait for the status? Or do I say that if the gateway/controller receives a status of OPENING or CLOSING, it can then check back in say 10 seconds or whatever to get the actual state of the door (OPEN or CLOSED). I guess I don't know how often polling would take place on the controller side.

    One other thing that I am a bit confused on is whether I would need to present two child nodes, one for the trigger relay, and one for the door status, or if I would present one child that would handle the trigger and status both?

    Like I say, I am still pretty new to this and am trying to get my bearings on how things work with MySensors.

    martinhjelmareM Offline
    martinhjelmareM Offline
    martinhjelmare
    Plugin Developer
    wrote on last edited by martinhjelmare
    #13

    @dbemowsk

    I think you make a good point that it can be important to know if the door is still moving or not after a command has been sent from the controller to go to a position or to move.

    I would use the V_UP and V_DOWN types for this. Also, it's best if the device pushes updates to the gateway and controller so that you don't need to poll the device from the controller all the time.

    You can have multiple different v_types for one child and s_type, but if you need more than one of the same v_type you should add a child. Also, your controller might limit your options depending on how it has implemented the mysensors API.

    M 1 Reply Last reply
    0
    • martinhjelmareM martinhjelmare

      @dbemowsk

      I think you make a good point that it can be important to know if the door is still moving or not after a command has been sent from the controller to go to a position or to move.

      I would use the V_UP and V_DOWN types for this. Also, it's best if the device pushes updates to the gateway and controller so that you don't need to poll the device from the controller all the time.

      You can have multiple different v_types for one child and s_type, but if you need more than one of the same v_type you should add a child. Also, your controller might limit your options depending on how it has implemented the mysensors API.

      M Offline
      M Offline
      mikeones
      wrote on last edited by mikeones
      #14

      @martinhjelmare

      V_UP and V_DOWN are a great suggestion. I use a distance sensor on my garage door for the state. This will let me know when a button push occurred or a remote open was used.

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

        @martinhjelmare said:

        You can have multiple different v_types for one child and s_type, but if you need more than one of the same v_type you should add a child. Also, your controller might limit your options depending on how it has implemented the mysensors API.

        So with the serial API, are you limited to the variables defined for a sensor, or are those just suggestions. So for S_DIMMER, am I limited to V_UP, V_DOWN, V_STOP, V_PERCENTAGE? The reason I ask is if I used S_DIMMER Can I handle the incoming toggle request using that? That is the reason I asked if I needed to use two child nodes.

        So I am guessing that by pushing updates you are talking about doing a gw.send immediately after a state change. I can see that being much better than having to send a polling request to get the status.

        martinhjelmareM 1 Reply Last reply
        0
        • dbemowskD dbemowsk

          @martinhjelmare said:

          You can have multiple different v_types for one child and s_type, but if you need more than one of the same v_type you should add a child. Also, your controller might limit your options depending on how it has implemented the mysensors API.

          So with the serial API, are you limited to the variables defined for a sensor, or are those just suggestions. So for S_DIMMER, am I limited to V_UP, V_DOWN, V_STOP, V_PERCENTAGE? The reason I ask is if I used S_DIMMER Can I handle the incoming toggle request using that? That is the reason I asked if I needed to use two child nodes.

          So I am guessing that by pushing updates you are talking about doing a gw.send immediately after a state change. I can see that being much better than having to send a polling request to get the status.

          martinhjelmareM Offline
          martinhjelmareM Offline
          martinhjelmare
          Plugin Developer
          wrote on last edited by
          #16

          @dbemowsk

          There's no inherit connection between s_types and v_types in the API, but the docs for the mysensors API groups them as a suggestion, I would say. The controllers, though, will probably have some kind of limit on the usage of the types. Each controller has to account for its implementation of the mysensors API.

          In the sketch you can combine V_STATUS with for example V_UP, V_DOWN and V_PERCENTAGE for S_COVER, yes, but you have to figure out how the controller will respond to that combination, if it will work or not.

          Regarding pushing updates, yes, after each state change etc, send in the new value.

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

            The only thing I would need the incoming status for would be to toggle the opener on. Once toggled on, shutting the relay off is done internally on a timer. The relay would emulate a momentary button press, so it would only be on for a second or two. The rest is just pushing the status back to the controller.

            Then my next step is going to be to actually try to compile this and upload it. What kind of command would I need to send from the serial monitor to activate the relay since I do not have any automation software set up yet?

            1 Reply Last reply
            0
            • 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 Offline
                                          skywatchS Offline
                                          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
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          16

                                          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