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. General Discussion
  3. Array Relay Button Actuator

Array Relay Button Actuator

Scheduled Pinned Locked Moved General Discussion
45 Posts 16 Posters 24.8k Views 16 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.
  • R Offline
    R Offline
    rainair
    wrote on last edited by
    #21

    Hello this is my first post, but i follow my sensors for about 2 months.
    Excuse my bad english.

    For those how want use a normal in wall switch

    just change the line:

    if (value != Relays[i].oldValue && value == 0){
    

    to

    if (value != Relays[i].oldValue){
    

    to

    hope this was a bit helpfully

    1 Reply Last reply
    0
    • jeylitesJ Offline
      jeylitesJ Offline
      jeylites
      wrote on last edited by jeylites
      #22

      @rainair, I tested it and it works! Thanks!!!

      1 Reply Last reply
      0
      • G Offline
        G Offline
        gonzalonal
        wrote on last edited by
        #23

        @jeylites said:

        Relays[i].relayState = gw.loadState(i); // retrieve last values from EEPROM
        digitalWrite(Relays[i].relayPin, Relays[i].relayState? RELAY_ON:RELAY_OFF); // and set relays accordingly
        gw.send(msg[i].set(Relays[i].relayState? true : false)); // make controller aware of last status
        gw.present(i, S_LIGHT); // present sensor to gateway
        delay(250);

        It's my idea, or shouldn't the sensor be presented to the gateway before sending it status?
        Thanks! regards.

        1 Reply Last reply
        0
        • jeylitesJ Offline
          jeylitesJ Offline
          jeylites
          wrote on last edited by
          #24

          @gonzalonal

          I don't think it matters. You could try flip "gw.send & gw.present" and see how it respond to the change.

          1 Reply Last reply
          0
          • E Offline
            E Offline
            ewgor
            wrote on last edited by
            #25

            Wow ! this is what i was looking for ... Could anyone please share with us some Openhab settings for this wonderful Arduino sketch?
            How can we assign in OH buttons to correspond to the physical buttons on the breadboard ?

            Looking for any answer.

            Thanks all!

            1 Reply Last reply
            0
            • Cliff KarlssonC Offline
              Cliff KarlssonC Offline
              Cliff Karlsson
              wrote on last edited by
              #26

              How would I update this to work with 1.6?

              N 1 Reply Last reply
              0
              • Cliff KarlssonC Cliff Karlsson

                How would I update this to work with 1.6?

                N Offline
                N Offline
                niccodemi
                wrote on last edited by
                #27

                @Cliff-Karlsson I recently started using 1.6 version, below is converted sketch. It works with momentary (pushbuttons) switches only.

                Does anyone have sketch for toggle switches?

                #define MY_RADIO_NRF24
                
                #define MY_REPEATER_FEATURE
                
                #include <MySensor.h>
                
                #include <SPI.h>
                #include <Bounce2.h>
                #define RELAY_ON 0                      // switch around for relay HIGH/LOW state
                #define RELAY_OFF 1
                //
                
                #define noRelays 2                     //2-4
                const int relayPin[] = {14,15};          //  switch around pins to your desire
                const int buttonPin[] = {3,4};      //  switch around pins to your desire
                
                class Relay             // relay class, store all relevant data (equivalent to struct)
                {
                public:                                      
                  int buttonPin;                   // physical pin number of button
                  int relayPin;             // physical pin number of relay
                  byte oldValue;                    // last Values for key (debounce)
                  boolean relayState;               // relay status (also stored in EEPROM)
                };
                
                Relay Relays[noRelays]; 
                Bounce debouncer[noRelays];
                MyMessage msg[noRelays];
                
                void setup(){
                    sendHeartbeat();
                    wait(250);
                    // Initialize Relays with corresponding buttons
                    for (int i = 0; i < noRelays; i++){
                    Relays[i].buttonPin = buttonPin[i];              // assign physical pins
                    Relays[i].relayPin = relayPin[i];
                    msg[i].sensor = i;                                   // initialize messages
                    msg[i].type = V_LIGHT;
                    debouncer[i] = Bounce();                        // initialize debouncer
                    debouncer[i].attach(buttonPin[i]);
                    debouncer[i].interval(5);
                    pinMode(Relays[i].buttonPin, INPUT_PULLUP);
                    //digitalWrite(Relays[i].relayPin, RELAY_OFF);
                    wait(250);
                    pinMode(Relays[i].relayPin, OUTPUT);
                    Relays[i].relayState = loadState(i);                               // retrieve last values from EEPROM
                    digitalWrite(Relays[i].relayPin, Relays[i].relayState? RELAY_ON:RELAY_OFF);   // and set relays accordingly
                    send(msg[i].set(Relays[i].relayState? true : false));                  // make controller aware of last status  
                    wait(250);
                    }
                }
                void presentation()  {
                      sendSketchInfo("MultiRelayButton", "0.9f");
                      wait(250);
                      for (int i = 0; i < noRelays; i++)
                      present(i, S_LIGHT);                               // present sensor to gateway
                }
                void loop()
                    {
                    for (byte i = 0; i < noRelays; i++){
                    debouncer[i].update();
                    byte value = debouncer[i].read();
                    if (value != Relays[i].oldValue && value==0){
                    Relays[i].relayState = !Relays[i].relayState;
                    digitalWrite(Relays[i].relayPin, Relays[i].relayState?RELAY_ON:RELAY_OFF);
                    send(msg[i].set(Relays[i].relayState? true : false));
                    saveState( i, Relays[i].relayState );}                 // save sensor state in EEPROM (location == sensor number)
                    
                        Relays[i].oldValue = value;      
                    }
                }
                // process incoming message 
                void receive(const MyMessage &message){        
                   if (message.type == V_LIGHT){ 
                   if (message.sensor <noRelays){            // check if message is valid for relays..... previous line  [[[ if (message.sensor <=noRelays){ ]]]
                   Relays[message.sensor].relayState = message.getBool(); 
                   digitalWrite(Relays[message.sensor].relayPin, Relays[message.sensor].relayState? RELAY_ON:RELAY_OFF); // and set relays accordingly
                   saveState( message.sensor, Relays[message.sensor].relayState ); // save sensor state in EEPROM (location == sensor number)
                   }
                  }
                }
                
                1 Reply Last reply
                0
                • jeylitesJ Offline
                  jeylitesJ Offline
                  jeylites
                  wrote on last edited by jeylites
                  #28

                  The following sketch has got what you're looking for. Hope that helps.

                  Relay With Actuator Switch Toggle

                  #include <MySensor.h>
                  #include <SPI.h>
                  #include <Bounce2.h>
                  #define RELAY_ON 0                      // switch around for realy HIGH/LOW state
                  #define RELAY_OFF 1
                  
                  MySensor gw;
                  
                  #define RADIO_ID 11                    // Radio ID, whatever channel you assigned to
                  #define noRelays 6
                  const int relayPin[] = {A0, A1, A2, A3, A4, A5};
                  const int buttonPin[] = {3, 4, 5, 6, 7, 8};
                  
                  class Relay				// relay class, store all relevant data (equivalent to struct)
                  {
                  public:                             		 
                    int buttonPin;			// physical pin number of button
                    int relayPin;				// physical pin number of relay
                    byte oldValue;               		// last Values for key (debounce)
                    boolean relayState;             	// relay status (also stored in EEPROM)
                  };
                  
                  Relay Relays[noRelays];	
                  Bounce debouncer[noRelays];
                  MyMessage msg[noRelays];
                  
                  void setup(){
                  	gw.begin(incomingMessage, RADIO_ID, true);
                  	delay(250);
                  	gw.sendSketchInfo("MultiRelayButton", "0.9b");
                  	delay(250);
                  
                  	// Initialize Relays with corresponding buttons
                  	for (int i = 0; i < noRelays; i++){
                  	Relays[i].buttonPin = buttonPin[i];				             // assign physical pins
                  	Relays[i].relayPin = relayPin[i];
                  	msg[i].sensor = i;						             // initialize messages
                  	msg[i].type = V_LIGHT;
                  	debouncer[i] = Bounce();						     // initialize debouncer
                  	debouncer[i].attach(buttonPin[i]);
                  	debouncer[i].interval(5);
                  	pinMode(Relays[i].buttonPin, INPUT_PULLUP);
                  	pinMode(Relays[i].relayPin, OUTPUT);
                  	Relays[i].relayState = gw.loadState(i);			                      // retrieve last values from EEPROM
                  	digitalWrite(Relays[i].relayPin, Relays[i].relayState? RELAY_ON:RELAY_OFF);   // and set relays accordingly
                  	gw.send(msg[i].set(Relays[i].relayState? true : false));	              // make controller aware of last status
                  	gw.present(i, S_LIGHT);							      // present sensor to gateway
                  	delay(250);
                  
                  	}
                  }
                  
                  void loop()
                  	{
                  	gw.process();
                  	for (byte i = 0; i < noRelays; i++){
                  	debouncer[i].update();
                  	byte value = debouncer[i].read();
                  //	if (value != Relays[i].oldValue && value == 0){
                          if (value != Relays[i].oldValue){
                  	Relays[i].relayState = !Relays[i].relayState;
                  	digitalWrite(Relays[i].relayPin, Relays[i].relayState?RELAY_ON:RELAY_OFF);
                  	gw.send(msg[i].set(Relays[i].relayState? true : false));
                  	gw.saveState( i, Relays[i].relayState );}                 // save sensor state in EEPROM (location == sensor number)
                  	
                          Relays[i].oldValue = value;
                          
                  	}
                  }
                  
                  // process incoming message 
                  void incomingMessage(const MyMessage &message){
                           
                          if (message.type == V_LIGHT){ 
                          if (message.sensor <noRelays){ 	 // check if message is valid for relays..... previous line if [[[ (message.sensor <=noRelays){ ]]]
                          Relays[message.sensor].relayState = message.getBool(); 
                          digitalWrite(Relays[message.sensor].relayPin, Relays[message.sensor].relayState? RELAY_ON:RELAY_OFF); // and set relays accordingly
                          gw.saveState( message.sensor, Relays[message.sensor].relayState ); // save sensor state in EEPROM (location == sensor number)
                  		}
                  	}
                  }
                  
                  1 Reply Last reply
                  1
                  • N Offline
                    N Offline
                    niccodemi
                    wrote on last edited by
                    #29

                    @jeylites Thanks, toggle switch works but there is issue when node boots / restarts. On 1st restart relays stay OFF, on 2nd come ON, on 3rd again OFF and so on. It seems that whatever happens during Setup is reversed in Loop. Hopefully someone can point out what should be changed in modified sketch.

                    #define MY_RADIO_NRF24
                    
                    #define MY_REPEATER_FEATURE
                    
                    #include <MySensor.h>
                    #include <SPI.h>
                    #include <Bounce2.h>
                    #define RELAY_ON 0                      // switch around for realy HIGH/LOW state
                    #define RELAY_OFF 1
                    //
                    
                    #define noRelays 2                     //2-4
                    const int relayPin[] = {14,15};          //  switch around pins to your desire
                    const int buttonPin[] = {3,4};      //  switch around pins to your desire
                    
                    class Relay             // relay class, store all relevant data (equivalent to struct)
                    {
                    public:                                      
                      int buttonPin;                   // physical pin number of button
                      int relayPin;             // physical pin number of relay
                      byte oldValue;                    // last Values for key (debounce)
                      boolean relayState;               // relay status (also stored in EEPROM)
                    };
                    
                    Relay Relays[noRelays]; 
                    Bounce debouncer[noRelays];
                    MyMessage msg[noRelays];
                    
                    void setup(){
                        sendHeartbeat();
                        wait(250);
                        // Initialize Relays with corresponding buttons
                        for (int i = 0; i < noRelays; i++){
                        Relays[i].buttonPin = buttonPin[i];              // assign physical pins
                        Relays[i].relayPin = relayPin[i];
                        msg[i].sensor = i;                                   // initialize messages
                        msg[i].type = V_LIGHT;
                        debouncer[i] = Bounce();                        // initialize debouncer
                        debouncer[i].attach(buttonPin[i]);
                        debouncer[i].interval(5);
                        pinMode(Relays[i].buttonPin, INPUT_PULLUP);
                        //digitalWrite(Relays[i].relayPin, RELAY_OFF);
                        wait(250);
                        pinMode(Relays[i].relayPin, OUTPUT);
                        Relays[i].relayState = loadState(i);                               // retrieve last values from EEPROM
                        digitalWrite(Relays[i].relayPin, Relays[i].relayState? RELAY_ON:RELAY_OFF);   // and set relays accordingly
                        send(msg[i].set(Relays[i].relayState? true : false));                  // make controller aware of last status  
                        wait(250);
                        }
                    }
                    void presentation()  {
                          sendSketchInfo("MultiRelayButton", "0.9g");
                          wait(250);
                          for (int i = 0; i < noRelays; i++)
                          present(i, S_LIGHT);                               // present sensor to gateway
                    }
                    void loop()
                        {
                        for (byte i = 0; i < noRelays; i++){
                        debouncer[i].update();
                        byte value = debouncer[i].read();
                        if (value != Relays[i].oldValue){
                        Relays[i].relayState = !Relays[i].relayState;
                        digitalWrite(Relays[i].relayPin, Relays[i].relayState?RELAY_ON:RELAY_OFF);
                        send(msg[i].set(Relays[i].relayState? true : false));
                        saveState( i, Relays[i].relayState );}                 // save sensor state in EEPROM (location == sensor number)
                        
                            Relays[i].oldValue = value;      
                        }
                    }
                    // process incoming message 
                    void receive(const MyMessage &message){        
                       if (message.type == V_LIGHT){ 
                       if (message.sensor <noRelays){            // check if message is valid for relays..... previous line  [[[ if (message.sensor <=noRelays){ ]]]
                       Relays[message.sensor].relayState = message.getBool(); 
                       digitalWrite(Relays[message.sensor].relayPin, Relays[message.sensor].relayState? RELAY_ON:RELAY_OFF); // and set relays accordingly
                       saveState( message.sensor, Relays[message.sensor].relayState ); // save sensor state in EEPROM (location == sensor number)
                       }
                      }
                    }
                    

                    these are screenshots from restarts

                    reboot1

                    reboot2

                    martinhjelmareM 1 Reply Last reply
                    0
                    • N niccodemi

                      @jeylites Thanks, toggle switch works but there is issue when node boots / restarts. On 1st restart relays stay OFF, on 2nd come ON, on 3rd again OFF and so on. It seems that whatever happens during Setup is reversed in Loop. Hopefully someone can point out what should be changed in modified sketch.

                      #define MY_RADIO_NRF24
                      
                      #define MY_REPEATER_FEATURE
                      
                      #include <MySensor.h>
                      #include <SPI.h>
                      #include <Bounce2.h>
                      #define RELAY_ON 0                      // switch around for realy HIGH/LOW state
                      #define RELAY_OFF 1
                      //
                      
                      #define noRelays 2                     //2-4
                      const int relayPin[] = {14,15};          //  switch around pins to your desire
                      const int buttonPin[] = {3,4};      //  switch around pins to your desire
                      
                      class Relay             // relay class, store all relevant data (equivalent to struct)
                      {
                      public:                                      
                        int buttonPin;                   // physical pin number of button
                        int relayPin;             // physical pin number of relay
                        byte oldValue;                    // last Values for key (debounce)
                        boolean relayState;               // relay status (also stored in EEPROM)
                      };
                      
                      Relay Relays[noRelays]; 
                      Bounce debouncer[noRelays];
                      MyMessage msg[noRelays];
                      
                      void setup(){
                          sendHeartbeat();
                          wait(250);
                          // Initialize Relays with corresponding buttons
                          for (int i = 0; i < noRelays; i++){
                          Relays[i].buttonPin = buttonPin[i];              // assign physical pins
                          Relays[i].relayPin = relayPin[i];
                          msg[i].sensor = i;                                   // initialize messages
                          msg[i].type = V_LIGHT;
                          debouncer[i] = Bounce();                        // initialize debouncer
                          debouncer[i].attach(buttonPin[i]);
                          debouncer[i].interval(5);
                          pinMode(Relays[i].buttonPin, INPUT_PULLUP);
                          //digitalWrite(Relays[i].relayPin, RELAY_OFF);
                          wait(250);
                          pinMode(Relays[i].relayPin, OUTPUT);
                          Relays[i].relayState = loadState(i);                               // retrieve last values from EEPROM
                          digitalWrite(Relays[i].relayPin, Relays[i].relayState? RELAY_ON:RELAY_OFF);   // and set relays accordingly
                          send(msg[i].set(Relays[i].relayState? true : false));                  // make controller aware of last status  
                          wait(250);
                          }
                      }
                      void presentation()  {
                            sendSketchInfo("MultiRelayButton", "0.9g");
                            wait(250);
                            for (int i = 0; i < noRelays; i++)
                            present(i, S_LIGHT);                               // present sensor to gateway
                      }
                      void loop()
                          {
                          for (byte i = 0; i < noRelays; i++){
                          debouncer[i].update();
                          byte value = debouncer[i].read();
                          if (value != Relays[i].oldValue){
                          Relays[i].relayState = !Relays[i].relayState;
                          digitalWrite(Relays[i].relayPin, Relays[i].relayState?RELAY_ON:RELAY_OFF);
                          send(msg[i].set(Relays[i].relayState? true : false));
                          saveState( i, Relays[i].relayState );}                 // save sensor state in EEPROM (location == sensor number)
                          
                              Relays[i].oldValue = value;      
                          }
                      }
                      // process incoming message 
                      void receive(const MyMessage &message){        
                         if (message.type == V_LIGHT){ 
                         if (message.sensor <noRelays){            // check if message is valid for relays..... previous line  [[[ if (message.sensor <=noRelays){ ]]]
                         Relays[message.sensor].relayState = message.getBool(); 
                         digitalWrite(Relays[message.sensor].relayPin, Relays[message.sensor].relayState? RELAY_ON:RELAY_OFF); // and set relays accordingly
                         saveState( message.sensor, Relays[message.sensor].relayState ); // save sensor state in EEPROM (location == sensor number)
                         }
                        }
                      }
                      

                      these are screenshots from restarts

                      reboot1

                      reboot2

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

                      @niccodemi

                      Hi!

                      I think the problem is you're not initializing oldValue to anything. It will then always be different than value in the loop, and state will change.

                      You should set oldValue to the same "state" as the loaded relayState in setup. Even better, only use relayState, and make it an int. You can do the same boolean evaluations anyway. 1 is true and 0 is false.

                      Edit:
                      Sorry, I forgot that this is a pushbutton, right? Then you should just make sure that oldValue and value are the same after setup is complete, ie HIGH.

                      1 Reply Last reply
                      1
                      • N Offline
                        N Offline
                        niccodemi
                        wrote on last edited by
                        #31

                        @martinhjelmare

                        thanks, I understand what you mean but I don't know how to write it in sketch.

                        I tried inserting

                        Relays[i].oldValue = Relays[i].relayState;
                        

                        at the end of Void Setup section but then sketch wouldn't compile. I get "name lookup of 'i' changed 'for' ISO for scoping [-fpermissive]" error. I get same error if I substitute Relays[i].relayState with loadstate.

                        martinhjelmareM 1 Reply Last reply
                        0
                        • N niccodemi

                          @martinhjelmare

                          thanks, I understand what you mean but I don't know how to write it in sketch.

                          I tried inserting

                          Relays[i].oldValue = Relays[i].relayState;
                          

                          at the end of Void Setup section but then sketch wouldn't compile. I get "name lookup of 'i' changed 'for' ISO for scoping [-fpermissive]" error. I get same error if I substitute Relays[i].relayState with loadstate.

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

                          @niccodemi

                          Put this on a line after pinMode() in setup function.

                          Relays[i].oldValue = digitalRead(Relays[i].buttonPin);
                          
                          1 Reply Last reply
                          0
                          • N Offline
                            N Offline
                            niccodemi
                            wrote on last edited by
                            #33

                            @martinhjelmare

                            Ok, there is an improvement. Relays now turn to same state as they were before reboot most of the time but not always. Sometimes they inverse - the one which was OFF turns ON and vice-versa. Sometimes (1 in 3) they switch ON and OFF (only for split second) in the loop function. See below screenshots:

                            reboot3

                            reboot4

                            This sketch is used with toggle button, same as on this photo.

                            martinhjelmareM BartEB 2 Replies Last reply
                            0
                            • N niccodemi

                              @martinhjelmare

                              Ok, there is an improvement. Relays now turn to same state as they were before reboot most of the time but not always. Sometimes they inverse - the one which was OFF turns ON and vice-versa. Sometimes (1 in 3) they switch ON and OFF (only for split second) in the loop function. See below screenshots:

                              reboot3

                              reboot4

                              This sketch is used with toggle button, same as on this photo.

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

                              @niccodemi

                              Could be the toggle is still bouncing at read time. Try increasing the debouncer interval. For example, double it until no more issues. Then decrease it in halves of what the last increase was until you see the issue again. This way you can try to find the smallest debounce time needed.

                              1 Reply Last reply
                              0
                              • N niccodemi

                                @martinhjelmare

                                Ok, there is an improvement. Relays now turn to same state as they were before reboot most of the time but not always. Sometimes they inverse - the one which was OFF turns ON and vice-versa. Sometimes (1 in 3) they switch ON and OFF (only for split second) in the loop function. See below screenshots:

                                reboot3

                                reboot4

                                This sketch is used with toggle button, same as on this photo.

                                BartEB Offline
                                BartEB Offline
                                BartE
                                Contest Winner
                                wrote on last edited by BartE
                                #35

                                @niccodemi You can forget using the oldValue, because the debounce takes track of it's last status. When update() is called and a debounced pin-change is detect this function will return true otherwise it will send false.
                                Having a short delay each loop will stabilize the debouncers so your loop() can look like this:

                                void loop()
                                {
                                    for (byte i = 0; i < noRelays; i++) {
                                        if (debouncer[i].update()) {
                                            Relays[i].relayState = !Relays[i].relayState;
                                            digitalWrite(Relays[i].relayPin, Relays[i].relayState?RELAY_ON:RELAY_OFF);
                                            send(msg[i].set(Relays[i].relayState? true : false));
                                            // save sensor state in EEPROM (location == sensor number)
                                            saveState( i, Relays[i].relayState );
                                        }                 
                                    }
                                    wait(10);
                                }
                                
                                martinhjelmareM 1 Reply Last reply
                                1
                                • BartEB BartE

                                  @niccodemi You can forget using the oldValue, because the debounce takes track of it's last status. When update() is called and a debounced pin-change is detect this function will return true otherwise it will send false.
                                  Having a short delay each loop will stabilize the debouncers so your loop() can look like this:

                                  void loop()
                                  {
                                      for (byte i = 0; i < noRelays; i++) {
                                          if (debouncer[i].update()) {
                                              Relays[i].relayState = !Relays[i].relayState;
                                              digitalWrite(Relays[i].relayPin, Relays[i].relayState?RELAY_ON:RELAY_OFF);
                                              send(msg[i].set(Relays[i].relayState? true : false));
                                              // save sensor state in EEPROM (location == sensor number)
                                              saveState( i, Relays[i].relayState );
                                          }                 
                                      }
                                      wait(10);
                                  }
                                  
                                  martinhjelmareM Offline
                                  martinhjelmareM Offline
                                  martinhjelmare
                                  Plugin Developer
                                  wrote on last edited by martinhjelmare
                                  #36

                                  @BartE

                                  Why do you think it's better to add the wait than to increase debounce interval? Didn't know update returns a boolean, cool.

                                  BartEB 1 Reply Last reply
                                  0
                                  • martinhjelmareM martinhjelmare

                                    @BartE

                                    Why do you think it's better to add the wait than to increase debounce interval? Didn't know update returns a boolean, cool.

                                    BartEB Offline
                                    BartEB Offline
                                    BartE
                                    Contest Winner
                                    wrote on last edited by BartE
                                    #37

                                    @martinhjelmare there is no reason to have that many button checks per millisecond, if you "wait" each while loop the MySensors core has more time to process messages i.s.o. of reading I/O pins especially when your node acts as a repeater. (During a wait the process function is called)
                                    A person will not notices a button to take 50 i.s.o 10 milliseconds to respond.

                                    martinhjelmareM 1 Reply Last reply
                                    1
                                    • BartEB BartE

                                      @martinhjelmare there is no reason to have that many button checks per millisecond, if you "wait" each while loop the MySensors core has more time to process messages i.s.o. of reading I/O pins especially when your node acts as a repeater. (During a wait the process function is called)
                                      A person will not notices a button to take 50 i.s.o 10 milliseconds to respond.

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

                                      @BartE

                                      Yes, very good point.

                                      1 Reply Last reply
                                      0
                                      • N Offline
                                        N Offline
                                        niccodemi
                                        wrote on last edited by
                                        #39

                                        @martinhjelmare @BartE thank you both for trying to solve this issue but the problem is still there. On reboot relay (usually just 1 never both) gets set randomly in loop function (setup function always restores correct state). I also tried increasing debouncer up to 500 without success. And I am also sure this is not hardware related because if I load sketch which is meant for momentary switch relays work as expected (tested with 10 consecutive reboots). Just to be on the same page this is latest sketch:

                                        //MultiRelayButton Sketch, MySensors 1.6
                                        
                                        #define MY_RADIO_NRF24
                                        
                                        #define MY_REPEATER_FEATURE
                                        
                                        #include <MySensor.h>
                                        #include <SPI.h>
                                        #include <Bounce2.h>
                                        #define RELAY_ON 0                      // switch around for realy HIGH/LOW state
                                        #define RELAY_OFF 1
                                        //
                                        
                                        #define noRelays 2                     //2-4
                                        const int relayPin[] = {14,15};          //  switch around pins to your desire
                                        const int buttonPin[] = {3,4};      //  switch around pins to your desire
                                        
                                        class Relay             // relay class, store all relevant data (equivalent to struct)
                                        {
                                        public:                                      
                                          int buttonPin;                   // physical pin number of button
                                          int relayPin;             // physical pin number of relay
                                          //byte oldValue;                    // last Values for key (debounce)
                                          boolean relayState;               // relay status (also stored in EEPROM)
                                        };
                                        
                                        Relay Relays[noRelays]; 
                                        Bounce debouncer[noRelays];
                                        MyMessage msg[noRelays];
                                        
                                        void setup(){
                                            sendHeartbeat();
                                            wait(250);
                                            // Initialize Relays with corresponding buttons
                                            for (int i = 0; i < noRelays; i++){
                                            Relays[i].buttonPin = buttonPin[i];              // assign physical pins
                                            Relays[i].relayPin = relayPin[i];
                                            msg[i].sensor = i;                                   // initialize messages
                                            msg[i].type = V_LIGHT;
                                            debouncer[i] = Bounce();                        // initialize debouncer
                                            debouncer[i].attach(buttonPin[i]);
                                            debouncer[i].interval(100);
                                            pinMode(Relays[i].buttonPin, INPUT_PULLUP);
                                            wait(250);
                                            pinMode(Relays[i].relayPin, OUTPUT);
                                            //Relays[i].oldValue = digitalRead(Relays[i].buttonPin);
                                            Relays[i].relayState = loadState(i);                               // retrieve last values from EEPROM
                                            digitalWrite(Relays[i].relayPin, Relays[i].relayState? RELAY_ON:RELAY_OFF);   // and set relays accordingly
                                            send(msg[i].set(Relays[i].relayState? true : false));                  // make controller aware of last status  
                                            wait(250);
                                            }
                                        }
                                        void presentation()  {
                                              sendSketchInfo("MultiRelayButton", "0.9k");
                                              wait(250);
                                              for (int i = 0; i < noRelays; i++)
                                              present(i, S_LIGHT);                               // present sensor to gateway
                                              wait(250);
                                        }
                                        void loop()
                                        {
                                            for (byte i = 0; i < noRelays; i++) {
                                                if (debouncer[i].update()) {
                                                    Relays[i].relayState = !Relays[i].relayState;
                                                    digitalWrite(Relays[i].relayPin, Relays[i].relayState?RELAY_ON:RELAY_OFF);
                                                    send(msg[i].set(Relays[i].relayState? true : false));
                                                    // save sensor state in EEPROM (location == sensor number)
                                                    saveState( i, Relays[i].relayState );
                                                }                 
                                            }
                                            wait(50);
                                        }
                                        // process incoming message 
                                        void receive(const MyMessage &message){        
                                           if (message.type == V_LIGHT){ 
                                           if (message.sensor <noRelays){            // check if message is valid for relays..... previous line  [[[ if (message.sensor <=noRelays){ ]]]
                                           Relays[message.sensor].relayState = message.getBool(); 
                                           digitalWrite(Relays[message.sensor].relayPin, Relays[message.sensor].relayState? RELAY_ON:RELAY_OFF); // and set relays accordingly
                                           saveState( message.sensor, Relays[message.sensor].relayState ); // save sensor state in EEPROM (location == sensor number)
                                           }
                                          }
                                          wait(50);
                                        }
                                        
                                        martinhjelmareM 1 Reply Last reply
                                        0
                                        • N niccodemi

                                          @martinhjelmare @BartE thank you both for trying to solve this issue but the problem is still there. On reboot relay (usually just 1 never both) gets set randomly in loop function (setup function always restores correct state). I also tried increasing debouncer up to 500 without success. And I am also sure this is not hardware related because if I load sketch which is meant for momentary switch relays work as expected (tested with 10 consecutive reboots). Just to be on the same page this is latest sketch:

                                          //MultiRelayButton Sketch, MySensors 1.6
                                          
                                          #define MY_RADIO_NRF24
                                          
                                          #define MY_REPEATER_FEATURE
                                          
                                          #include <MySensor.h>
                                          #include <SPI.h>
                                          #include <Bounce2.h>
                                          #define RELAY_ON 0                      // switch around for realy HIGH/LOW state
                                          #define RELAY_OFF 1
                                          //
                                          
                                          #define noRelays 2                     //2-4
                                          const int relayPin[] = {14,15};          //  switch around pins to your desire
                                          const int buttonPin[] = {3,4};      //  switch around pins to your desire
                                          
                                          class Relay             // relay class, store all relevant data (equivalent to struct)
                                          {
                                          public:                                      
                                            int buttonPin;                   // physical pin number of button
                                            int relayPin;             // physical pin number of relay
                                            //byte oldValue;                    // last Values for key (debounce)
                                            boolean relayState;               // relay status (also stored in EEPROM)
                                          };
                                          
                                          Relay Relays[noRelays]; 
                                          Bounce debouncer[noRelays];
                                          MyMessage msg[noRelays];
                                          
                                          void setup(){
                                              sendHeartbeat();
                                              wait(250);
                                              // Initialize Relays with corresponding buttons
                                              for (int i = 0; i < noRelays; i++){
                                              Relays[i].buttonPin = buttonPin[i];              // assign physical pins
                                              Relays[i].relayPin = relayPin[i];
                                              msg[i].sensor = i;                                   // initialize messages
                                              msg[i].type = V_LIGHT;
                                              debouncer[i] = Bounce();                        // initialize debouncer
                                              debouncer[i].attach(buttonPin[i]);
                                              debouncer[i].interval(100);
                                              pinMode(Relays[i].buttonPin, INPUT_PULLUP);
                                              wait(250);
                                              pinMode(Relays[i].relayPin, OUTPUT);
                                              //Relays[i].oldValue = digitalRead(Relays[i].buttonPin);
                                              Relays[i].relayState = loadState(i);                               // retrieve last values from EEPROM
                                              digitalWrite(Relays[i].relayPin, Relays[i].relayState? RELAY_ON:RELAY_OFF);   // and set relays accordingly
                                              send(msg[i].set(Relays[i].relayState? true : false));                  // make controller aware of last status  
                                              wait(250);
                                              }
                                          }
                                          void presentation()  {
                                                sendSketchInfo("MultiRelayButton", "0.9k");
                                                wait(250);
                                                for (int i = 0; i < noRelays; i++)
                                                present(i, S_LIGHT);                               // present sensor to gateway
                                                wait(250);
                                          }
                                          void loop()
                                          {
                                              for (byte i = 0; i < noRelays; i++) {
                                                  if (debouncer[i].update()) {
                                                      Relays[i].relayState = !Relays[i].relayState;
                                                      digitalWrite(Relays[i].relayPin, Relays[i].relayState?RELAY_ON:RELAY_OFF);
                                                      send(msg[i].set(Relays[i].relayState? true : false));
                                                      // save sensor state in EEPROM (location == sensor number)
                                                      saveState( i, Relays[i].relayState );
                                                  }                 
                                              }
                                              wait(50);
                                          }
                                          // process incoming message 
                                          void receive(const MyMessage &message){        
                                             if (message.type == V_LIGHT){ 
                                             if (message.sensor <noRelays){            // check if message is valid for relays..... previous line  [[[ if (message.sensor <=noRelays){ ]]]
                                             Relays[message.sensor].relayState = message.getBool(); 
                                             digitalWrite(Relays[message.sensor].relayPin, Relays[message.sensor].relayState? RELAY_ON:RELAY_OFF); // and set relays accordingly
                                             saveState( message.sensor, Relays[message.sensor].relayState ); // save sensor state in EEPROM (location == sensor number)
                                             }
                                            }
                                            wait(50);
                                          }
                                          
                                          martinhjelmareM Offline
                                          martinhjelmareM Offline
                                          martinhjelmare
                                          Plugin Developer
                                          wrote on last edited by martinhjelmare
                                          #40

                                          @niccodemi

                                          I think you should setup the button first, pinMode etc, and then setup the debouncer and attach it to the button.

                                          https://github.com/thomasfredericks/Bounce2/wiki

                                          If you attach the debouncer while the pin is floating, the debouncer will probably have a hard time figuring out correct new state.

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


                                          15

                                          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