Automated garage door
-

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:1Overall 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.
-
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; } } -
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; } } -
@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.
-
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.
-
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.
-
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.
-
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.
-
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.
-
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 -
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@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
-
@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
@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???
-
@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???
@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.....
- Post the code (in full) that you have problems with (use code tags </>).
- Post the detailed messages for the errors you enounter.
- Tell us exactly what is wrong and/or why you think it is wrong and what you are expecting.
-
@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.....
- Post the code (in full) that you have problems with (use code tags </>).
- Post the detailed messages for the errors you enounter.
- Tell us exactly what is wrong and/or why you think it is wrong and what you are expecting.
@skywatch :sweat_smile: