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. Synchronising Light switch

Synchronising Light switch

Scheduled Pinned Locked Moved My Project
light switch
10 Posts 3 Posters 5.7k Views 7 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.
  • Boots33B Offline
    Boots33B Offline
    Boots33
    Hero Member
    wrote on last edited by
    #1

    I have a 12v system in my house that is used for some of the lighting so wanted to let Mysensors take control of the nightlights that until now i have had to switch on manually. There were a few things that needed to be achieved with these nodes to make them acceptable for use.

    1. I had to retain hardware switch so the lights could still be switched from the local wall plate.

    2. The hardware switch had to remain functional even if the gateway or controller were not available. we live in a semi rural area where there are few street lights so the 12v lighting has to remain operational during power outages etc.

    3. The node should make an effort to keep the controller in sync with its current state. During first boot up and when a broken up-link has been re-established.

    The code is working with Domoticz and so far has responded well to all conditions stated above.
    it uses request to check with the controllers state and sends a message if needed to sync.
    A momentary push button is used for the switch.

    /*
       Relay with button sketch
       modified to work with no uplink
       to gateway and try to maintain sync to controller
    */
    
    
    #define MY_DEBUG                               // Enable debug prints to serial monitor
    
    #define MY_RADIO_NRF24                         // Enable and select radio type attached
    
    #define MY_TRANSPORT_WAIT_READY_MS 5000        //set how long to wait for transport ready in milliseconds
    
    #include <MySensors.h>
    #include <Bounce2.h>
    
    #define RELAY_PIN  4      // Arduino Digital I/O pin number for relay 
    #define BUTTON_PIN  3     // Arduino Digital I/O pin number for button 
    #define CHILD_ID 1        // Id of the sensor child
    #define RELAY_ON 1
    #define RELAY_OFF 0
    
    Bounce debouncer = Bounce();
    int oldValue = 0;
    bool uplinkAvailable = true;
    bool state = false;
    bool requestState;
    bool firstStart = true;
    unsigned long uplinkCheckTime ;                // holder for uplink checks
    unsigned long uplinkCheckPeriod = 30*1000;     // time between checks for uplink in milliseconds
    unsigned long returnWait = 1500;               // how long to wait for return from controller in milliseconds
    MyMessage msg(CHILD_ID, V_STATUS);
    
    void setup(){
      pinMode(BUTTON_PIN, INPUT_PULLUP);           // Setup the button pin, Activate internal pull-up
      
      debouncer.attach(BUTTON_PIN);                // After setting up the button, setup debouncer
      debouncer.interval(5);
    
      pinMode(RELAY_PIN, OUTPUT);                 // set relay pin in output mode
      digitalWrite(RELAY_PIN, RELAY_OFF);         // Make sure relay is off when starting up
    }
    
    void presentation()  {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("Relay & Button", "1.0");
    
      // Register all sensors to gw (they will be created as child devices)
      present(CHILD_ID, S_BINARY);
    }
    
    
    void loop(){
      if (firstStart) {                            // this code is only run once at startup
        Serial.println("First run started");
        if (request( CHILD_ID, V_STATUS)) {       // request the current state of the switch on the controller and check that an ack was received
          Serial.println("uplink available");
          wait (returnWait);                      //wait needed to allow request to return from controller
          Serial.print("controller state --- ");
          Serial.println(requestState);
          if (requestState != state) {           // check that controller is corectly showing the current relay state
            send(msg.set(state), false);         // notify controller of current state
          }
        }
        else {
          Serial.println("uplink not available");
          uplinkAvailable = false;               // no uplink established
          uplinkCheckTime = millis();
        }
        firstStart = false;                     // set firstStart flag false to prevent code from running again
      }
    
      debouncer.update();
      int value = debouncer.read();                               // Get the update value
      if (value != oldValue && value == 0) {                      // check for new button push
        state =  !state;                                          // Toggle the state
        digitalWrite(RELAY_PIN, state ? RELAY_ON : RELAY_OFF);    // switch the relay to the new state
        if (!send(msg.set(state), true)) {                        //Attempt to notify controller of changed state
          Serial.println("uplink not available");
          uplinkAvailable = false;                                // no uplink available
          uplinkCheckTime = millis();                             
        }
      }
     oldValue = value;
    
      if (!uplinkAvailable && (millis() - uplinkCheckTime > uplinkCheckPeriod) ) {       // test to see if function should be called
        uplinkCheck();                                                                  // call uplink checking function
      }
    
    }
    
    /*-------------------start of functions--------------------------*/
    
    void receive(const MyMessage &message) {
      if (message.type == V_STATUS) {                                   // check to see if incoming message is for a switch
        switch (message.getCommand()) {                                 // message.getCommand will give us the command type of the incomming message
          case C_SET:                                                   //message is a set command  from controller to update relay state
            state = message.getBool();                                  // get the new state
            digitalWrite(RELAY_PIN, state ? RELAY_ON : RELAY_OFF);      // switch relay to new state
            uplinkAvailable = true;                                     //  uplink established
            /*---- Write some debug info----*/
            Serial.print("Incoming change for sensor:");
            Serial.print(message.sensor);
            Serial.print(", New status: ");
            Serial.println(message.getBool());
            break;
          case C_REQ:                                               // message is a returning request from controller
            requestState = message.getBool();                       // update requestState with returning state
            break;
        }
      }
    }
    
    void uplinkCheck() {
      if (request( CHILD_ID, V_STATUS)) {         // request the current state of the switch on the controller and check that the request was succsessful
        Serial.println("uplink re-established");
        wait (returnWait);                        //wait needed to allow request to return from controller
        if (requestState != state) {              // check that controller is corectly showing the current relay state
          send(msg.set(state), false);            // notify controller of current state no ack
          uplinkAvailable = true;                 //  uplink established
        }
      }
      uplinkCheckTime = millis();                // reset the checktime
      Serial.println("uplinkchecktime reset");
    }
    
    
    

    The wiring
    0_1496469040524_relay circuit.jpg

    1 Reply Last reply
    2
    • core_cC Offline
      core_cC Offline
      core_c
      wrote on last edited by
      #2

      cool.
      nothing too much in code, nor in wiring.
      :+1:

      Boots33B 1 Reply Last reply
      0
      • core_cC core_c

        cool.
        nothing too much in code, nor in wiring.
        :+1:

        Boots33B Offline
        Boots33B Offline
        Boots33
        Hero Member
        wrote on last edited by
        #3

        @core_c Yes I did not want it to be overly complicated or to be constantly pinging the network either.
        It is a fairly good compromise the node only starts to ping once it has determined the uplink is broken and you can decide the interval by changing uplinkCheckPeriod. At the moment it is set to 30 seconds.

        In testing the return from request usually arrived within 800 milliseconds so returnWait could also be reduced from 1500ms if it was a concern. It is only used when the node is first reconnected so felt I would rather make sure I got the correct data by adding an extra delay.

        1 Reply Last reply
        0
        • Boots33B Offline
          Boots33B Offline
          Boots33
          Hero Member
          wrote on last edited by Boots33
          #4

          Just a couple of other ideas on this subject to share :)

          This sketch is a small modification on the original to allow for the use of a toggle type switch instead of the push button

          /*
             Relay with toggle switch sketch
             modified to work with no uplink
             to gateway and try to maintain sync to controller
             Toggle switch connected between pin3 and ground.
          */
          
          
          #define MY_DEBUG                               // Enable debug prints to serial monitor
          
          #define MY_RADIO_NRF24                         // Enable and select radio type attached
          
          #define MY_TRANSPORT_WAIT_READY_MS 5000        //set how long to wait for transport ready in milliseconds
          
          #include <MySensors.h>
          #include <Bounce2.h>
          
          #define RELAY_PIN  4      // Arduino Digital I/O pin number for relay 
          #define SWITCH_PIN  3     // Arduino Digital I/O pin number for switch 
          #define CHILD_ID 1        // Id of the sensor child
          #define RELAY_ON 1
          #define RELAY_OFF 0
          
          Bounce debouncer = Bounce();
          int oldValue = 0;
          bool uplinkAvailable = true;
          bool state = false;
          bool requestState;
          bool firstStart = true;
          unsigned long uplinkCheckTime ;                // holder for uplink checks
          unsigned long uplinkCheckPeriod = 30*1000;     // time between checks for uplink in milliseconds
          unsigned long returnWait = 1500;               // how long to wait for return from controller in milliseconds
          MyMessage msg(CHILD_ID, V_STATUS);
          
          void setup(){
            pinMode(SWITCH_PIN, INPUT_PULLUP);           // Setup the button pin, Activate internal pull-up
            
            debouncer.attach(SWITCH_PIN);                // After setting up the button, setup debouncer
            debouncer.interval(5);
          
            pinMode(RELAY_PIN, OUTPUT);                 // set relay pin in output mode
            digitalWrite(RELAY_PIN, RELAY_OFF);         // Make sure relay is off when starting up
          }
          
          void presentation()  {
            // Send the sketch version information to the gateway and Controller
            sendSketchInfo("Relay & Toggle", "1.0");
          
            // Register all sensors to gw (they will be created as child devices)
            present(CHILD_ID, S_BINARY);
          }
          
          
          void loop(){
            if (firstStart) {                            // this code is only run once at startup
              Serial.println("First run started");
              if (request( CHILD_ID, V_STATUS)) {       // request the current state of the switch on the controller and check that an ack was received
                Serial.println("uplink available");
                wait (returnWait);                      //wait needed to allow request to return from controller
                Serial.print("controller state --- ");
                Serial.println(requestState);
                if (requestState != state) {           // check that controller is corectly showing the current relay state
                  send(msg.set(state), false);         // notify controller of current state
                }
              }
              else {
                Serial.println("uplink not available");
                uplinkAvailable = false;               // no uplink established
                uplinkCheckTime = millis();
              }
              firstStart = false;                     // set firstStart flag false to prevent code from running again
            }
          
            debouncer.update();
            int value = debouncer.read();                               // Get the update value
            if (value != oldValue) {                      // check for new throw of toggle switch
              state =  !state;                                          // Toggle the state
              digitalWrite(RELAY_PIN, state ? RELAY_ON : RELAY_OFF);    // switch the relay to the new state
              if (!send(msg.set(state), true)) {                        //Attempt to notify controller of changed state
                Serial.println("uplink not available");
                uplinkAvailable = false;                                // no uplink available
                uplinkCheckTime = millis();                             
              }
             oldValue = value;
            }
           
          
            if (!uplinkAvailable && (millis() - uplinkCheckTime > uplinkCheckPeriod) ) {       // test to see if function should be called
              uplinkCheck();                                                                  // call uplink checking function
            }
          
          }
          
          /*-------------------start of functions--------------------------*/
          
          void receive(const MyMessage &message) {
            if (message.type == V_STATUS) {                                   // check to see if incoming message is for a switch
              switch (message.getCommand()) {                                 // message.getCommand will give us the command type of the incomming message
                case C_SET:                                                   //message is a set command  from controller to update relay state
                  state = message.getBool();                                  // get the new state
                  digitalWrite(RELAY_PIN, state ? RELAY_ON : RELAY_OFF);      // switch relay to new state
                  uplinkAvailable = true;                                     //  uplink established
                  /*---- Write some debug info----*/
                  Serial.print("Incoming change for sensor:");
                  Serial.print(message.sensor);
                  Serial.print(", New status: ");
                  Serial.println(message.getBool());
                  break;
                case C_REQ:                                               // message is a returning request from controller
                  requestState = message.getBool();                       // update requestState with returning state
                  break;
              }
            }
          }
          
          void uplinkCheck() {
            if (request( CHILD_ID, V_STATUS)) {         // request the current state of the switch on the controller and check that the request was succsessful
              Serial.println("uplink re-established");
              wait (returnWait);                        //wait needed to allow request to return from controller
              if (requestState != state) {              // check that controller is corectly showing the current relay state
                send(msg.set(state), false);            // notify controller of current state no ack
                uplinkAvailable = true;                 //  uplink established
              }
            }
            uplinkCheckTime = millis();                // reset the checktime
            Serial.println("uplinkchecktime reset");
          }
          
          

          This next sketch is for a push button once again but this time it is using requestTime() to try and determine if the controller is available. While all uplink checks are only made to the gateway, by checking for the time returned from the controller it is possible to use this to test for the controllers presence. I have not tested this code extensively but it does appear to work ok within the original design goals.

          /*
             Relay with button sketch
             modified to work with no uplink
             to gateway and try to maintain sync to controller
          */
          
          
          #define MY_DEBUG                               // Enable debug prints to serial monitor
          
          #define MY_RADIO_NRF24                         // Enable and select radio type attached
          //#define MY_RF24_CHANNEL 84
          //#define MY_NODE_ID 203
          #define MY_TRANSPORT_WAIT_READY_MS 5000        //set how long to wait for transport ready in milliseconds
          
          #include <MySensors.h>
          #include <Bounce2.h>
          
          #define RELAY_PIN  4      // Arduino Digital I/O pin number for relay 
          #define BUTTON_PIN  3     // Arduino Digital I/O pin number for button 
          #define CHILD_ID 1        // Id of the sensor child
          #define RELAY_ON 1
          #define RELAY_OFF 0
          
          Bounce debouncer = Bounce();
          int oldValue = 0;
          bool uplinkAvailable = true;
          bool state = false;
          bool requestState;
          bool firstStart = true;
          unsigned long uplinkCheckTime ;                // holder for uplink checks
          unsigned long uplinkCheckPeriod = 30*1000;     // time between checks for uplink in milliseconds
          unsigned long returnWait = 1500;               // how long to wait for return from controller in milliseconds.. adjust as needed
          unsigned long oldTime = 0;
          unsigned long newTime = 0;
          MyMessage msg(CHILD_ID, V_STATUS);
          
          void setup(){
            pinMode(BUTTON_PIN, INPUT_PULLUP);           // Setup the button pin, Activate internal pull-up
            
            debouncer.attach(BUTTON_PIN);                // After setting up the button, setup debouncer
            debouncer.interval(5);
          
            pinMode(RELAY_PIN, OUTPUT);                 // set relay pin in output mode
            digitalWrite(RELAY_PIN, RELAY_OFF);         // Make sure relay is off when starting up
          }
          
          void presentation()  {
            // Send the sketch version information to the gateway and Controller
            sendSketchInfo("Relay & Button test", "1.1");
          
            // Register all sensors to gw (they will be created as child devices)
            present(CHILD_ID, S_BINARY);
          }
          
          
          void loop(){
            if (firstStart) {                            // this code is only run once at startup
              Serial.println("First run started");
              requestTime();                             // get time from controller
              wait (returnWait);                         // delay to allow time to return
              if (oldTime == 0){                         // check to see if there was a return from the time request
                Serial.println("uplink not available");
                uplinkAvailable = false;                 // no uplink established
                uplinkCheckTime = millis();
              }
               else{
                Serial.println("uplink available");
                request( CHILD_ID, V_STATUS);            // get status of switch on controller
                wait (returnWait);                       //wait needed to allow request to return from controller
                Serial.print("controller state --- ");
                Serial.println(requestState);
                if (requestState != state) {             // check that controller is corectly showing the current relay state
                  send(msg.set(state), false);           // notify controller of current state
                } 
               }   
            firstStart = false;                                          // set firstStart flag false to prevent code from running again
           }
          
            debouncer.update();
            int value = debouncer.read();                               // Get the update value
            if (value != oldValue && value == 0) {                      // check for new button push
              state =  !state;                                          // Toggle the state
              digitalWrite(RELAY_PIN, state ? RELAY_ON : RELAY_OFF);    // switch the relay to the new state
              requestTime();
              wait (returnWait);                                               // delay to allow time to return
              if (oldTime != newTime){                                  // if times are different then uplink is available
                send(msg.set(state), false);
                oldTime = newTime;
              }
              else{                                                    // if times are the same no uplink is available
               Serial.println("uplink not available");
                uplinkAvailable = false;                                // no uplink available, set flag false
                uplinkCheckTime = millis();                             // start the timer from now
              }
          
            }
            oldValue = value;
           
            if (!uplinkAvailable && (millis() - uplinkCheckTime > uplinkCheckPeriod) ) {       // test to see if function should be called
              uplinkCheck();                                                                  // call uplink checking function
            }
          
          }
          
          /*-------------------start of functions--------------------------*/
          
          void receive(const MyMessage &message) {
            if (message.type == V_STATUS) {                                   // check to see if incoming message is for a switch
              switch (message.getCommand()) {                                 // message.getCommand will give us the command type of the incomming message
                case C_SET:                                                   //message is a set command  from controller to update relay state
                  state = message.getBool();                                  // get the new state
                  digitalWrite(RELAY_PIN, state ? RELAY_ON : RELAY_OFF);      // switch relay to new state
                  uplinkAvailable = true;                                     //  uplink established
                  /*---- Write some debug info----*/
                  Serial.print("Incoming change for sensor:");
                  Serial.print(message.sensor);
                  Serial.print(", New status: ");
                  Serial.println(message.getBool());
                  break;
                case C_REQ:                                               // message is a returning request from controller
                  requestState = message.getBool();                       // update requestState with returning state
                  break;
              }
            }
          }
          
          void uplinkCheck() {
              requestTime();
              wait (returnWait);                       // wait for time return.. this may need to be varied for your system
             if (oldTime != newTime){
               Serial.println("uplink re-established");
               request( CHILD_ID, V_STATUS);
               wait (returnWait);                        //wait needed to allow request to return from controller
              if (requestState != state) {              // check that controller is corectly showing the current relay state
                send(msg.set(state), false);            // notify controller of current state no ack
                uplinkAvailable = true;                 //  uplink established
                oldTime = newTime;
              }
            }
            uplinkCheckTime = millis();                // reset the checktime
            Serial.println("uplinkchecktime reset");
          }
          
          
          void receiveTime(unsigned long time)
          {
            if (firstStart){
              oldTime = time;
              newTime = time;
            }
            else{
            newTime = time;
          }
            Serial.print("time received---- " );
            Serial.println(time);
          }
          
          
          
          pepsonP 1 Reply Last reply
          0
          • Boots33B Boots33

            Just a couple of other ideas on this subject to share :)

            This sketch is a small modification on the original to allow for the use of a toggle type switch instead of the push button

            /*
               Relay with toggle switch sketch
               modified to work with no uplink
               to gateway and try to maintain sync to controller
               Toggle switch connected between pin3 and ground.
            */
            
            
            #define MY_DEBUG                               // Enable debug prints to serial monitor
            
            #define MY_RADIO_NRF24                         // Enable and select radio type attached
            
            #define MY_TRANSPORT_WAIT_READY_MS 5000        //set how long to wait for transport ready in milliseconds
            
            #include <MySensors.h>
            #include <Bounce2.h>
            
            #define RELAY_PIN  4      // Arduino Digital I/O pin number for relay 
            #define SWITCH_PIN  3     // Arduino Digital I/O pin number for switch 
            #define CHILD_ID 1        // Id of the sensor child
            #define RELAY_ON 1
            #define RELAY_OFF 0
            
            Bounce debouncer = Bounce();
            int oldValue = 0;
            bool uplinkAvailable = true;
            bool state = false;
            bool requestState;
            bool firstStart = true;
            unsigned long uplinkCheckTime ;                // holder for uplink checks
            unsigned long uplinkCheckPeriod = 30*1000;     // time between checks for uplink in milliseconds
            unsigned long returnWait = 1500;               // how long to wait for return from controller in milliseconds
            MyMessage msg(CHILD_ID, V_STATUS);
            
            void setup(){
              pinMode(SWITCH_PIN, INPUT_PULLUP);           // Setup the button pin, Activate internal pull-up
              
              debouncer.attach(SWITCH_PIN);                // After setting up the button, setup debouncer
              debouncer.interval(5);
            
              pinMode(RELAY_PIN, OUTPUT);                 // set relay pin in output mode
              digitalWrite(RELAY_PIN, RELAY_OFF);         // Make sure relay is off when starting up
            }
            
            void presentation()  {
              // Send the sketch version information to the gateway and Controller
              sendSketchInfo("Relay & Toggle", "1.0");
            
              // Register all sensors to gw (they will be created as child devices)
              present(CHILD_ID, S_BINARY);
            }
            
            
            void loop(){
              if (firstStart) {                            // this code is only run once at startup
                Serial.println("First run started");
                if (request( CHILD_ID, V_STATUS)) {       // request the current state of the switch on the controller and check that an ack was received
                  Serial.println("uplink available");
                  wait (returnWait);                      //wait needed to allow request to return from controller
                  Serial.print("controller state --- ");
                  Serial.println(requestState);
                  if (requestState != state) {           // check that controller is corectly showing the current relay state
                    send(msg.set(state), false);         // notify controller of current state
                  }
                }
                else {
                  Serial.println("uplink not available");
                  uplinkAvailable = false;               // no uplink established
                  uplinkCheckTime = millis();
                }
                firstStart = false;                     // set firstStart flag false to prevent code from running again
              }
            
              debouncer.update();
              int value = debouncer.read();                               // Get the update value
              if (value != oldValue) {                      // check for new throw of toggle switch
                state =  !state;                                          // Toggle the state
                digitalWrite(RELAY_PIN, state ? RELAY_ON : RELAY_OFF);    // switch the relay to the new state
                if (!send(msg.set(state), true)) {                        //Attempt to notify controller of changed state
                  Serial.println("uplink not available");
                  uplinkAvailable = false;                                // no uplink available
                  uplinkCheckTime = millis();                             
                }
               oldValue = value;
              }
             
            
              if (!uplinkAvailable && (millis() - uplinkCheckTime > uplinkCheckPeriod) ) {       // test to see if function should be called
                uplinkCheck();                                                                  // call uplink checking function
              }
            
            }
            
            /*-------------------start of functions--------------------------*/
            
            void receive(const MyMessage &message) {
              if (message.type == V_STATUS) {                                   // check to see if incoming message is for a switch
                switch (message.getCommand()) {                                 // message.getCommand will give us the command type of the incomming message
                  case C_SET:                                                   //message is a set command  from controller to update relay state
                    state = message.getBool();                                  // get the new state
                    digitalWrite(RELAY_PIN, state ? RELAY_ON : RELAY_OFF);      // switch relay to new state
                    uplinkAvailable = true;                                     //  uplink established
                    /*---- Write some debug info----*/
                    Serial.print("Incoming change for sensor:");
                    Serial.print(message.sensor);
                    Serial.print(", New status: ");
                    Serial.println(message.getBool());
                    break;
                  case C_REQ:                                               // message is a returning request from controller
                    requestState = message.getBool();                       // update requestState with returning state
                    break;
                }
              }
            }
            
            void uplinkCheck() {
              if (request( CHILD_ID, V_STATUS)) {         // request the current state of the switch on the controller and check that the request was succsessful
                Serial.println("uplink re-established");
                wait (returnWait);                        //wait needed to allow request to return from controller
                if (requestState != state) {              // check that controller is corectly showing the current relay state
                  send(msg.set(state), false);            // notify controller of current state no ack
                  uplinkAvailable = true;                 //  uplink established
                }
              }
              uplinkCheckTime = millis();                // reset the checktime
              Serial.println("uplinkchecktime reset");
            }
            
            

            This next sketch is for a push button once again but this time it is using requestTime() to try and determine if the controller is available. While all uplink checks are only made to the gateway, by checking for the time returned from the controller it is possible to use this to test for the controllers presence. I have not tested this code extensively but it does appear to work ok within the original design goals.

            /*
               Relay with button sketch
               modified to work with no uplink
               to gateway and try to maintain sync to controller
            */
            
            
            #define MY_DEBUG                               // Enable debug prints to serial monitor
            
            #define MY_RADIO_NRF24                         // Enable and select radio type attached
            //#define MY_RF24_CHANNEL 84
            //#define MY_NODE_ID 203
            #define MY_TRANSPORT_WAIT_READY_MS 5000        //set how long to wait for transport ready in milliseconds
            
            #include <MySensors.h>
            #include <Bounce2.h>
            
            #define RELAY_PIN  4      // Arduino Digital I/O pin number for relay 
            #define BUTTON_PIN  3     // Arduino Digital I/O pin number for button 
            #define CHILD_ID 1        // Id of the sensor child
            #define RELAY_ON 1
            #define RELAY_OFF 0
            
            Bounce debouncer = Bounce();
            int oldValue = 0;
            bool uplinkAvailable = true;
            bool state = false;
            bool requestState;
            bool firstStart = true;
            unsigned long uplinkCheckTime ;                // holder for uplink checks
            unsigned long uplinkCheckPeriod = 30*1000;     // time between checks for uplink in milliseconds
            unsigned long returnWait = 1500;               // how long to wait for return from controller in milliseconds.. adjust as needed
            unsigned long oldTime = 0;
            unsigned long newTime = 0;
            MyMessage msg(CHILD_ID, V_STATUS);
            
            void setup(){
              pinMode(BUTTON_PIN, INPUT_PULLUP);           // Setup the button pin, Activate internal pull-up
              
              debouncer.attach(BUTTON_PIN);                // After setting up the button, setup debouncer
              debouncer.interval(5);
            
              pinMode(RELAY_PIN, OUTPUT);                 // set relay pin in output mode
              digitalWrite(RELAY_PIN, RELAY_OFF);         // Make sure relay is off when starting up
            }
            
            void presentation()  {
              // Send the sketch version information to the gateway and Controller
              sendSketchInfo("Relay & Button test", "1.1");
            
              // Register all sensors to gw (they will be created as child devices)
              present(CHILD_ID, S_BINARY);
            }
            
            
            void loop(){
              if (firstStart) {                            // this code is only run once at startup
                Serial.println("First run started");
                requestTime();                             // get time from controller
                wait (returnWait);                         // delay to allow time to return
                if (oldTime == 0){                         // check to see if there was a return from the time request
                  Serial.println("uplink not available");
                  uplinkAvailable = false;                 // no uplink established
                  uplinkCheckTime = millis();
                }
                 else{
                  Serial.println("uplink available");
                  request( CHILD_ID, V_STATUS);            // get status of switch on controller
                  wait (returnWait);                       //wait needed to allow request to return from controller
                  Serial.print("controller state --- ");
                  Serial.println(requestState);
                  if (requestState != state) {             // check that controller is corectly showing the current relay state
                    send(msg.set(state), false);           // notify controller of current state
                  } 
                 }   
              firstStart = false;                                          // set firstStart flag false to prevent code from running again
             }
            
              debouncer.update();
              int value = debouncer.read();                               // Get the update value
              if (value != oldValue && value == 0) {                      // check for new button push
                state =  !state;                                          // Toggle the state
                digitalWrite(RELAY_PIN, state ? RELAY_ON : RELAY_OFF);    // switch the relay to the new state
                requestTime();
                wait (returnWait);                                               // delay to allow time to return
                if (oldTime != newTime){                                  // if times are different then uplink is available
                  send(msg.set(state), false);
                  oldTime = newTime;
                }
                else{                                                    // if times are the same no uplink is available
                 Serial.println("uplink not available");
                  uplinkAvailable = false;                                // no uplink available, set flag false
                  uplinkCheckTime = millis();                             // start the timer from now
                }
            
              }
              oldValue = value;
             
              if (!uplinkAvailable && (millis() - uplinkCheckTime > uplinkCheckPeriod) ) {       // test to see if function should be called
                uplinkCheck();                                                                  // call uplink checking function
              }
            
            }
            
            /*-------------------start of functions--------------------------*/
            
            void receive(const MyMessage &message) {
              if (message.type == V_STATUS) {                                   // check to see if incoming message is for a switch
                switch (message.getCommand()) {                                 // message.getCommand will give us the command type of the incomming message
                  case C_SET:                                                   //message is a set command  from controller to update relay state
                    state = message.getBool();                                  // get the new state
                    digitalWrite(RELAY_PIN, state ? RELAY_ON : RELAY_OFF);      // switch relay to new state
                    uplinkAvailable = true;                                     //  uplink established
                    /*---- Write some debug info----*/
                    Serial.print("Incoming change for sensor:");
                    Serial.print(message.sensor);
                    Serial.print(", New status: ");
                    Serial.println(message.getBool());
                    break;
                  case C_REQ:                                               // message is a returning request from controller
                    requestState = message.getBool();                       // update requestState with returning state
                    break;
                }
              }
            }
            
            void uplinkCheck() {
                requestTime();
                wait (returnWait);                       // wait for time return.. this may need to be varied for your system
               if (oldTime != newTime){
                 Serial.println("uplink re-established");
                 request( CHILD_ID, V_STATUS);
                 wait (returnWait);                        //wait needed to allow request to return from controller
                if (requestState != state) {              // check that controller is corectly showing the current relay state
                  send(msg.set(state), false);            // notify controller of current state no ack
                  uplinkAvailable = true;                 //  uplink established
                  oldTime = newTime;
                }
              }
              uplinkCheckTime = millis();                // reset the checktime
              Serial.println("uplinkchecktime reset");
            }
            
            
            void receiveTime(unsigned long time)
            {
              if (firstStart){
                oldTime = time;
                newTime = time;
              }
              else{
              newTime = time;
            }
              Serial.print("time received---- " );
              Serial.println(time);
            }
            
            
            
            pepsonP Offline
            pepsonP Offline
            pepson
            wrote on last edited by pepson
            #5

            @boots33

            Can you also share version for 2 relays and also 1relays with temperature sensors DS18B20 Dallas and 2relays also with DS18B20 ?

            And how your sketch check that controller is available ? And if controlller is not available what is do ?

            1 Reply Last reply
            0
            • pepsonP Offline
              pepsonP Offline
              pepson
              wrote on last edited by pepson
              #6

              Ok i test your sketch with custom my radio. It look as this below.
              This look that works ok. When controller is ENABLE and i only disable on controller GATEWAY, then change status NODE and again ENABLE gateway status node on controller is refresh after some time. Also when POWER OFF controller and gateway and then change status NODE , also status is correct refresh on controller after bootup controller with gateway.

              Status is not refreshed only in one situation. When i only reboote controller with gateway and under reboote i change status NODE. After run controller and gateway status is not refresh and show not correct.

              Please share me this sketch if you can for 2xrelays ? And also option with send temperature from Dallas DS18b20 ?

              One question... How change time betwen change relay on and off. Now i must wait about 2-4 secund before try change status on off by button. Can i change this time ?

              /*
                 Relay with button sketch
                 modified to work with no uplink
                 to gateway and try to maintain sync to controller
              */
              
              
              #define MY_DEBUG                               // Enable debug prints to serial monitor
              
              #define MY_RADIO_RFM69
              #define MY_RFM69_FREQUENCY RF69_868MHZ
              #define MY_IS_RFM69HW
              
              //#define MY_NODE_ID 203                       // Node id defaults to AUTO (tries to fetch id from controller) 
              
              #define MY_TRANSPORT_WAIT_READY_MS 5000        //set how long to wait for transport ready in milliseconds
              
              #define MY_REPEATER_FEATURE                    // Enabled repeater feature for this node
              
              #include <MySensors.h>
              #include <Bounce2.h>
              
              #define RELAY_PIN  5      // Arduino Digital I/O pin number for relay 
              #define BUTTON_PIN  3     // Arduino Digital I/O pin number for button 
              #define CHILD_ID 1        // Id of the sensor child
              #define RELAY_ON 1
              #define RELAY_OFF 0
              
              Bounce debouncer = Bounce();
              int oldValue = 0;
              bool uplinkAvailable = true;
              bool state = false;
              bool requestState;
              bool firstStart = true;
              unsigned long uplinkCheckTime ;                // holder for uplink checks
              unsigned long uplinkCheckPeriod = 30*1000;     // time between checks for uplink in milliseconds
              unsigned long returnWait = 1500;               // how long to wait for return from controller in milliseconds.. adjust as needed
              unsigned long oldTime = 0;
              unsigned long newTime = 0;
              MyMessage msg(CHILD_ID, V_STATUS);
              
              void setup(){
                pinMode(BUTTON_PIN, INPUT_PULLUP);           // Setup the button pin, Activate internal pull-up
                
                debouncer.attach(BUTTON_PIN);                // After setting up the button, setup debouncer
                debouncer.interval(5);
              
                pinMode(RELAY_PIN, OUTPUT);                 // set relay pin in output mode
                digitalWrite(RELAY_PIN, RELAY_OFF);         // Make sure relay is off when starting up
              }
              
              void presentation()  {
                // Send the sketch version information to the gateway and Controller
                sendSketchInfo("Relay & Button test", "1.1");
              
                // Register all sensors to gw (they will be created as child devices)
                present(CHILD_ID, S_BINARY);
              }
              
              
              void loop(){
                if (firstStart) {                            // this code is only run once at startup
                  Serial.println("First run started");
                  requestTime();                             // get time from controller
                  wait (returnWait);                         // delay to allow time to return
                  if (oldTime == 0){                         // check to see if there was a return from the time request
                    Serial.println("uplink not available");
                    uplinkAvailable = false;                 // no uplink established
                    uplinkCheckTime = millis();
                  }
                   else{
                    Serial.println("uplink available");
                    request( CHILD_ID, V_STATUS);            // get status of switch on controller
                    wait (returnWait);                       //wait needed to allow request to return from controller
                    Serial.print("controller state --- ");
                    Serial.println(requestState);
                    if (requestState != state) {             // check that controller is corectly showing the current relay state
                      send(msg.set(state), false);           // notify controller of current state
                    } 
                   }   
                firstStart = false;                                          // set firstStart flag false to prevent code from running again
               }
              
                debouncer.update();
                int value = debouncer.read();                               // Get the update value
                if (value != oldValue && value == 0) {                      // check for new button push
                  state =  !state;                                          // Toggle the state
                  digitalWrite(RELAY_PIN, state ? RELAY_ON : RELAY_OFF);    // switch the relay to the new state
                  requestTime();
                  wait (returnWait);                                               // delay to allow time to return
                  if (oldTime != newTime){                                  // if times are different then uplink is available
                    send(msg.set(state), false);
                    oldTime = newTime;
                  }
                  else{                                                    // if times are the same no uplink is available
                   Serial.println("uplink not available");
                    uplinkAvailable = false;                                // no uplink available, set flag false
                    uplinkCheckTime = millis();                             // start the timer from now
                  }
              
                }
                oldValue = value;
               
                if (!uplinkAvailable && (millis() - uplinkCheckTime > uplinkCheckPeriod) ) {       // test to see if function should be called
                  uplinkCheck();                                                                  // call uplink checking function
                }
              
              }
              
              /*-------------------start of functions--------------------------*/
              
              void receive(const MyMessage &message) {
                if (message.type == V_STATUS) {                                   // check to see if incoming message is for a switch
                  switch (message.getCommand()) {                                 // message.getCommand will give us the command type of the incomming message
                    case C_SET:                                                   //message is a set command  from controller to update relay state
                      state = message.getBool();                                  // get the new state
                      digitalWrite(RELAY_PIN, state ? RELAY_ON : RELAY_OFF);      // switch relay to new state
                      uplinkAvailable = true;                                     //  uplink established
                      /*---- Write some debug info----*/
                      Serial.print("Incoming change for sensor:");
                      Serial.print(message.sensor);
                      Serial.print(", New status: ");
                      Serial.println(message.getBool());
                      break;
                    case C_REQ:                                               // message is a returning request from controller
                      requestState = message.getBool();                       // update requestState with returning state
                      break;
                  }
                }
              }
              
              void uplinkCheck() {
                  requestTime();
                  wait (returnWait);                       // wait for time return.. this may need to be varied for your system
                 if (oldTime != newTime){
                   Serial.println("uplink re-established");
                   request( CHILD_ID, V_STATUS);
                   wait (returnWait);                        //wait needed to allow request to return from controller
                  if (requestState != state) {              // check that controller is corectly showing the current relay state
                    send(msg.set(state), false);            // notify controller of current state no ack
                    uplinkAvailable = true;                 //  uplink established
                    oldTime = newTime;
                  }
                }
                uplinkCheckTime = millis();                // reset the checktime
                Serial.println("uplinkchecktime reset");
              }
              
              
              void receiveTime(unsigned long time)
              {
                if (firstStart){
                  oldTime = time;
                  newTime = time;
                }
                else{
                newTime = time;
              }
                Serial.print("time received---- " );
                Serial.println(time);
              }```
              Boots33B 1 Reply Last reply
              0
              • pepsonP pepson

                Ok i test your sketch with custom my radio. It look as this below.
                This look that works ok. When controller is ENABLE and i only disable on controller GATEWAY, then change status NODE and again ENABLE gateway status node on controller is refresh after some time. Also when POWER OFF controller and gateway and then change status NODE , also status is correct refresh on controller after bootup controller with gateway.

                Status is not refreshed only in one situation. When i only reboote controller with gateway and under reboote i change status NODE. After run controller and gateway status is not refresh and show not correct.

                Please share me this sketch if you can for 2xrelays ? And also option with send temperature from Dallas DS18b20 ?

                One question... How change time betwen change relay on and off. Now i must wait about 2-4 secund before try change status on off by button. Can i change this time ?

                /*
                   Relay with button sketch
                   modified to work with no uplink
                   to gateway and try to maintain sync to controller
                */
                
                
                #define MY_DEBUG                               // Enable debug prints to serial monitor
                
                #define MY_RADIO_RFM69
                #define MY_RFM69_FREQUENCY RF69_868MHZ
                #define MY_IS_RFM69HW
                
                //#define MY_NODE_ID 203                       // Node id defaults to AUTO (tries to fetch id from controller) 
                
                #define MY_TRANSPORT_WAIT_READY_MS 5000        //set how long to wait for transport ready in milliseconds
                
                #define MY_REPEATER_FEATURE                    // Enabled repeater feature for this node
                
                #include <MySensors.h>
                #include <Bounce2.h>
                
                #define RELAY_PIN  5      // Arduino Digital I/O pin number for relay 
                #define BUTTON_PIN  3     // Arduino Digital I/O pin number for button 
                #define CHILD_ID 1        // Id of the sensor child
                #define RELAY_ON 1
                #define RELAY_OFF 0
                
                Bounce debouncer = Bounce();
                int oldValue = 0;
                bool uplinkAvailable = true;
                bool state = false;
                bool requestState;
                bool firstStart = true;
                unsigned long uplinkCheckTime ;                // holder for uplink checks
                unsigned long uplinkCheckPeriod = 30*1000;     // time between checks for uplink in milliseconds
                unsigned long returnWait = 1500;               // how long to wait for return from controller in milliseconds.. adjust as needed
                unsigned long oldTime = 0;
                unsigned long newTime = 0;
                MyMessage msg(CHILD_ID, V_STATUS);
                
                void setup(){
                  pinMode(BUTTON_PIN, INPUT_PULLUP);           // Setup the button pin, Activate internal pull-up
                  
                  debouncer.attach(BUTTON_PIN);                // After setting up the button, setup debouncer
                  debouncer.interval(5);
                
                  pinMode(RELAY_PIN, OUTPUT);                 // set relay pin in output mode
                  digitalWrite(RELAY_PIN, RELAY_OFF);         // Make sure relay is off when starting up
                }
                
                void presentation()  {
                  // Send the sketch version information to the gateway and Controller
                  sendSketchInfo("Relay & Button test", "1.1");
                
                  // Register all sensors to gw (they will be created as child devices)
                  present(CHILD_ID, S_BINARY);
                }
                
                
                void loop(){
                  if (firstStart) {                            // this code is only run once at startup
                    Serial.println("First run started");
                    requestTime();                             // get time from controller
                    wait (returnWait);                         // delay to allow time to return
                    if (oldTime == 0){                         // check to see if there was a return from the time request
                      Serial.println("uplink not available");
                      uplinkAvailable = false;                 // no uplink established
                      uplinkCheckTime = millis();
                    }
                     else{
                      Serial.println("uplink available");
                      request( CHILD_ID, V_STATUS);            // get status of switch on controller
                      wait (returnWait);                       //wait needed to allow request to return from controller
                      Serial.print("controller state --- ");
                      Serial.println(requestState);
                      if (requestState != state) {             // check that controller is corectly showing the current relay state
                        send(msg.set(state), false);           // notify controller of current state
                      } 
                     }   
                  firstStart = false;                                          // set firstStart flag false to prevent code from running again
                 }
                
                  debouncer.update();
                  int value = debouncer.read();                               // Get the update value
                  if (value != oldValue && value == 0) {                      // check for new button push
                    state =  !state;                                          // Toggle the state
                    digitalWrite(RELAY_PIN, state ? RELAY_ON : RELAY_OFF);    // switch the relay to the new state
                    requestTime();
                    wait (returnWait);                                               // delay to allow time to return
                    if (oldTime != newTime){                                  // if times are different then uplink is available
                      send(msg.set(state), false);
                      oldTime = newTime;
                    }
                    else{                                                    // if times are the same no uplink is available
                     Serial.println("uplink not available");
                      uplinkAvailable = false;                                // no uplink available, set flag false
                      uplinkCheckTime = millis();                             // start the timer from now
                    }
                
                  }
                  oldValue = value;
                 
                  if (!uplinkAvailable && (millis() - uplinkCheckTime > uplinkCheckPeriod) ) {       // test to see if function should be called
                    uplinkCheck();                                                                  // call uplink checking function
                  }
                
                }
                
                /*-------------------start of functions--------------------------*/
                
                void receive(const MyMessage &message) {
                  if (message.type == V_STATUS) {                                   // check to see if incoming message is for a switch
                    switch (message.getCommand()) {                                 // message.getCommand will give us the command type of the incomming message
                      case C_SET:                                                   //message is a set command  from controller to update relay state
                        state = message.getBool();                                  // get the new state
                        digitalWrite(RELAY_PIN, state ? RELAY_ON : RELAY_OFF);      // switch relay to new state
                        uplinkAvailable = true;                                     //  uplink established
                        /*---- Write some debug info----*/
                        Serial.print("Incoming change for sensor:");
                        Serial.print(message.sensor);
                        Serial.print(", New status: ");
                        Serial.println(message.getBool());
                        break;
                      case C_REQ:                                               // message is a returning request from controller
                        requestState = message.getBool();                       // update requestState with returning state
                        break;
                    }
                  }
                }
                
                void uplinkCheck() {
                    requestTime();
                    wait (returnWait);                       // wait for time return.. this may need to be varied for your system
                   if (oldTime != newTime){
                     Serial.println("uplink re-established");
                     request( CHILD_ID, V_STATUS);
                     wait (returnWait);                        //wait needed to allow request to return from controller
                    if (requestState != state) {              // check that controller is corectly showing the current relay state
                      send(msg.set(state), false);            // notify controller of current state no ack
                      uplinkAvailable = true;                 //  uplink established
                      oldTime = newTime;
                    }
                  }
                  uplinkCheckTime = millis();                // reset the checktime
                  Serial.println("uplinkchecktime reset");
                }
                
                
                void receiveTime(unsigned long time)
                {
                  if (firstStart){
                    oldTime = time;
                    newTime = time;
                  }
                  else{
                  newTime = time;
                }
                  Serial.print("time received---- " );
                  Serial.println(time);
                }```
                Boots33B Offline
                Boots33B Offline
                Boots33
                Hero Member
                wrote on last edited by
                #7

                @pepson said in Synchronising Light switch:

                Status is not refreshed only in one situation. When i only reboote controller with gateway and under reboote i change status NODE. After run controller and gateway status is not refresh and show not correct.

                Sorry I do not understand what start up scenario you are describing here. Can you post details of the exact steps needed to replicate this problem.

                Please share me this sketch if you can for 2xrelays ? And also option with send temperature from Dallas DS18b20 ?

                I do not have any sketches that include switches & temperature sensors, there are however some posts already on combining relays and temp senders. You should do a search to locate them or perhaps start a new thread about that.

                One question... How change time betwen change relay on and off. Now i must wait about 2-4 secund before try change status on off by button. Can i change this time ?

                The relay should change from on/off instantly from the local switch or from the controller.
                The delay in being able to continuously flick the switch between on and off will most likely be caused by the delay required to receive the time return.
                As I said in an earlier post : In testing the return from request usually arrived within 800 milliseconds so returnWait could also be reduced from 1500ms if it was a concern.

                If you reduce it too far the switch sync will once again become unreliable. This is the trade off for a sync switch

                Why do you need to switch your lights every 2 seconds?

                1 Reply Last reply
                0
                • pepsonP Offline
                  pepsonP Offline
                  pepson
                  wrote on last edited by
                  #8

                  If i need fast on and then off light.
                  But ok i test with change returnWait about 1000.

                  But can you also share me only sketch for 2 or more relay ? This will be good sketch also for other user... Thanks for your help.
                  You are the best :)

                  1 Reply Last reply
                  0
                  • pepsonP Offline
                    pepsonP Offline
                    pepson
                    wrote on last edited by pepson
                    #9

                    Please help me modification this script to support 2x relays with button. I start modification but i dont know how finished it...

                    /*
                       2xRelay with button sketch
                       modified to work with no uplink
                       to gateway and try to maintain sync to controller
                    */
                    
                    
                    #define MY_DEBUG                               // Enable debug prints to serial monitor
                    
                    #define MY_RADIO_RFM69
                    #define MY_RFM69_FREQUENCY RF69_868MHZ
                    #define MY_IS_RFM69HW
                    
                    //#define MY_NODE_ID 203                       // Node id defaults to AUTO (tries to fetch id from controller) 
                    
                    #define MY_TRANSPORT_WAIT_READY_MS 5000        //set how long to wait for transport ready in milliseconds
                    
                    #define MY_REPEATER_FEATURE                    // Enabled repeater feature for this node
                    
                    #include <MySensors.h>
                    #include <Bounce2.h>
                    
                    #define RELAY_PIN_A  5      // Arduino Digital I/O pin number for relay A
                    #define BUTTON_PIN_A  3     // Arduino Digital I/O pin number for button A
                    #define RELAY_PIN_B  6      // Arduino Digital I/O pin number for relay B
                    #define BUTTON_PIN_B  4     // Arduino Digital I/O pin number for button B
                    #define CHILD_ID_A 1        // Id of the sensor child A
                    #define CHILD_ID_B 2        // Id of the sensor child B
                    #define RELAY_ON 1
                    #define RELAY_OFF 0
                    
                    Bounce debouncer = Bounce();
                    int oldValue = 0;
                    bool uplinkAvailable = true;
                    bool stateA = false;
                    bool stateB = false;
                    bool requestState;
                    bool firstStart = true;
                    unsigned long uplinkCheckTime ;                // holder for uplink checks
                    unsigned long uplinkCheckPeriod = 30*1000;     // time between checks for uplink in milliseconds
                    unsigned long returnWait = 1000;               // how long to wait for return from controller in milliseconds.. adjust as needed
                    unsigned long oldTime = 0;
                    unsigned long newTime = 0;
                    MyMessage msg(CHILD_ID_A, V_STATUS);
                    MyMessage msg(CHILD_ID_B, V_STATUS);
                    
                    void setup(){
                      pinMode(BUTTON_PIN, INPUT_PULLUP);           // Setup the button pin, Activate internal pull-up
                      
                      debouncer.attach(BUTTON_PIN_A);                // After setting up the button A, setup debouncer
                      debouncer.interval(5);
                      debouncer.attach(BUTTON_PIN_B);                // After setting up the button B, setup debouncer
                      debouncer.interval(5);
                    
                      pinMode(RELAY_PIN_A, OUTPUT);                 // set relay A pin in output mode
                      digitalWrite(RELAY_PIN_A, RELAY_OFF);         // Make sure relay B is off when starting up
                      pinMode(RELAY_PIN_B, OUTPUT);                 // set relay B pin in output mode
                      digitalWrite(RELAY_PIN_B, RELAY_OFF);         // Make sure relay B is off when starting up
                    }
                    
                    void presentation()  {
                      // Send the sketch version information to the gateway and Controller
                      sendSketchInfo("2xRelay & Button", "2.1.1");
                    
                      // Register all sensors to gw (they will be created as child devices)
                      present(CHILD_ID_A, S_BINARY);
                      present(CHILD_ID_B, S_BINARY);
                    }
                    
                    
                    void loop(){
                      if (firstStart) {                            // this code is only run once at startup
                        Serial.println("First run started");
                        requestTime();                             // get time from controller
                        wait (returnWait);                         // delay to allow time to return
                        if (oldTime == 0){                         // check to see if there was a return from the time request
                          Serial.println("uplink not available");
                          uplinkAvailable = false;                 // no uplink established
                          uplinkCheckTime = millis();
                        }
                         else{
                          Serial.println("uplink available");
                          request( CHILD_ID_A, V_STATUS);            // get status of switch on controller
                          wait (returnWait);                       //wait needed to allow request to return from controller
                          Serial.print("controller state --- ");
                          Serial.println(requestState);
                          if (requestState != state) {             // check that controller is corectly showing the current relay state
                            send(msg.set(state), false);           // notify controller of current state
                          } 
                         }   
                      firstStart = false;                                          // set firstStart flag false to prevent code from running again
                     }
                    
                      debouncer.update();
                      int value = debouncer.read();                               // Get the update value
                      if (value != oldValue && value == 0) {                      // check for new button push
                        state =  !state;                                          // Toggle the state
                        digitalWrite(RELAY_PIN_A, state ? RELAY_ON : RELAY_OFF);    // switch the relay to the new state
                        requestTime();
                        wait (returnWait);                                               // delay to allow time to return
                        if (oldTime != newTime){                                  // if times are different then uplink is available
                          send(msg.set(state), false);
                          oldTime = newTime;
                        }
                        else{                                                    // if times are the same no uplink is available
                         Serial.println("uplink not available");
                          uplinkAvailable = false;                                // no uplink available, set flag false
                          uplinkCheckTime = millis();                             // start the timer from now
                        }
                    
                      }
                    
                      if (firstStart) {                            // this code is only run once at startup
                        Serial.println("First run started");
                        requestTime();                             // get time from controller
                        wait (returnWait);                         // delay to allow time to return
                        if (oldTime == 0){                         // check to see if there was a return from the time request
                          Serial.println("uplink not available");
                          uplinkAvailable = false;                 // no uplink established
                          uplinkCheckTime = millis();
                        }
                         else{
                          Serial.println("uplink available");
                          request( CHILD_ID_B, V_STATUS);            // get status of switch on controller
                          wait (returnWait);                       //wait needed to allow request to return from controller
                          Serial.print("controller state --- ");
                          Serial.println(requestState);
                          if (requestState != state) {             // check that controller is corectly showing the current relay state
                            send(msg.set(state), false);           // notify controller of current state
                          } 
                         }   
                      firstStart = false;                                          // set firstStart flag false to prevent code from running again
                     }
                    
                      debouncer.update();
                      int value = debouncer.read();                               // Get the update value
                      if (value != oldValue && value == 0) {                      // check for new button push
                        state =  !state;                                          // Toggle the state
                        digitalWrite(RELAY_PIN_B, stateB ? RELAY_ON : RELAY_OFF);    // switch the relay to the new state
                        requestTime();
                        wait (returnWait);                                               // delay to allow time to return
                        if (oldTime != newTime){                                  // if times are different then uplink is available
                          send(msg.set(stateB), false);
                          oldTime = newTime;
                        }
                        else{                                                    // if times are the same no uplink is available
                         Serial.println("uplink not available");
                          uplinkAvailable = false;                                // no uplink available, set flag false
                          uplinkCheckTime = millis();                             // start the timer from now
                        }
                    
                      }
                      oldValue = value;
                     
                      if (!uplinkAvailable && (millis() - uplinkCheckTime > uplinkCheckPeriod) ) {       // test to see if function should be called
                        uplinkCheck();                                                                  // call uplink checking function
                      }
                    
                    }
                    
                    /*-------------------start of functions--------------------------*/
                    
                    void receive(const MyMessage &message) {
                      if (message.type == V_STATUS) {                                   // check to see if incoming message is for a switch
                        switch (message.getCommand()) {                                 // message.getCommand will give us the command type of the incomming message
                          case C_SET:                                                   //message is a set command  from controller to update relay state
                            state = message.getBool();                                  // get the new state
                            digitalWrite(RELAY_PIN_A, stateA ? RELAY_ON : RELAY_OFF);      // switch relay to new state
                            uplinkAvailable = true;                                     //  uplink established
                            /*---- Write some debug info----*/
                            Serial.print("Incoming change for sensor:");
                            Serial.print(message.sensor);
                            Serial.print(", New status: ");
                            Serial.println(message.getBool());
                            break;
                          case C_REQ:                                               // message is a returning request from controller
                            requestState = message.getBool();                       // update requestState with returning state
                            break;
                        }
                      }
                    
                      if (message.type == V_STATUS) {                                   // check to see if incoming message is for a switch
                        switch (message.getCommand()) {                                 // message.getCommand will give us the command type of the incomming message
                          case C_SET:                                                   //message is a set command  from controller to update relay state
                            state = message.getBool();                                  // get the new state
                            digitalWrite(RELAY_PIN_B, stateB ? RELAY_ON : RELAY_OFF);      // switch relay to new state
                            uplinkAvailable = true;                                     //  uplink established
                            /*---- Write some debug info----*/
                            Serial.print("Incoming change for sensor:");
                            Serial.print(message.sensor);
                            Serial.print(", New status: ");
                            Serial.println(message.getBool());
                            break;
                          case C_REQ:                                               // message is a returning request from controller
                            requestState = message.getBool();                       // update requestState with returning state
                            break;
                        }
                      }
                    }
                    
                    void uplinkCheck() {
                        requestTime();
                        wait (returnWait);                       // wait for time return.. this may need to be varied for your system
                       if (oldTime != newTime){
                         Serial.println("uplink re-established");
                         request( CHILD_ID_A, V_STATUS);
                         wait (returnWait);                        //wait needed to allow request to return from controller
                        if (requestState != stateA) {              // check that controller is corectly showing the current relay state
                          send(msg.set(state), false);            // notify controller of current state no ack
                          uplinkAvailable = true;                 //  uplink established
                          oldTime = newTime;
                        }
                      }
                      uplinkCheckTime = millis();                // reset the checktime
                      Serial.println("uplinkchecktime reset");
                    }
                    
                    
                    void receiveTime(unsigned long time)
                    {
                      if (firstStart){
                        oldTime = time;
                        newTime = time;
                      }
                      else{
                      newTime = time;
                    }
                      Serial.print("time received---- " );
                      Serial.println(time);
                    }```
                    1 Reply Last reply
                    0
                    • pepsonP Offline
                      pepsonP Offline
                      pepson
                      wrote on last edited by
                      #10

                      Hi
                      Can you help me convert this skecth for MySensors 2.2.0 because it was released. I upload to my Arduino MIni Pro this sketch but in Gateway Domoticz not show child to switch relay. Only show repeater child on ID 255.
                      And also if you can please share me ready skecth for 2x releay.

                      /*
                         Relay with button sketch
                         modified to work with no uplink
                         to gateway and try to maintain sync to controller
                      */
                      
                      
                      #define MY_DEBUG                               // Enable debug prints to serial monitor
                      
                      #define MY_RADIO_RFM69
                      #define MY_IS_RFM69HW
                      #define RFM69_868MH
                      #define MY_RFM69_NEW_DRIVER
                      
                      //#define MY_NODE_ID 203                       // Node id defaults to AUTO (tries to fetch id from controller) 
                      
                      #define MY_TRANSPORT_WAIT_READY_MS 5000        //set how long to wait for transport ready in milliseconds
                      
                      #define MY_REPEATER_FEATURE                    // Enabled repeater feature for this node
                      
                      #include <MySensors.h>
                      #include <Bounce2.h>
                      
                      #define RELAY_PIN  5      // Arduino Digital I/O pin number for relay 
                      #define BUTTON_PIN  3     // Arduino Digital I/O pin number for button 
                      #define CHILD_ID 1        // Id of the sensor child
                      #define RELAY_ON 1
                      #define RELAY_OFF 0
                      
                      Bounce debouncer = Bounce();
                      int oldValue = 0;
                      bool uplinkAvailable = true;
                      bool state = false;
                      bool requestState;
                      bool firstStart = true;
                      unsigned long uplinkCheckTime ;                // holder for uplink checks
                      unsigned long uplinkCheckPeriod = 30*1000;     // time between checks for uplink in milliseconds
                      unsigned long returnWait = 1000;               // how long to wait for return from controller in milliseconds.. adjust as needed
                      unsigned long oldTime = 0;
                      unsigned long newTime = 0;
                      MyMessage msg(CHILD_ID, V_STATUS);
                      
                      void setup(){
                        pinMode(BUTTON_PIN, INPUT_PULLUP);           // Setup the button pin, Activate internal pull-up
                        
                        debouncer.attach(BUTTON_PIN);                // After setting up the button, setup debouncer
                        debouncer.interval(5);
                      
                        pinMode(RELAY_PIN, OUTPUT);                 // set relay pin in output mode
                        digitalWrite(RELAY_PIN, RELAY_OFF);         // Make sure relay is off when starting up
                      }
                      
                      void presentation()  {
                        // Send the sketch version information to the gateway and Controller
                        sendSketchInfo("1xRelay & Button", "2.2.0");
                      
                        // Register all sensors to gw (they will be created as child devices)
                        present(CHILD_ID, S_BINARY);
                      }
                      
                      
                      void loop(){
                        if (firstStart) {                            // this code is only run once at startup
                          Serial.println("First run started");
                          requestTime();                             // get time from controller
                          wait (returnWait);                         // delay to allow time to return
                          if (oldTime == 0){                         // check to see if there was a return from the time request
                            Serial.println("uplink not available");
                            uplinkAvailable = false;                 // no uplink established
                            uplinkCheckTime = millis();
                          }
                           else{
                            Serial.println("uplink available");
                            request( CHILD_ID, V_STATUS);            // get status of switch on controller
                            wait (returnWait);                       //wait needed to allow request to return from controller
                            Serial.print("controller state --- ");
                            Serial.println(requestState);
                            if (requestState != state) {             // check that controller is corectly showing the current relay state
                              send(msg.set(state), false);           // notify controller of current state
                            } 
                           }   
                        firstStart = false;                                          // set firstStart flag false to prevent code from running again
                       }
                      
                        debouncer.update();
                        int value = debouncer.read();                               // Get the update value
                        if (value != oldValue && value == 0) {                      // check for new button push
                          state =  !state;                                          // Toggle the state
                          digitalWrite(RELAY_PIN, state ? RELAY_ON : RELAY_OFF);    // switch the relay to the new state
                          requestTime();
                          wait (returnWait);                                               // delay to allow time to return
                          if (oldTime != newTime){                                  // if times are different then uplink is available
                            send(msg.set(state), false);
                            oldTime = newTime;
                          }
                          else{                                                    // if times are the same no uplink is available
                           Serial.println("uplink not available");
                            uplinkAvailable = false;                                // no uplink available, set flag false
                            uplinkCheckTime = millis();                             // start the timer from now
                          }
                      
                        }
                        oldValue = value;
                       
                        if (!uplinkAvailable && (millis() - uplinkCheckTime > uplinkCheckPeriod) ) {       // test to see if function should be called
                          uplinkCheck();                                                                  // call uplink checking function
                        }
                      
                      }
                      
                      /*-------------------start of functions--------------------------*/
                      
                      void receive(const MyMessage &message) {
                        if (message.type == V_STATUS) {                                   // check to see if incoming message is for a switch
                          switch (message.getCommand()) {                                 // message.getCommand will give us the command type of the incomming message
                            case C_SET:                                                   //message is a set command  from controller to update relay state
                              state = message.getBool();                                  // get the new state
                              digitalWrite(RELAY_PIN, state ? RELAY_ON : RELAY_OFF);      // switch relay to new state
                              uplinkAvailable = true;                                     //  uplink established
                              /*---- Write some debug info----*/
                              Serial.print("Incoming change for sensor:");
                              Serial.print(message.sensor);
                              Serial.print(", New status: ");
                              Serial.println(message.getBool());
                              break;
                            case C_REQ:                                               // message is a returning request from controller
                              requestState = message.getBool();                       // update requestState with returning state
                              break;
                          }
                        }
                      }
                      
                      void uplinkCheck() {
                          requestTime();
                          wait (returnWait);                       // wait for time return.. this may need to be varied for your system
                         if (oldTime != newTime){
                           Serial.println("uplink re-established");
                           request( CHILD_ID, V_STATUS);
                           wait (returnWait);                        //wait needed to allow request to return from controller
                          if (requestState != state) {              // check that controller is corectly showing the current relay state
                            send(msg.set(state), false);            // notify controller of current state no ack
                            uplinkAvailable = true;                 //  uplink established
                            oldTime = newTime;
                          }
                        }
                        uplinkCheckTime = millis();                // reset the checktime
                        Serial.println("uplinkchecktime reset");
                      }
                      
                      
                      void receiveTime(unsigned long time)
                      {
                        if (firstStart){
                          oldTime = time;
                          newTime = time;
                        }
                        else{
                        newTime = time;
                      }
                        Serial.print("time received---- " );
                        Serial.println(time);
                      }
                      
                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      6

                      Online

                      11.7k

                      Users

                      11.2k

                      Topics

                      113.0k

                      Posts


                      Copyright 2019 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