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.
  • jeylitesJ jeylites

    @AWI

    ... This is insane and it works :joy: :smiley: How do you change between HIGH/LOW state. I changed the #define settings but it's not taking effect.

    jeylitesJ Offline
    jeylitesJ Offline
    jeylites
    wrote on last edited by
    #11

    @AWI

    This is the awkward part. On the Vera App & Web, I'm able to toggle ON / OFF to the respective state of the Relay. Eg: "ON" on Vera energize the Relay and "OFF" de-energine the relay. But, when I use the actuator buttons on Arduino input , its reversed. "OFF" turns ON the Relay ...vice versa.

    AWIA 1 Reply Last reply
    0
    • jeylitesJ jeylites

      @AWI

      This is the awkward part. On the Vera App & Web, I'm able to toggle ON / OFF to the respective state of the Relay. Eg: "ON" on Vera energize the Relay and "OFF" de-energine the relay. But, when I use the actuator buttons on Arduino input , its reversed. "OFF" turns ON the Relay ...vice versa.

      AWIA Offline
      AWIA Offline
      AWI
      Hero Member
      wrote on last edited by AWI
      #12

      @jeylites I understand your Relays are active low. You have to be consequent in terminology like: on/off; true/false; RELAY_ON/RELAY_OFF. From a first glance I think you should be fine if you change the line:

      digitalWrite(Relays[i].relayPin, Relays[i].relayState);
      

      to

      digitalWrite(Relays[i].relayPin, Relays[i].relayState?RELAY_ON:RELAY_OFF);
      

      as things get mixed up here. i.e RELAY_ON is in fact "false" or "0"

      jeylitesJ 1 Reply Last reply
      0
      • AWIA AWI

        @jeylites I understand your Relays are active low. You have to be consequent in terminology like: on/off; true/false; RELAY_ON/RELAY_OFF. From a first glance I think you should be fine if you change the line:

        digitalWrite(Relays[i].relayPin, Relays[i].relayState);
        

        to

        digitalWrite(Relays[i].relayPin, Relays[i].relayState?RELAY_ON:RELAY_OFF);
        

        as things get mixed up here. i.e RELAY_ON is in fact "false" or "0"

        jeylitesJ Offline
        jeylitesJ Offline
        jeylites
        wrote on last edited by jeylites
        #13

        @AWI

        I revised the sketch based on your advice and seem to be working as we speak. I tried to make the final sketch as organized as possible, It has be copied below. Thank you everyone for making this work!!!

        
        #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 2
        const int relayPin[] = {3,7};          //  switch around pins to your desire
        const int buttonPin[] = {4,5};      //  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(){
        	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){
        	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)
        		}
        	}
        }
        
        
        M 1 Reply Last reply
        1
        • jeylitesJ jeylites

          @AWI

          I revised the sketch based on your advice and seem to be working as we speak. I tried to make the final sketch as organized as possible, It has be copied below. Thank you everyone for making this work!!!

          
          #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 2
          const int relayPin[] = {3,7};          //  switch around pins to your desire
          const int buttonPin[] = {4,5};      //  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(){
          	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){
          	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)
          		}
          	}
          }
          
          
          M Offline
          M Offline
          mikemayers
          wrote on last edited by
          #14

          @jeylites

          Just tested this sketch and it works. Thank for the effort.

          M 1 Reply Last reply
          0
          • M mikemayers

            @jeylites

            Just tested this sketch and it works. Thank for the effort.

            M Offline
            M Offline
            maglo18
            wrote on last edited by
            #15

            Could someone tell what i should to modify to use toggle button not flash button?

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

              @maglo18 what do you mean?

              1 Reply Last reply
              0
              • M Offline
                M Offline
                maglo18
                wrote on last edited by
                #17

                In yours sketch state button should high next low then relay change state. I want to have possibility after button HIGH relay state change button LOW state relay change again

                1 Reply Last reply
                0
                • J Offline
                  J Offline
                  jemish
                  wrote on last edited by
                  #18

                  yes , I have same problem.

                  how can we use simple wall switch with relay to ON and OFF the lights.

                  1 Reply Last reply
                  0
                  • AWIA Offline
                    AWIA Offline
                    AWI
                    Hero Member
                    wrote on last edited by
                    #19

                    For learning purposes: Instead of coding it for you, try the line of thought:

                    Now it changes with the toggle, so if "value" (switch) becomes high is changes the state of the relays, send the message to controller and stores it in EEPROM.

                    If you use a normal switch, you should change the state if when the "value" changes. So remember the last state of the switch and make it happen ;-)

                    btw :you need a variable to store the last button state and the physical position of the switch does not change if you update the relay switch from the controller..

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

                      Just wondering any of you guys made progress in normal switch?

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


                                          12

                                          Online

                                          11.7k

                                          Users

                                          11.2k

                                          Topics

                                          113.1k

                                          Posts


                                          Copyright 2025 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • MySensors
                                          • OpenHardware.io
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular