Array Relay Button Actuator
-
Hello everyone,
Has anyone done an Array Relay Button Actuator?
-
Hello everyone,
Has anyone done an Array Relay Button Actuator?
I'm having the same issue too using Multi Button Actuator sketch. I can't figure out how to switch from Lo to Hi or Lo to Hi to drive my relays because nothing happens when I change #define. and the sketch can't seem to communicate with my Vera UI7. But when I use a single actuator sketch from My sensor library, it communicates well with Vera. So its obvious that something is not right in the sketch for it to react that way.
Anyway, this is what I have done with the help of the community. Perhaps you or someone can make it better.
#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 #define noRelays 4 const int relayPin[] = {3,7}; const int buttonPin[] = {4,5}; 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(NULL, 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); delay(250); 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){ delay(250); if (message.type == V_LIGHT){ delay(250); if (message.sensor <= noRelays){ // check if message is valid for relays delay(250); Relays[message.sensor].relayState = message.getBool(); delay(250); digitalWrite(Relays[message.sensor].relayPin, Relays[message.sensor].relayState? RELAY_ON:RELAY_OFF); // and set relays accordingly delay(250); gw.saveState( message.sensor, Relays[message.sensor].relayState ); // save sensor state in EEPROM (location == sensor number) } } } -
@jeylites A few things to consider:
- You have hardwired the radio id to 11 - make sure you aren't using 11 on any other sensors or actuators.
- #define noRelays is set to 4 but you only have two relayPin and buttonPin values set. So noRelays needs to be set to 2 otherwise the setup method is going to run off the end of the arrays in the for loop that could crash the sketch/Arduino or at a minimum overwrite other memory causing unpredictable behavior.
I would check those two things first and report back.
-
@jeylites A few things to consider:
- You have hardwired the radio id to 11 - make sure you aren't using 11 on any other sensors or actuators.
- #define noRelays is set to 4 but you only have two relayPin and buttonPin values set. So noRelays needs to be set to 2 otherwise the setup method is going to run off the end of the arrays in the for loop that could crash the sketch/Arduino or at a minimum overwrite other memory causing unpredictable behavior.
I would check those two things first and report back.
I dedicated Radio ID 11 for this sketch. I don't have any sensor or actuators on this channel. Initially, I had #define noRelays set as 4 but I changed it to 2 for testing purpose and forgot to update the sketch when I posted here. Anyway, this is the problem I'm facing.
-
I'm unable to control the Relays from the Vera App and Web interface, but I'm able to toggle the light switch button ON / OFF on Vera App and Web from the Arduino button inputs. Basically the Button pin works, but not Relay Pin.
-
I'm unable to switch around for realy HIGH/LOW state.
Serial Report: Upon start up
repeater started, id 11
send: 11-11-0-0 s=255,c=0,t=18,pt=0,l=5,st=ok:1.4.1
send: 11-11-0-0 s=255,c=3,t=6,pt=1,l=1,st=ok:0
read: 0-0-11 s=255,c=3,t=6,pt=0,l=1:M
send: 11-11-0-0 s=255,c=3,t=11,pt=0,l=16,st=ok:MultiRelayButton
send: 11-11-0-0 s=255,c=3,t=12,pt=0,l=4,st=ok:0.9b
send: 11-11-0-0 s=0,c=1,t=2,pt=2,l=2,st=ok:0
send: 11-11-0-0 s=0,c=0,t=3,pt=0,l=5,st=ok:1.4.1
send: 11-11-0-0 s=1,c=1,t=2,pt=2,l=2,st=ok:1
send: 11-11-0-0 s=1,c=0,t=3,pt=0,l=5,st=ok:1.4.1Serial Report: When button is pressed
send: 11-11-0-0 s=0,c=1,t=2,pt=2,l=2,st=ok:1
send: 11-11-0-0 s=0,c=1,t=2,pt=2,l=2,st=ok:0#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 #define noRelays 2 const int relayPin[] = {3,7}; const int buttonPin[] = {4,5}; 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(NULL, 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); delay(250); 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){ delay(250); if (message.type == V_LIGHT){ delay(250); if (message.sensor <= noRelays){ // check if message is valid for relays delay(250); Relays[message.sensor].relayState = message.getBool(); delay(250); digitalWrite(Relays[message.sensor].relayPin, Relays[message.sensor].relayState? RELAY_ON:RELAY_OFF); // and set relays accordingly delay(250); gw.saveState( message.sensor, Relays[message.sensor].relayState ); // save sensor state in EEPROM (location == sensor number) } } } -
Do you have messages coming in from the controller when executing commands from Vera? You should see this as 'read' in the debug output.?
-
Do you have messages coming in from the controller when executing commands from Vera? You should see this as 'read' in the debug output.?
-
@AWI How do I go about doing this?
This is the messages i get from the gateway when actuator is pressed on the sensor node.
0;0;3;0;9;read: 11-11-0 s=0,c=1,t=2,pt=2,l=2:0
11;0;1;0;2;0
0;0;3;0;9;read: 11-11-0 s=0,c=1,t=2,pt=2,l=2:1
11;0;1;0;2;1 -
@AWI How do I go about doing this?
This is the messages i get from the gateway when actuator is pressed on the sensor node.
0;0;3;0;9;read: 11-11-0 s=0,c=1,t=2,pt=2,l=2:0
11;0;1;0;2;0
0;0;3;0;9;read: 11-11-0 s=0,c=1,t=2,pt=2,l=2:1
11;0;1;0;2;1 -
@jeylites I was meaning to say.: on the node serial output. Do you see messages coming in. You can also add a print statement in the received message code.
-
... 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.
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.
-
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.
@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"
-
@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"
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) } } } -
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) } } }Just tested this sketch and it works. Thank for the effort.
-
Just tested this sketch and it works. Thank for the effort.
-
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..