My garage door sensor



  • OK, so I now have my garage door sensor "SOMEWHAT" working in Domoticz. I have the switch set up under switches, and if I toggle it, the garage door opens/closes, but I get an error immediately after it is toggled. The error says "Error sending switch command, check device/hardware !". I am guessing that there is something with my sketch for the opener that is probably wrong, so I have included my sketch below.

     /*
      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 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] ) );  //"obstr" : 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;
      }
    }
    

    My other issue with it that I would like to figure out is whether or not there is a way to display the responses from the node such as Open, Closed, Opening, Closing and Obstruction. I don't need to know the switch state because it is a momentary toggle. If I could display the node responses instead of that that would be ideal.



  • Hi dbemowsk
    Regarding your first question - could it be that Domoticz are expecting an ACK from the node? ACK are enabled by default on all childs created. You could try to disable it.

    Br
    Lemme



  • @Lemme You say that ACK is enabled by default on all child nodes. If that is the case and Domoticz is expecting it, shouldn't it work? On the flip side, if it is not expecting it and it is sent, wouldn't it just ignore it? I will look into how to disable it and test that, but it would be nice to know for sure that that is the way Domoticz is set up to work.



  • I cannot see that your code are handling ACK's. So if Domoticz are expecting ACK, and your code do not respond, it could cause the problem.

    I have had an issu myself with the error "Error sending switch command, check device/hardware !". I first disabled the ACK - update, and then enabled ACK - update, and then it worked correctely.

    You find it at the buttom of the screen.
    0_1467467252349_ACK.jpg



  • I did some searching and did find this post regarding my first question.
    https://forum.mysensors.org/topic/2553/error-sending-switch-command-check-device-hardware/8
    One response was this:

    @hek said:

    The gateway code running on RPI doesn't remember routing information when restated (the EEPROM emulation is just in-memory).
    This means you have to restart the actuator nodes after RPI was restarted to fill the routing information again.
    It's on the grand TODO list. Anyone: Feel free to fix.

    But I am not sure if that is only for the Raspberry Pi or not. I am running an Orange Pi which may run the same gateway code, but I am not sure. I am going to try resetting my node later today to see if that works.



  • So I restarted my garage door node and I am no longer getting the error message. I am still wondering though how I can display the responses sent from the node. The node responds with Open, Closed, Opening, Closing and Obstruction. I would like to display that for the node instead of the state of the relay. The relay is just a momentary toggle to open and close the door, so that information I don't need, but the state of the door is crucial.

    Thanks for all the help


  • Hero Member

    @dbemowsk you would need a V_TEXT type to send text information to domoticz. V_VAR types in Domoticz are not available in the Web and other interfaces.



  • @AWI Looking at the API documentation for 1.5 and I don't see a V_TEXT type. Is there a way to do this with MySensors?


  • Hero Member

    @dbemowsk This is added in 2.0 but you can patch it in v1.5 by defining it yourself.

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


  • @AWI I added those two types to my sketch and it worked perfect. I now have a device that shows up as "Garage door position" under the utility tab. Thanks a million for the help.



  • Hello guys,

    I am very interested in this project. Did you simply change V_VAR1 to V_Text to make it work?

    Would you mind posting your fully working code?

    Thanks



  • @Dringie As @AWI pointed out, the V_TEXT variable and S_INFO sensor type have not been implemented until version 2.0. He mentions that you can add them by putting these lines in 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 ;
    

    I did that and it worked like a charm. I now havemy "Garage door position object that shows me the current state of the door as one of {Open, Closed, Opening, Closing, Obstruction}. As for posting the code, I will do that in another thread. I have a thread started under the Hardware section of the forum called "Automate garage door". Here is the link.
    https://forum.mysensors.org/topic/4059/automated-garage-door
    I will be posting the new code later tonight. I just want to tidy it up a bit before posting.


 

423
Online

7.9k
Users

8.8k
Topics

94.3k
Posts