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. Hardware
  3. Multi Button Relay switch

Multi Button Relay switch

Scheduled Pinned Locked Moved Hardware
43 Posts 13 Posters 25.5k Views 8 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.
  • T Terence Faul

    hek

    Do you have an example sketch, I am a newby and would not have any idea how to alter the sketch to include buttons and move the relay pins

    BulldogLowellB Offline
    BulldogLowellB Offline
    BulldogLowell
    Contest Winner
    wrote on last edited by BulldogLowell
    #5

    @Terence-Faul said:

    Do you have an example sketch, I am a newby and would not have any idea how to alter the sketch to include buttons and move the relay pins

    try this (untested but compiles)

    #include <MySensor.h>
    #include <SPI.h>
    #include <Bounce2.h>
    //
    MySensor gw;
    const int relayPin[] = {7, 8, A0, A1};
    const int buttonPin[sizeof(relayPin) / sizeof(relayPin[0])] = {3, 4, 5, 6};
    byte oldValue[sizeof(relayPin) / sizeof(relayPin[0])];
    boolean relayState[sizeof(relayPin) / sizeof(relayPin[0])];
    
    Bounce debouncer[sizeof(relayPin) / sizeof(relayPin[0])];
    
    MyMessage msg[sizeof(relayPin) / sizeof(relayPin[0])];//(sensor,type);
    
    void setup()  
    {  
      Serial.begin(115200);
      gw.begin(incomingMessage, AUTO, false);
      for (int i = 0; i < sizeof(relayPin) / sizeof(relayPin[0]); i++)
      {
        msg[i].sensor = i;
        msg[i].type = V_LIGHT;
        debouncer[i] = Bounce();
        debouncer[i].attach(buttonPin[i]);
        debouncer[i].interval(5);
        pinMode(buttonPin[i], INPUT_PULLUP);
        digitalWrite(relayPin[i], LOW);
        pinMode(relayPin[i], OUTPUT);
        gw.present(relayPin[i], S_LIGHT);
        delay(250);
      }
      //retreive from EEPROM last states
      for (int i = 0; i < sizeof(relayPin) / sizeof(relayPin[0]); i++)
      {
        relayState[i] = gw.loadState(i);
        digitalWrite(relayPin[i], relayState[i]? HIGH : LOW);
        gw.send(msg[i].set(relayState[i]? true : false), true);
        delay(250);
      }
    }
    //
    void loop() 
    {
      gw.process();
      for (byte i = 0; i < sizeof(relayPin) / sizeof(relayPin[0]); i++)
      {
        debouncer[i].update();
        byte value = debouncer[i].read();
        if (value != oldValue[i] && value == 0)
        {
          relayState[i] = !relayState[i];
          digitalWrite(relayPin[i], relayState[i]);
          gw.send(msg[i].set(relayState[i]? true : false), true);
        }
        oldValue[i] = value;
      }
    }
    //
    void incomingMessage(const MyMessage &message)
    {
      if (message.isAck()) 
      {
        Serial.println(F("This is an ack from gateway"));
      }
      for (byte i = 0; i< sizeof(relayPin) / sizeof(relayPin[0]); i++)
      {
        if (message.sensor == i)
        {
          if (message.type == V_LIGHT)
          {
            relayState[i] = message.getBool();
            digitalWrite(relayPin[i], relayState[i]); 
            gw.saveState(relayPin[i], relayState[i]);
          }
        }
      }
    }
    
    1 Reply Last reply
    0
    • gigiG Offline
      gigiG Offline
      gigi
      wrote on last edited by
      #6

      there is no problem to put 4 relays.
      you just feed a separate power!!!

      Vera lite - mysensors Ethernet gateway - AirWik sensor - Relay Module

      1 Reply Last reply
      0
      • T Offline
        T Offline
        Terence Faul
        wrote on last edited by
        #7
          // Example sketch för a "light switch" where you can control light or something 
          // else from both vera and a local physical button (connected between digital
          // pin 3 and GND).
          // This node also works as a repeader for other nodes
          
          #include <MySensor.h>
          #include <SPI.h>
          #include <Bounce2.h>
          
          #define RELAY_PIN  4  // Arduino Digital I/O pin number for relay 
          #define BUTTON_PIN  3  // Arduino Digital I/O pin number for button 
          #define CHILD_ID 1   // Id of the sensor child
          #define RELAY_ON 1
          #define RELAY_OFF 0
          
          Bounce debouncer = Bounce(); 
          int oldValue=0;
          bool state;
          MySensor gw;
          MyMessage msg(CHILD_ID,V_LIGHT);
          
          void setup()  
          {  
            gw.begin(incomingMessage, AUTO, true);
          
            // Send the sketch version information to the gateway and Controller
            gw.sendSketchInfo("Relay & Button", "1.0");
          
           // Setup the button
            pinMode(BUTTON_PIN,INPUT);
            // Activate internal pull-up
            digitalWrite(BUTTON_PIN,HIGH);
            
            // After setting up the button, setup debouncer
            debouncer.attach(BUTTON_PIN);
            debouncer.interval(5);
          
            // Register all sensors to gw (they will be created as child devices)
            gw.present(CHILD_ID, S_LIGHT);
          
            // Make sure relays are off when starting up
            digitalWrite(RELAY_PIN, RELAY_OFF);
            // Then set relay pins in output mode
            pinMode(RELAY_PIN, OUTPUT);   
                
            // Set relay to last known state (using eeprom storage) 
            state = gw.loadState(CHILD_ID);
            digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF);
          }
          
          
          /*
          *  Example on how to asynchronously check for new messages from gw
          */
          void loop() 
          {
            gw.process();
            debouncer.update();
            // Get the update value
            int value = debouncer.read();
            if (value != oldValue && value==0) {
                gw.send(msg.set(state?false:true), true); // Send new state and request ack back
            }
            oldValue = value;
          } 
           
          void incomingMessage(const MyMessage &message) {
            // We only expect one type of message from controller. But we better check anyway.
            if (message.isAck()) {
               Serial.println("This is an ack from gateway");
            }
          
            if (message.type == V_LIGHT) {
               // Change relay state
               state = message.getBool();
               digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF);
               // Store state in eeprom
               gw.saveState(CHILD_ID, state);
              
               // Write some debug info
               Serial.print("Incoming change for sensor:");
               Serial.print(message.sensor);
               Serial.print(", New status: ");
               Serial.println(message.getBool());
             } 
          }
        
        
        BulldogLowellB 2 Replies Last reply
        0
        • T Terence Faul
            // Example sketch för a "light switch" where you can control light or something 
            // else from both vera and a local physical button (connected between digital
            // pin 3 and GND).
            // This node also works as a repeader for other nodes
            
            #include <MySensor.h>
            #include <SPI.h>
            #include <Bounce2.h>
            
            #define RELAY_PIN  4  // Arduino Digital I/O pin number for relay 
            #define BUTTON_PIN  3  // Arduino Digital I/O pin number for button 
            #define CHILD_ID 1   // Id of the sensor child
            #define RELAY_ON 1
            #define RELAY_OFF 0
            
            Bounce debouncer = Bounce(); 
            int oldValue=0;
            bool state;
            MySensor gw;
            MyMessage msg(CHILD_ID,V_LIGHT);
            
            void setup()  
            {  
              gw.begin(incomingMessage, AUTO, true);
            
              // Send the sketch version information to the gateway and Controller
              gw.sendSketchInfo("Relay & Button", "1.0");
            
             // Setup the button
              pinMode(BUTTON_PIN,INPUT);
              // Activate internal pull-up
              digitalWrite(BUTTON_PIN,HIGH);
              
              // After setting up the button, setup debouncer
              debouncer.attach(BUTTON_PIN);
              debouncer.interval(5);
            
              // Register all sensors to gw (they will be created as child devices)
              gw.present(CHILD_ID, S_LIGHT);
            
              // Make sure relays are off when starting up
              digitalWrite(RELAY_PIN, RELAY_OFF);
              // Then set relay pins in output mode
              pinMode(RELAY_PIN, OUTPUT);   
                  
              // Set relay to last known state (using eeprom storage) 
              state = gw.loadState(CHILD_ID);
              digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF);
            }
            
            
            /*
            *  Example on how to asynchronously check for new messages from gw
            */
            void loop() 
            {
              gw.process();
              debouncer.update();
              // Get the update value
              int value = debouncer.read();
              if (value != oldValue && value==0) {
                  gw.send(msg.set(state?false:true), true); // Send new state and request ack back
              }
              oldValue = value;
            } 
             
            void incomingMessage(const MyMessage &message) {
              // We only expect one type of message from controller. But we better check anyway.
              if (message.isAck()) {
                 Serial.println("This is an ack from gateway");
              }
            
              if (message.type == V_LIGHT) {
                 // Change relay state
                 state = message.getBool();
                 digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF);
                 // Store state in eeprom
                 gw.saveState(CHILD_ID, state);
                
                 // Write some debug info
                 Serial.print("Incoming change for sensor:");
                 Serial.print(message.sensor);
                 Serial.print(", New status: ");
                 Serial.println(message.getBool());
               } 
            }
          
          
          BulldogLowellB Offline
          BulldogLowellB Offline
          BulldogLowell
          Contest Winner
          wrote on last edited by BulldogLowell
          #8

          @Terence-Faul said:

          gw.sendSketchInfo("Relay & Button", "1.0");

          yeah, a mistake or two ;)

          #include <MySensor.h>
          #include <SPI.h>
          #include <Bounce2.h>
          //
          MySensor gw;
          const int relayPin[] = {7, 8, A0, A1};
          const int buttonPin[sizeof(relayPin) / sizeof(relayPin[0])] = {3, 4, 5, 6};
          byte oldValue[sizeof(relayPin) / sizeof(relayPin[0])];
          boolean relayState[sizeof(relayPin) / sizeof(relayPin[0])];
          
          Bounce debouncer[sizeof(relayPin) / sizeof(relayPin[0])];
          
          MyMessage msg[sizeof(relayPin) / sizeof(relayPin[0])];//(sensor,type);
          
          void setup()  
          {  
            Serial.begin(115200);
            gw.begin(incomingMessage, AUTO, false);
            //
            // or you can try:
            // gw.begin(incomingMessage, <Your_Node_ID>, false); // where Your_Node_ID is a number from 1 to 254
            //
            delay(250);
            gw.sendSketchInfo("MultiRelayButton", "0.9b");// <<<<<<<<<<<<<<<<<<< I forgot this, here
            //
            delay(250);
            for (int i = 0; i < sizeof(relayPin) / sizeof(relayPin[0]); i++)
            {
              msg[i].sensor = i;
              msg[i].type = V_LIGHT;
              debouncer[i] = Bounce();
              debouncer[i].attach(buttonPin[i]);
              debouncer[i].interval(5);
              pinMode(buttonPin[i], INPUT_PULLUP);
              digitalWrite(relayPin[i], LOW);
              pinMode(relayPin[i], OUTPUT);
              gw.present(i, S_LIGHT); // <<<<<<<<<<<<<<<<<<<<<<< I fixed this too...
              delay(250);
            }
            //retreive from EEPROM last states
            for (int i = 0; i < sizeof(relayPin) / sizeof(relayPin[0]); i++)
            {
              relayState[i] = gw.loadState(i);
              digitalWrite(relayPin[i], relayState[i]? HIGH : LOW);
              gw.send(msg[i].set(relayState[i]? true : false), true);
              delay(250);
            }
          }
          //
          void loop() 
          {
            gw.process();
            for (byte i = 0; i < sizeof(relayPin) / sizeof(relayPin[0]); i++)
            {
              debouncer[i].update();
              byte value = debouncer[i].read();
              if (value != oldValue[i] && value == 0)
              {
                relayState[i] = !relayState[i];
                digitalWrite(relayPin[i], relayState[i]);
                gw.send(msg[i].set(relayState[i]? true : false), true);
              }
              oldValue[i] = value;
            }
          }
          //
          void incomingMessage(const MyMessage &message)
          {
            if (message.isAck()) 
            {
              Serial.println(F("This is an ack from gateway"));
            }
            for (byte i = 0; i< sizeof(relayPin) / sizeof(relayPin[0]); i++)
            {
              if (message.sensor == i)
              {
                if (message.type == V_LIGHT)
                {
                  relayState[i] = message.getBool();
                  digitalWrite(relayPin[i], relayState[i]); 
                  gw.saveState(relayPin[i], relayState[i]);
                }
              }
            }
          }
          

          try and see if it fixes your issues :)

          1 Reply Last reply
          0
          • T Terence Faul
              // Example sketch för a "light switch" where you can control light or something 
              // else from both vera and a local physical button (connected between digital
              // pin 3 and GND).
              // This node also works as a repeader for other nodes
              
              #include <MySensor.h>
              #include <SPI.h>
              #include <Bounce2.h>
              
              #define RELAY_PIN  4  // Arduino Digital I/O pin number for relay 
              #define BUTTON_PIN  3  // Arduino Digital I/O pin number for button 
              #define CHILD_ID 1   // Id of the sensor child
              #define RELAY_ON 1
              #define RELAY_OFF 0
              
              Bounce debouncer = Bounce(); 
              int oldValue=0;
              bool state;
              MySensor gw;
              MyMessage msg(CHILD_ID,V_LIGHT);
              
              void setup()  
              {  
                gw.begin(incomingMessage, AUTO, true);
              
                // Send the sketch version information to the gateway and Controller
                gw.sendSketchInfo("Relay & Button", "1.0");
              
               // Setup the button
                pinMode(BUTTON_PIN,INPUT);
                // Activate internal pull-up
                digitalWrite(BUTTON_PIN,HIGH);
                
                // After setting up the button, setup debouncer
                debouncer.attach(BUTTON_PIN);
                debouncer.interval(5);
              
                // Register all sensors to gw (they will be created as child devices)
                gw.present(CHILD_ID, S_LIGHT);
              
                // Make sure relays are off when starting up
                digitalWrite(RELAY_PIN, RELAY_OFF);
                // Then set relay pins in output mode
                pinMode(RELAY_PIN, OUTPUT);   
                    
                // Set relay to last known state (using eeprom storage) 
                state = gw.loadState(CHILD_ID);
                digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF);
              }
              
              
              /*
              *  Example on how to asynchronously check for new messages from gw
              */
              void loop() 
              {
                gw.process();
                debouncer.update();
                // Get the update value
                int value = debouncer.read();
                if (value != oldValue && value==0) {
                    gw.send(msg.set(state?false:true), true); // Send new state and request ack back
                }
                oldValue = value;
              } 
               
              void incomingMessage(const MyMessage &message) {
                // We only expect one type of message from controller. But we better check anyway.
                if (message.isAck()) {
                   Serial.println("This is an ack from gateway");
                }
              
                if (message.type == V_LIGHT) {
                   // Change relay state
                   state = message.getBool();
                   digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF);
                   // Store state in eeprom
                   gw.saveState(CHILD_ID, state);
                  
                   // Write some debug info
                   Serial.print("Incoming change for sensor:");
                   Serial.print(message.sensor);
                   Serial.print(", New status: ");
                   Serial.println(message.getBool());
                 } 
              }
            
            
            BulldogLowellB Offline
            BulldogLowellB Offline
            BulldogLowell
            Contest Winner
            wrote on last edited by BulldogLowell
            #9

            @Terence-Faul

            #include <MySensor.h>
            #include <SPI.h>
            #include <Bounce2.h>
            //
            #define RELAY_ON 1
            #define RELAY_OFF 0
              
            MySensor gw;
            const int relayPin[] = {7, 8, A0, A1};
            const int buttonPin[sizeof(relayPin) / sizeof(relayPin[0])] = {3, 4, 5, 6};
            byte oldValue[sizeof(relayPin) / sizeof(relayPin[0])];
            boolean relayState[sizeof(relayPin) / sizeof(relayPin[0])];
            
            Bounce debouncer[sizeof(relayPin) / sizeof(relayPin[0])];
            
            MyMessage msg[sizeof(relayPin) / sizeof(relayPin[0])];//(sensor,type);
            
            void setup()  
            {  
              Serial.begin(115200);
              gw.begin(incomingMessage, AUTO, false);
              //
              // or you can try:
              // gw.begin(incomingMessage, <Your_Node_ID>, false); // where Your_Node_ID is a number from 1 to 254
              //
              delay(250);
              gw.sendSketchInfo("MultiRelayButton", "0.9b");
              //
              delay(250);
              for (int i = 0; i < sizeof(relayPin) / sizeof(relayPin[0]); i++)
              {
                msg[i].sensor = i;
                msg[i].type = V_LIGHT;
                debouncer[i] = Bounce();
                debouncer[i].attach(buttonPin[i]);
                debouncer[i].interval(5);
                pinMode(buttonPin[i], INPUT_PULLUP);
                digitalWrite(relayPin[i], LOW);
                pinMode(relayPin[i], OUTPUT);
                gw.present(i, S_LIGHT); 
                delay(250);
              }
              //retreive from EEPROM last states
              for (int i = 0; i < sizeof(relayPin) / sizeof(relayPin[0]); i++)
              {
                relayState[i] = gw.loadState(i);
                digitalWrite(relayPin[i], relayState[i]? RELAY_ON : RELAY_OFF);
                //gw.send(msg[i].set(relayState[i]? RELAY_ON : RELAY_OFF), true);
                delay(250);
              }
            }
            //
            void loop() 
            {
              gw.process();
              for (byte i = 0; i < sizeof(relayPin) / sizeof(relayPin[0]); i++)
              {
                debouncer[i].update();
                byte value = debouncer[i].read();
                if (value != oldValue[i] && value == 0)
                {
                  relayState[i] = !relayState[i];
                  //digitalWrite(relayPin[i], relayState[i]);
                  gw.send(msg[i].set(relayState[i]? false : true), true);
                }
                oldValue[i] = value;
              }
            }
            //
            void incomingMessage(const MyMessage &message)
            {
              if (message.isAck()) 
              {
                Serial.println(F("This is an ack from gateway"));
              }
              for (byte i = 0; i< sizeof(relayPin) / sizeof(relayPin[0]); i++)
              {
                if (message.sensor == i)
                {
                  if (message.type == V_LIGHT)
                  {
                    relayState[i] = message.getBool();
                    digitalWrite(relayPin[i], relayState[i]? RELAY_ON : RELAY_OFF); 
                    gw.saveState(relayPin[i], relayState[i]);
                  }
                }
              }
            }
            
            T 1 Reply Last reply
            0
            • BulldogLowellB BulldogLowell

              @Terence-Faul

              #include <MySensor.h>
              #include <SPI.h>
              #include <Bounce2.h>
              //
              #define RELAY_ON 1
              #define RELAY_OFF 0
                
              MySensor gw;
              const int relayPin[] = {7, 8, A0, A1};
              const int buttonPin[sizeof(relayPin) / sizeof(relayPin[0])] = {3, 4, 5, 6};
              byte oldValue[sizeof(relayPin) / sizeof(relayPin[0])];
              boolean relayState[sizeof(relayPin) / sizeof(relayPin[0])];
              
              Bounce debouncer[sizeof(relayPin) / sizeof(relayPin[0])];
              
              MyMessage msg[sizeof(relayPin) / sizeof(relayPin[0])];//(sensor,type);
              
              void setup()  
              {  
                Serial.begin(115200);
                gw.begin(incomingMessage, AUTO, false);
                //
                // or you can try:
                // gw.begin(incomingMessage, <Your_Node_ID>, false); // where Your_Node_ID is a number from 1 to 254
                //
                delay(250);
                gw.sendSketchInfo("MultiRelayButton", "0.9b");
                //
                delay(250);
                for (int i = 0; i < sizeof(relayPin) / sizeof(relayPin[0]); i++)
                {
                  msg[i].sensor = i;
                  msg[i].type = V_LIGHT;
                  debouncer[i] = Bounce();
                  debouncer[i].attach(buttonPin[i]);
                  debouncer[i].interval(5);
                  pinMode(buttonPin[i], INPUT_PULLUP);
                  digitalWrite(relayPin[i], LOW);
                  pinMode(relayPin[i], OUTPUT);
                  gw.present(i, S_LIGHT); 
                  delay(250);
                }
                //retreive from EEPROM last states
                for (int i = 0; i < sizeof(relayPin) / sizeof(relayPin[0]); i++)
                {
                  relayState[i] = gw.loadState(i);
                  digitalWrite(relayPin[i], relayState[i]? RELAY_ON : RELAY_OFF);
                  //gw.send(msg[i].set(relayState[i]? RELAY_ON : RELAY_OFF), true);
                  delay(250);
                }
              }
              //
              void loop() 
              {
                gw.process();
                for (byte i = 0; i < sizeof(relayPin) / sizeof(relayPin[0]); i++)
                {
                  debouncer[i].update();
                  byte value = debouncer[i].read();
                  if (value != oldValue[i] && value == 0)
                  {
                    relayState[i] = !relayState[i];
                    //digitalWrite(relayPin[i], relayState[i]);
                    gw.send(msg[i].set(relayState[i]? false : true), true);
                  }
                  oldValue[i] = value;
                }
              }
              //
              void incomingMessage(const MyMessage &message)
              {
                if (message.isAck()) 
                {
                  Serial.println(F("This is an ack from gateway"));
                }
                for (byte i = 0; i< sizeof(relayPin) / sizeof(relayPin[0]); i++)
                {
                  if (message.sensor == i)
                  {
                    if (message.type == V_LIGHT)
                    {
                      relayState[i] = message.getBool();
                      digitalWrite(relayPin[i], relayState[i]? RELAY_ON : RELAY_OFF); 
                      gw.saveState(relayPin[i], relayState[i]);
                    }
                  }
                }
              }
              
              T Offline
              T Offline
              Terence Faul
              wrote on last edited by Terence Faul
              #10

              @BulldogLowell

              This new one had the relays correct, but the buttons did not work. I compared the old with the new and below now works.

              Thanks again a million for all the help

              #include <MySensor.h>
              #include <SPI.h>
              #include <Bounce2.h>
              
              #define RELAY_ON 0
              #define RELAY_OFF 1
              
              //
              MySensor gw;
              const int relayPin[] = {7, 8, A0, A1};
              const int buttonPin[sizeof(relayPin) / sizeof(relayPin[0])] = {3, 4, 5, 6};
              byte oldValue[sizeof(relayPin) / sizeof(relayPin[0])];
              boolean relayState[sizeof(relayPin) / sizeof(relayPin[0])];
              
              Bounce debouncer[sizeof(relayPin) / sizeof(relayPin[0])];
              
              MyMessage msg[sizeof(relayPin) / sizeof(relayPin[0])];//(sensor,type);
              
              void setup()  
              {  
                Serial.begin(115200);
                gw.begin(incomingMessage, AUTO, false);
                //
                // or you can try:
                // gw.begin(incomingMessage, <Your_Node_ID>, false); // where Your_Node_ID is a number from 1 to 254
                //
                delay(250);
                gw.sendSketchInfo("MultiRelayButton", "0.9b");// <<<<<<<<<<<<<<<<<<< I forgot this, here
                //
                delay(250);
                for (int i = 0; i < sizeof(relayPin) / sizeof(relayPin[0]); i++)
                {
                  msg[i].sensor = i;
                  msg[i].type = V_LIGHT;
                  debouncer[i] = Bounce();
                  debouncer[i].attach(buttonPin[i]);
                  debouncer[i].interval(5);
                  pinMode(buttonPin[i], INPUT_PULLUP);
                  digitalWrite(relayPin[i], LOW);
                  pinMode(relayPin[i], OUTPUT);
                  gw.present(i, S_LIGHT); // <<<<<<<<<<<<<<<<<<<<<<< I fixed this too...
                  delay(250);
                }
                //retreive from EEPROM last states
                for (int i = 0; i < sizeof(relayPin) / sizeof(relayPin[0]); i++)
                {
                  relayState[i] = gw.loadState(i);
                  digitalWrite(relayPin[i], relayState[i]? RELAY_ON : RELAY_OFF);
                  gw.send(msg[i].set(relayState[i]? true : false), true);
                  delay(250);
                }
              }
              //
              void loop() 
              {
                gw.process();
                for (byte i = 0; i < sizeof(relayPin) / sizeof(relayPin[0]); i++)
                {
                  debouncer[i].update();
                  byte value = debouncer[i].read();
                  if (value != oldValue[i] && value == 0)
                  {
                    relayState[i] = !relayState[i];
                    digitalWrite(relayPin[i], relayState[i]);
                    gw.send(msg[i].set(relayState[i]? true : false), true);
                  }
                  oldValue[i] = value;
                }
              }
              //
              void incomingMessage(const MyMessage &message)
              {
                if (message.isAck()) 
                {
                  Serial.println(F("This is an ack from gateway"));
                }
                for (byte i = 0; i< sizeof(relayPin) / sizeof(relayPin[0]); i++)
                {
                  if (message.sensor == i)
                  {
                    if (message.type == V_LIGHT)
                    {
                      relayState[i] = message.getBool();
                      digitalWrite(relayPin[i], relayState[i]? RELAY_ON : RELAY_OFF); 
                      gw.saveState(relayPin[i], relayState[i]);
                    }
                  }
                }
              }
              
              T 1 Reply Last reply
              1
              • T Terence Faul

                @BulldogLowell

                This new one had the relays correct, but the buttons did not work. I compared the old with the new and below now works.

                Thanks again a million for all the help

                #include <MySensor.h>
                #include <SPI.h>
                #include <Bounce2.h>
                
                #define RELAY_ON 0
                #define RELAY_OFF 1
                
                //
                MySensor gw;
                const int relayPin[] = {7, 8, A0, A1};
                const int buttonPin[sizeof(relayPin) / sizeof(relayPin[0])] = {3, 4, 5, 6};
                byte oldValue[sizeof(relayPin) / sizeof(relayPin[0])];
                boolean relayState[sizeof(relayPin) / sizeof(relayPin[0])];
                
                Bounce debouncer[sizeof(relayPin) / sizeof(relayPin[0])];
                
                MyMessage msg[sizeof(relayPin) / sizeof(relayPin[0])];//(sensor,type);
                
                void setup()  
                {  
                  Serial.begin(115200);
                  gw.begin(incomingMessage, AUTO, false);
                  //
                  // or you can try:
                  // gw.begin(incomingMessage, <Your_Node_ID>, false); // where Your_Node_ID is a number from 1 to 254
                  //
                  delay(250);
                  gw.sendSketchInfo("MultiRelayButton", "0.9b");// <<<<<<<<<<<<<<<<<<< I forgot this, here
                  //
                  delay(250);
                  for (int i = 0; i < sizeof(relayPin) / sizeof(relayPin[0]); i++)
                  {
                    msg[i].sensor = i;
                    msg[i].type = V_LIGHT;
                    debouncer[i] = Bounce();
                    debouncer[i].attach(buttonPin[i]);
                    debouncer[i].interval(5);
                    pinMode(buttonPin[i], INPUT_PULLUP);
                    digitalWrite(relayPin[i], LOW);
                    pinMode(relayPin[i], OUTPUT);
                    gw.present(i, S_LIGHT); // <<<<<<<<<<<<<<<<<<<<<<< I fixed this too...
                    delay(250);
                  }
                  //retreive from EEPROM last states
                  for (int i = 0; i < sizeof(relayPin) / sizeof(relayPin[0]); i++)
                  {
                    relayState[i] = gw.loadState(i);
                    digitalWrite(relayPin[i], relayState[i]? RELAY_ON : RELAY_OFF);
                    gw.send(msg[i].set(relayState[i]? true : false), true);
                    delay(250);
                  }
                }
                //
                void loop() 
                {
                  gw.process();
                  for (byte i = 0; i < sizeof(relayPin) / sizeof(relayPin[0]); i++)
                  {
                    debouncer[i].update();
                    byte value = debouncer[i].read();
                    if (value != oldValue[i] && value == 0)
                    {
                      relayState[i] = !relayState[i];
                      digitalWrite(relayPin[i], relayState[i]);
                      gw.send(msg[i].set(relayState[i]? true : false), true);
                    }
                    oldValue[i] = value;
                  }
                }
                //
                void incomingMessage(const MyMessage &message)
                {
                  if (message.isAck()) 
                  {
                    Serial.println(F("This is an ack from gateway"));
                  }
                  for (byte i = 0; i< sizeof(relayPin) / sizeof(relayPin[0]); i++)
                  {
                    if (message.sensor == i)
                    {
                      if (message.type == V_LIGHT)
                      {
                        relayState[i] = message.getBool();
                        digitalWrite(relayPin[i], relayState[i]? RELAY_ON : RELAY_OFF); 
                        gw.saveState(relayPin[i], relayState[i]);
                      }
                    }
                  }
                }
                
                T Offline
                T Offline
                Terence Faul
                wrote on last edited by Terence Faul
                #11

                @Terence-Faul
                Only one other thing.

                I notice that when the sensor starts up, each of the relays turn on and then off.

                This ia all good and well, however i assume in practice this would mean what ever is connected to them will turn on and off as well in the initialisation phase.

                Also I assume that retrieve from EEPROM means that if the sensor loses power while a relay is on, when it powers up this relay will return to the on state?

                Can you point me to to code that controls this, if these are lights and the power goes out a better option may be to have the relays all start in the off position so that the lights do not come on in the middle of the night

                Is this correct?

                1 Reply Last reply
                1
                • T Offline
                  T Offline
                  Terence Faul
                  wrote on last edited by
                  #12

                  Bulldog

                  So this is as far as I got.

                  Managed to get the relays to start in the off position by Changing LOW for the defined RELAY_OFF.

                  Commented out the EEPROM Section and now when the sensor reboots is starts with all relays in off position.

                  I do not know how to change the EEPROM section I am sur I need to maybe include the RELAY_OFF somewhere in that line.

                  #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;
                  const int relayPin[] = {7, 8, A0, A1};
                  const int buttonPin[sizeof(relayPin) / sizeof(relayPin[0])] = {3, 4, 5, 6};
                  byte oldValue[sizeof(relayPin) / sizeof(relayPin[0])];
                  boolean relayState[sizeof(relayPin) / sizeof(relayPin[0])];
                  
                  Bounce debouncer[sizeof(relayPin) / sizeof(relayPin[0])];
                  
                  MyMessage msg[sizeof(relayPin) / sizeof(relayPin[0])];//(sensor,type);
                  
                  void setup()  
                  {  
                    Serial.begin(115200);
                    gw.begin(incomingMessage, AUTO, false);
                    //
                    // or you can try:
                    // gw.begin(incomingMessage, <Your_Node_ID>, false); // where Your_Node_ID is a number from 1 to 254
                    //
                    delay(250);
                    gw.sendSketchInfo("MultiRelayButton", "0.9b");// <<<<<<<<<<<<<<<<<<< I forgot this, here
                    //
                    delay(250);
                    for (int i = 0; i < sizeof(relayPin) / sizeof(relayPin[0]); i++)
                    {
                      msg[i].sensor = i;
                      msg[i].type = V_LIGHT;
                      debouncer[i] = Bounce();
                      debouncer[i].attach(buttonPin[i]);
                      debouncer[i].interval(5);
                      pinMode(buttonPin[i], INPUT_PULLUP);
                      digitalWrite(relayPin[i], RELAY_OFF); //Start State of Relays
                      pinMode(relayPin[i], OUTPUT);
                      gw.present(i, S_LIGHT); // <<<<<<<<<<<<<<<<<<<<<<< I fixed this too...
                      delay(250);
                    }
                    //retreive from EEPROM last states
                  //  for (int i = 0; i < sizeof(relayPin) / sizeof(relayPin[0]); i++)//>>>>>>> I'm sure that this is causing all relays to turn on and off at startup
                  //  {
                  //    relayState[i] = gw.loadState(i);
                  //    digitalWrite(relayPin[i], relayState[i]? RELAY_ON:RELAY_OFF);
                  //    gw.send(msg[i].set(relayState[i]? true : false), true);
                  //    delay(250);
                  //  }
                  //  
                  }
                  //
                  void loop() 
                  {
                    gw.process();
                    for (byte i = 0; i < sizeof(relayPin) / sizeof(relayPin[0]); i++)
                    {
                      debouncer[i].update();
                      byte value = debouncer[i].read();
                      if (value != oldValue[i] && value == 0)
                      {
                        relayState[i] = !relayState[i];
                        digitalWrite(relayPin[i], relayState[i]);
                        gw.send(msg[i].set(relayState[i]? true : false), true);
                      }
                      oldValue[i] = value;
                    }
                  }
                  //
                  void incomingMessage(const MyMessage &message)
                  {
                    if (message.isAck()) 
                    {
                      Serial.println(F("This is an ack from gateway"));
                    }
                    for (byte i = 0; i< sizeof(relayPin) / sizeof(relayPin[0]); i++)
                    {
                      if (message.sensor == i)
                      {
                        if (message.type == V_LIGHT)
                        {
                          relayState[i] = message.getBool();
                          digitalWrite(relayPin[i], relayState[i]? RELAY_ON : RELAY_OFF); 
                          gw.saveState(relayPin[i], relayState[i]);
                        }
                      }
                    }
                  }
                  
                  BulldogLowellB 1 Reply Last reply
                  0
                  • T Terence Faul

                    Bulldog

                    So this is as far as I got.

                    Managed to get the relays to start in the off position by Changing LOW for the defined RELAY_OFF.

                    Commented out the EEPROM Section and now when the sensor reboots is starts with all relays in off position.

                    I do not know how to change the EEPROM section I am sur I need to maybe include the RELAY_OFF somewhere in that line.

                    #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;
                    const int relayPin[] = {7, 8, A0, A1};
                    const int buttonPin[sizeof(relayPin) / sizeof(relayPin[0])] = {3, 4, 5, 6};
                    byte oldValue[sizeof(relayPin) / sizeof(relayPin[0])];
                    boolean relayState[sizeof(relayPin) / sizeof(relayPin[0])];
                    
                    Bounce debouncer[sizeof(relayPin) / sizeof(relayPin[0])];
                    
                    MyMessage msg[sizeof(relayPin) / sizeof(relayPin[0])];//(sensor,type);
                    
                    void setup()  
                    {  
                      Serial.begin(115200);
                      gw.begin(incomingMessage, AUTO, false);
                      //
                      // or you can try:
                      // gw.begin(incomingMessage, <Your_Node_ID>, false); // where Your_Node_ID is a number from 1 to 254
                      //
                      delay(250);
                      gw.sendSketchInfo("MultiRelayButton", "0.9b");// <<<<<<<<<<<<<<<<<<< I forgot this, here
                      //
                      delay(250);
                      for (int i = 0; i < sizeof(relayPin) / sizeof(relayPin[0]); i++)
                      {
                        msg[i].sensor = i;
                        msg[i].type = V_LIGHT;
                        debouncer[i] = Bounce();
                        debouncer[i].attach(buttonPin[i]);
                        debouncer[i].interval(5);
                        pinMode(buttonPin[i], INPUT_PULLUP);
                        digitalWrite(relayPin[i], RELAY_OFF); //Start State of Relays
                        pinMode(relayPin[i], OUTPUT);
                        gw.present(i, S_LIGHT); // <<<<<<<<<<<<<<<<<<<<<<< I fixed this too...
                        delay(250);
                      }
                      //retreive from EEPROM last states
                    //  for (int i = 0; i < sizeof(relayPin) / sizeof(relayPin[0]); i++)//>>>>>>> I'm sure that this is causing all relays to turn on and off at startup
                    //  {
                    //    relayState[i] = gw.loadState(i);
                    //    digitalWrite(relayPin[i], relayState[i]? RELAY_ON:RELAY_OFF);
                    //    gw.send(msg[i].set(relayState[i]? true : false), true);
                    //    delay(250);
                    //  }
                    //  
                    }
                    //
                    void loop() 
                    {
                      gw.process();
                      for (byte i = 0; i < sizeof(relayPin) / sizeof(relayPin[0]); i++)
                      {
                        debouncer[i].update();
                        byte value = debouncer[i].read();
                        if (value != oldValue[i] && value == 0)
                        {
                          relayState[i] = !relayState[i];
                          digitalWrite(relayPin[i], relayState[i]);
                          gw.send(msg[i].set(relayState[i]? true : false), true);
                        }
                        oldValue[i] = value;
                      }
                    }
                    //
                    void incomingMessage(const MyMessage &message)
                    {
                      if (message.isAck()) 
                      {
                        Serial.println(F("This is an ack from gateway"));
                      }
                      for (byte i = 0; i< sizeof(relayPin) / sizeof(relayPin[0]); i++)
                      {
                        if (message.sensor == i)
                        {
                          if (message.type == V_LIGHT)
                          {
                            relayState[i] = message.getBool();
                            digitalWrite(relayPin[i], relayState[i]? RELAY_ON : RELAY_OFF); 
                            gw.saveState(relayPin[i], relayState[i]);
                          }
                        }
                      }
                    }
                    
                    BulldogLowellB Offline
                    BulldogLowellB Offline
                    BulldogLowell
                    Contest Winner
                    wrote on last edited by
                    #13

                    @Terence-Faul said:

                    gw.saveState(relayPin[i], relayState[i]);

                    if you are not relying on settings saved to EEPROM to recover its state after a power cycle, you can also comment our or remove this line:

                    gw.saveState(relayPin[i], relayState[i]);
                    

                    it saves the state of the relay each time it gets changed.

                    glad to see you are learning and have it working just the way you like.

                    1 Reply Last reply
                    0
                    • T Offline
                      T Offline
                      Terence Faul
                      wrote on last edited by
                      #14

                      Thanks a stack, it is slow.

                      If I did want to restore the relay state how would I change the code?

                      At the moment if I leave that code in when the arduino boots it cycles each relay on and then off, instead of just restoring the previous state

                      1 Reply Last reply
                      0
                      • A Offline
                        A Offline
                        Anthony Straw
                        wrote on last edited by
                        #15

                        go for SSR instead of hk mechical relay it will stop working after 10,000 clicked ... cheap brand

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

                          I got the same question as @Terence-Faul, How to change the code to have the Relay to restore its previous state. I tried a couple of things but can't seem to get it to work. Thanks @BulldogLowell for the script !

                          1 Reply Last reply
                          0
                          • BulldogLowellB Offline
                            BulldogLowellB Offline
                            BulldogLowell
                            Contest Winner
                            wrote on last edited by
                            #17

                            @jeylites ,

                            so, try to look over the example just above the one that worked for @Terence-Faul

                            It included saving states to EEPROM and retrieving them in setup( ).

                            1 Reply Last reply
                            0
                            • C Offline
                              C Offline
                              C.r.a.z.y.
                              wrote on last edited by
                              #18

                              How do you seperate relay power?

                              What is your solution to drop 220v AC to 5v DC?

                              jeylitesJ 1 Reply Last reply
                              0
                              • C C.r.a.z.y.

                                How do you seperate relay power?

                                What is your solution to drop 220v AC to 5v DC?

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

                                @C.r.a.z.y. You could get a USB power adapter... see Ebay link below. On my current setup, I'm using a 2.1A+1A Dual USB 2-Ports. I use the the 1A port for the Arduino and the 2.1A port for the relays. On the relay board, you have VCC, IN1 & GND. IN1 gets connected to the Arduino, VCC to the second power supply or power port. The GND is shared between both power ports. Hope that helps!

                                http://www.ebay.com/sch/i.html?_from=R40&_trksid=p2141725.m570.l1313.TR12.TRC2.A0.H0.XUSB+Wall+Charger+.TRS0&_nkw=USB+Wall+Charger+&ghostText=&_sacat=0

                                jeylitesJ 1 Reply Last reply
                                0
                                • jeylitesJ jeylites

                                  @C.r.a.z.y. You could get a USB power adapter... see Ebay link below. On my current setup, I'm using a 2.1A+1A Dual USB 2-Ports. I use the the 1A port for the Arduino and the 2.1A port for the relays. On the relay board, you have VCC, IN1 & GND. IN1 gets connected to the Arduino, VCC to the second power supply or power port. The GND is shared between both power ports. Hope that helps!

                                  http://www.ebay.com/sch/i.html?_from=R40&_trksid=p2141725.m570.l1313.TR12.TRC2.A0.H0.XUSB+Wall+Charger+.TRS0&_nkw=USB+Wall+Charger+&ghostText=&_sacat=0

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

                                  @BulldogLowell

                                  I have gone through the script like 8 times with no luck at all. Are you suggesting the mistake in in the EEPROM retrieval section ?

                                  #include <MySensor.h>
                                  #include <SPI.h>
                                  #include <Bounce2.h>
                                  
                                  #define RELAY_ON 1 //switch around for realy HIGH/LOW state
                                  #define RELAY_OFF 0
                                  
                                  //
                                  MySensor gw;
                                  const int relayPin[] = {7, 8, A0, A1};
                                  const int buttonPin[sizeof(relayPin) / sizeof(relayPin[0])] = {3, 4, 5, 6};
                                  byte oldValue[sizeof(relayPin) / sizeof(relayPin[0])];
                                  boolean relayState[sizeof(relayPin) / sizeof(relayPin[0])];
                                  
                                  Bounce debouncer[sizeof(relayPin) / sizeof(relayPin[0])];
                                  
                                  MyMessage msg[sizeof(relayPin) / sizeof(relayPin[0])];//(sensor,type);
                                  
                                  void setup()
                                  {
                                  Serial.begin(115200);
                                  gw.begin(incomingMessage, AUTO, true);
                                  //
                                  // or you can try:
                                  // gw.begin(incomingMessage, <Your_Node_ID>, false); // where Your_Node_ID is a number from 1 to 254
                                  //
                                  delay(250);
                                  gw.sendSketchInfo("MultiRelayButton", "0.9b");
                                  
                                  delay(250);
                                  for (int i = 0; i < sizeof(relayPin) / sizeof(relayPin[0]); i++)
                                  {
                                  msg[i].sensor = i;
                                  msg[i].type = V_LIGHT;
                                  debouncer[i] = Bounce();
                                  debouncer[i].attach(buttonPin[i]);
                                  debouncer[i].interval(5);
                                  pinMode(buttonPin[i], INPUT_PULLUP);
                                  digitalWrite(relayPin[i], RELAY_OFF); //Start State of Relays
                                  pinMode(relayPin[i], OUTPUT);
                                  gw.present(i, S_LIGHT);
                                  delay(250);
                                  }
                                  //retreive from EEPROM last states
                                  for (int i = 0; i < sizeof(relayPin) / sizeof(relayPin[0]); i++)//>>>>>>> I'm sure that this is causing all relays to turn on and off at startup
                                  {
                                  relayState[i] = gw.loadState(i);
                                  digitalWrite(relayPin[i], relayState[i]? RELAY_ON:RELAY_OFF);
                                  //gw.send(msg[i].set(relayState[i]? true : false), true);
                                  delay(250);
                                  }
                                  
                                  }
                                  
                                  void loop()
                                  {
                                  gw.process();
                                  for (byte i = 0; i < sizeof(relayPin) / sizeof(relayPin[0]); i++)
                                  {
                                  debouncer[i].update();
                                  byte value = debouncer[i].read();
                                  if (value != oldValue[i] && value == 0)
                                  {
                                  relayState[i] = !relayState[i];
                                  digitalWrite(relayPin[i], relayState[i]);
                                  gw.send(msg[i].set(relayState[i]? true : false), true);
                                  }
                                  oldValue[i] = value;
                                  }
                                  }
                                  //
                                  void incomingMessage(const MyMessage &message)
                                  {
                                  if (message.isAck())
                                  {
                                  Serial.println(F("This is an ack from gateway"));
                                  }
                                  for (byte i = 0; i< sizeof(relayPin) / sizeof(relayPin[0]); i++)
                                  {
                                  if (message.sensor == i)
                                  {
                                  if (message.type == V_LIGHT)
                                  {
                                  relayState[i] = message.getBool();
                                  digitalWrite(relayPin[i], relayState[i]? RELAY_ON : RELAY_OFF);
                                  gw.saveState(relayPin[i], relayState[i]);
                                  }
                                  }
                                  }
                                  }```
                                  
                                  
                                  
                                  
                                  
                                  #include <MySensor.h>
                                  #include <SPI.h>
                                  #include <Bounce2.h>
                                  
                                  #define RELAY_ON 1  //switch around for realy HIGH/LOW state
                                  #define RELAY_OFF 0
                                  
                                  //
                                  MySensor gw;
                                  const int relayPin[] = {7, 8, A0, A1};
                                  const int buttonPin[sizeof(relayPin) / sizeof(relayPin[0])] = {3, 4, 5, 6};
                                  byte oldValue[sizeof(relayPin) / sizeof(relayPin[0])];
                                  boolean relayState[sizeof(relayPin) / sizeof(relayPin[0])];
                                  
                                  Bounce debouncer[sizeof(relayPin) / sizeof(relayPin[0])];
                                  
                                  MyMessage msg[sizeof(relayPin) / sizeof(relayPin[0])];//(sensor,type);
                                  
                                  void setup()  
                                  {  
                                    Serial.begin(115200);
                                    gw.begin(incomingMessage, AUTO, true);
                                    //
                                    // or you can try:
                                    // gw.begin(incomingMessage, <Your_Node_ID>, false); // where Your_Node_ID is a number from 1 to 254
                                    //
                                    delay(250);
                                    gw.sendSketchInfo("MultiRelayButton", "0.9b");
                                    
                                    delay(250);
                                    for (int i = 0; i < sizeof(relayPin) / sizeof(relayPin[0]); i++)
                                    {
                                      msg[i].sensor = i;
                                      msg[i].type = V_LIGHT;
                                      debouncer[i] = Bounce();
                                      debouncer[i].attach(buttonPin[i]);
                                      debouncer[i].interval(5);
                                      pinMode(buttonPin[i], INPUT_PULLUP);
                                      digitalWrite(relayPin[i], RELAY_OFF); //Start State of Relays
                                      pinMode(relayPin[i], OUTPUT);
                                      gw.present(i, S_LIGHT);
                                      delay(250);
                                    }
                                    //retreive from EEPROM last states
                                    for (int i = 0; i < sizeof(relayPin) / sizeof(relayPin[0]); i++)//>>>>>>> I'm sure that this is causing all relays to turn on and off at startup
                                    {
                                      relayState[i] = gw.loadState(i);
                                      digitalWrite(relayPin[i], relayState[i]? RELAY_ON:RELAY_OFF);
                                      //gw.send(msg[i].set(relayState[i]? true : false), true);
                                      delay(250);
                                    }
                                    
                                  }
                                  
                                  void loop() 
                                  {
                                    gw.process();
                                    for (byte i = 0; i < sizeof(relayPin) / sizeof(relayPin[0]); i++)
                                    {
                                      debouncer[i].update();
                                      byte value = debouncer[i].read();
                                      if (value != oldValue[i] && value == 0)
                                      {
                                        relayState[i] = !relayState[i];
                                        digitalWrite(relayPin[i], relayState[i]);
                                        gw.send(msg[i].set(relayState[i]? true : false), true);
                                      }
                                      oldValue[i] = value;
                                    }
                                  }
                                  //
                                  void incomingMessage(const MyMessage &message)
                                  {
                                    if (message.isAck()) 
                                    {
                                      Serial.println(F("This is an ack from gateway"));
                                    }
                                    for (byte i = 0; i< sizeof(relayPin) / sizeof(relayPin[0]); i++)
                                    {
                                      if (message.sensor == i)
                                      {
                                        if (message.type == V_LIGHT)
                                        {
                                          relayState[i] = message.getBool();
                                          digitalWrite(relayPin[i], relayState[i]? RELAY_ON : RELAY_OFF); 
                                          gw.saveState(relayPin[i], relayState[i]);
                                        }
                                      }
                                    }
                                  }
                                  AWIA 1 Reply Last reply
                                  0
                                  • jeylitesJ jeylites

                                    @BulldogLowell

                                    I have gone through the script like 8 times with no luck at all. Are you suggesting the mistake in in the EEPROM retrieval section ?

                                    #include <MySensor.h>
                                    #include <SPI.h>
                                    #include <Bounce2.h>
                                    
                                    #define RELAY_ON 1 //switch around for realy HIGH/LOW state
                                    #define RELAY_OFF 0
                                    
                                    //
                                    MySensor gw;
                                    const int relayPin[] = {7, 8, A0, A1};
                                    const int buttonPin[sizeof(relayPin) / sizeof(relayPin[0])] = {3, 4, 5, 6};
                                    byte oldValue[sizeof(relayPin) / sizeof(relayPin[0])];
                                    boolean relayState[sizeof(relayPin) / sizeof(relayPin[0])];
                                    
                                    Bounce debouncer[sizeof(relayPin) / sizeof(relayPin[0])];
                                    
                                    MyMessage msg[sizeof(relayPin) / sizeof(relayPin[0])];//(sensor,type);
                                    
                                    void setup()
                                    {
                                    Serial.begin(115200);
                                    gw.begin(incomingMessage, AUTO, true);
                                    //
                                    // or you can try:
                                    // gw.begin(incomingMessage, <Your_Node_ID>, false); // where Your_Node_ID is a number from 1 to 254
                                    //
                                    delay(250);
                                    gw.sendSketchInfo("MultiRelayButton", "0.9b");
                                    
                                    delay(250);
                                    for (int i = 0; i < sizeof(relayPin) / sizeof(relayPin[0]); i++)
                                    {
                                    msg[i].sensor = i;
                                    msg[i].type = V_LIGHT;
                                    debouncer[i] = Bounce();
                                    debouncer[i].attach(buttonPin[i]);
                                    debouncer[i].interval(5);
                                    pinMode(buttonPin[i], INPUT_PULLUP);
                                    digitalWrite(relayPin[i], RELAY_OFF); //Start State of Relays
                                    pinMode(relayPin[i], OUTPUT);
                                    gw.present(i, S_LIGHT);
                                    delay(250);
                                    }
                                    //retreive from EEPROM last states
                                    for (int i = 0; i < sizeof(relayPin) / sizeof(relayPin[0]); i++)//>>>>>>> I'm sure that this is causing all relays to turn on and off at startup
                                    {
                                    relayState[i] = gw.loadState(i);
                                    digitalWrite(relayPin[i], relayState[i]? RELAY_ON:RELAY_OFF);
                                    //gw.send(msg[i].set(relayState[i]? true : false), true);
                                    delay(250);
                                    }
                                    
                                    }
                                    
                                    void loop()
                                    {
                                    gw.process();
                                    for (byte i = 0; i < sizeof(relayPin) / sizeof(relayPin[0]); i++)
                                    {
                                    debouncer[i].update();
                                    byte value = debouncer[i].read();
                                    if (value != oldValue[i] && value == 0)
                                    {
                                    relayState[i] = !relayState[i];
                                    digitalWrite(relayPin[i], relayState[i]);
                                    gw.send(msg[i].set(relayState[i]? true : false), true);
                                    }
                                    oldValue[i] = value;
                                    }
                                    }
                                    //
                                    void incomingMessage(const MyMessage &message)
                                    {
                                    if (message.isAck())
                                    {
                                    Serial.println(F("This is an ack from gateway"));
                                    }
                                    for (byte i = 0; i< sizeof(relayPin) / sizeof(relayPin[0]); i++)
                                    {
                                    if (message.sensor == i)
                                    {
                                    if (message.type == V_LIGHT)
                                    {
                                    relayState[i] = message.getBool();
                                    digitalWrite(relayPin[i], relayState[i]? RELAY_ON : RELAY_OFF);
                                    gw.saveState(relayPin[i], relayState[i]);
                                    }
                                    }
                                    }
                                    }```
                                    
                                    
                                    
                                    
                                    
                                    #include <MySensor.h>
                                    #include <SPI.h>
                                    #include <Bounce2.h>
                                    
                                    #define RELAY_ON 1  //switch around for realy HIGH/LOW state
                                    #define RELAY_OFF 0
                                    
                                    //
                                    MySensor gw;
                                    const int relayPin[] = {7, 8, A0, A1};
                                    const int buttonPin[sizeof(relayPin) / sizeof(relayPin[0])] = {3, 4, 5, 6};
                                    byte oldValue[sizeof(relayPin) / sizeof(relayPin[0])];
                                    boolean relayState[sizeof(relayPin) / sizeof(relayPin[0])];
                                    
                                    Bounce debouncer[sizeof(relayPin) / sizeof(relayPin[0])];
                                    
                                    MyMessage msg[sizeof(relayPin) / sizeof(relayPin[0])];//(sensor,type);
                                    
                                    void setup()  
                                    {  
                                      Serial.begin(115200);
                                      gw.begin(incomingMessage, AUTO, true);
                                      //
                                      // or you can try:
                                      // gw.begin(incomingMessage, <Your_Node_ID>, false); // where Your_Node_ID is a number from 1 to 254
                                      //
                                      delay(250);
                                      gw.sendSketchInfo("MultiRelayButton", "0.9b");
                                      
                                      delay(250);
                                      for (int i = 0; i < sizeof(relayPin) / sizeof(relayPin[0]); i++)
                                      {
                                        msg[i].sensor = i;
                                        msg[i].type = V_LIGHT;
                                        debouncer[i] = Bounce();
                                        debouncer[i].attach(buttonPin[i]);
                                        debouncer[i].interval(5);
                                        pinMode(buttonPin[i], INPUT_PULLUP);
                                        digitalWrite(relayPin[i], RELAY_OFF); //Start State of Relays
                                        pinMode(relayPin[i], OUTPUT);
                                        gw.present(i, S_LIGHT);
                                        delay(250);
                                      }
                                      //retreive from EEPROM last states
                                      for (int i = 0; i < sizeof(relayPin) / sizeof(relayPin[0]); i++)//>>>>>>> I'm sure that this is causing all relays to turn on and off at startup
                                      {
                                        relayState[i] = gw.loadState(i);
                                        digitalWrite(relayPin[i], relayState[i]? RELAY_ON:RELAY_OFF);
                                        //gw.send(msg[i].set(relayState[i]? true : false), true);
                                        delay(250);
                                      }
                                      
                                    }
                                    
                                    void loop() 
                                    {
                                      gw.process();
                                      for (byte i = 0; i < sizeof(relayPin) / sizeof(relayPin[0]); i++)
                                      {
                                        debouncer[i].update();
                                        byte value = debouncer[i].read();
                                        if (value != oldValue[i] && value == 0)
                                        {
                                          relayState[i] = !relayState[i];
                                          digitalWrite(relayPin[i], relayState[i]);
                                          gw.send(msg[i].set(relayState[i]? true : false), true);
                                        }
                                        oldValue[i] = value;
                                      }
                                    }
                                    //
                                    void incomingMessage(const MyMessage &message)
                                    {
                                      if (message.isAck()) 
                                      {
                                        Serial.println(F("This is an ack from gateway"));
                                      }
                                      for (byte i = 0; i< sizeof(relayPin) / sizeof(relayPin[0]); i++)
                                      {
                                        if (message.sensor == i)
                                        {
                                          if (message.type == V_LIGHT)
                                          {
                                            relayState[i] = message.getBool();
                                            digitalWrite(relayPin[i], relayState[i]? RELAY_ON : RELAY_OFF); 
                                            gw.saveState(relayPin[i], relayState[i]);
                                          }
                                        }
                                      }
                                    }
                                    AWIA Offline
                                    AWIA Offline
                                    AWI
                                    Hero Member
                                    wrote on last edited by
                                    #21

                                    @jeylites You are initializing the relays with the "Start State of Relays" and afterwards with the state from EEPROM. That could cause the on/off switching at startup.

                                    1 Reply Last reply
                                    0
                                    • ChaoticC Offline
                                      ChaoticC Offline
                                      Chaotic
                                      wrote on last edited by
                                      #22

                                      To Elaborate on what AWI said

                                      @jeylites said:

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

                                      You have both of those lines in your Setup() The first one is setting the relay to off the second one is checking the EEPROM value

                                      Remove the first one and the problems should be fixed (assuming the EEPROM data is correct.

                                      jeylitesJ 1 Reply Last reply
                                      0
                                      • ChaoticC Chaotic

                                        To Elaborate on what AWI said

                                        @jeylites said:

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

                                        You have both of those lines in your Setup() The first one is setting the relay to off the second one is checking the EEPROM value

                                        Remove the first one and the problems should be fixed (assuming the EEPROM data is correct.

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

                                        @Chaotic , @AWI

                                        //digitalWrite(relayPin[i], RELAY_OFF); //Start State of Relays
                                        I did as you say and removed the above line but still no luck. The relay turns on/off on every start up. And it doesn't hold the last state. I compared My Sensor's script with Bulldogs's and found lots of similarities but can't seem to find the fault.

                                        AWIA 1 Reply Last reply
                                        0
                                        • jeylitesJ jeylites

                                          @Chaotic , @AWI

                                          //digitalWrite(relayPin[i], RELAY_OFF); //Start State of Relays
                                          I did as you say and removed the above line but still no luck. The relay turns on/off on every start up. And it doesn't hold the last state. I compared My Sensor's script with Bulldogs's and found lots of similarities but can't seem to find the fault.

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

                                          @jeylites I took a deeper look at your sketch and think I found the cause. You are writing and reading from different EEPROM locations. The "standard" way is to use the "Sensor number" as location reference. Whereas the sketch also used "relayPin[i]" to store values. I took the liberty of adapting your sketch as I found it hard to read. Also added storing the value in EEPROM after pushing a button.
                                          I have not build the circuit so were not able to test it in real life :) Have fun and let me know if it worked for you.

                                          https://codebender.cc/sketch:92964

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


                                          7

                                          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