Multi Button Relay Sketch
-
I try sketch from your link but i test and the same issu.
I enable relay, then disable GATEWAY MySensors on DOmoticz and then change status relay to DISABLE by button. Then enable Gateway on Domoticz and still in domoticz show that relay is ENABLED. Not update status that i manual DISABLE relay by button.@pepson said in Multi Button Relay Sketch:
I try sketch from your link but i test and the same issu.
I enable relay, then disable GATEWAY MySensors on DOmoticz and then change status relay to DISABLE by button. Then enable Gateway on Domoticz and still in domoticz show that relay is ENABLED. Not update status that i manual DISABLE relay by button.As far as I know there is no direct way to test for a connection all the way to the controller in MySensors 2.1.
My sketch for the synchronising switch uses the presence of the gateway as the test, this has been adequate for my needs. My controller and gateway are both powered from the same place so they both go down if power is lost.
I have found Domoticz very stable and have not had any issues with it at all so am wondering why Dometicz seems to be giving you problems. is it powered from a different supply to your gateway?
I do have another sketch that uses requestTime as a way of checking for the controller that may be of use to you. it needs a little cleaning up first, so will have a look at it when i get a chance and post it for you to try.
-
@pepson said in Multi Button Relay Sketch:
I try sketch from your link but i test and the same issu.
I enable relay, then disable GATEWAY MySensors on DOmoticz and then change status relay to DISABLE by button. Then enable Gateway on Domoticz and still in domoticz show that relay is ENABLED. Not update status that i manual DISABLE relay by button.As far as I know there is no direct way to test for a connection all the way to the controller in MySensors 2.1.
My sketch for the synchronising switch uses the presence of the gateway as the test, this has been adequate for my needs. My controller and gateway are both powered from the same place so they both go down if power is lost.
I have found Domoticz very stable and have not had any issues with it at all so am wondering why Dometicz seems to be giving you problems. is it powered from a different supply to your gateway?
I do have another sketch that uses requestTime as a way of checking for the controller that may be of use to you. it needs a little cleaning up first, so will have a look at it when i get a chance and post it for you to try.
@boots33
Gateway and Node has the same POWER. But Node start faster than Domoticz with Gateway.But in my gateway is not tested when i use radio RFM69HW ?
Problem is when Domoticz with gateway down power, (also NODE down power). When power come back and under start Domoticz i change status on relay it is not show in domoticz because NODE with relay start faster than DOmoticz with Gateway.
Also when i disable power from Domoticz with ENABLE RELAY . but NODe has still power and change relay to DISABLE and then again POWER ON Domoticz. After run Domoticz not show actual status my Relay because GATWAY was disable when i change status relay.Explaine me more please for what is in your sketch SYNCHRONISING ? What does it give us?
-
@boots33
Gateway and Node has the same POWER. But Node start faster than Domoticz with Gateway.But in my gateway is not tested when i use radio RFM69HW ?
Problem is when Domoticz with gateway down power, (also NODE down power). When power come back and under start Domoticz i change status on relay it is not show in domoticz because NODE with relay start faster than DOmoticz with Gateway.
Also when i disable power from Domoticz with ENABLE RELAY . but NODe has still power and change relay to DISABLE and then again POWER ON Domoticz. After run Domoticz not show actual status my Relay because GATWAY was disable when i change status relay.Explaine me more please for what is in your sketch SYNCHRONISING ? What does it give us?
@pepson said in Multi Button Relay Sketch:
because NODE with relay start faster than DOmoticz with Gateway.
One solution could be to add a delay to your node and gateway sketches. This could just be run once as the node/gateway boots up thus giving Domoticz time to boot.
Also when i disable power from Domoticz with ENABLE RELAY . but NODe has still power and change relay to DISABLE and then again POWER ON Domoticz. After run Domoticz not show actual status my Relay because GATWAY was disable >when i change status relay.
As I have said earlier all MySensors 2.1 checks for uplink available are only checking for a connection to the gateway not all the way to the controller. So you can turn the controller on and off as often as you like and the node will not know it is not there. As long as the gateway is present the node will show the uplink as available.
Explaine me more please for what is in your sketch SYNCHRONISING ? What does it give us?
My original syncing switch sketch that i pointed you to above will work for most normal situations where the controller and gateway are on the same power supply. If you add the delay I have mentioned to your Gateway/node then that will allow the controller to boot first when returning from a power outage.
When you are turning off the controller by itself I do not think that is a true real world test, if the gateway and controller share the same power supply then this is not likely to happen.
In any case you may need to implement some form of code on Dometicz to push the occurrence of a controller reboot to your nodes. The nodes will not detect a missing controller unless your nodes are constantly pinging the controller to see if it is there.
I do have the other sketch using a time request to check for the presence of the controller, I will post that code in my Synchronising Light switch thread for you to try.
-
@boots33 said in Multi Button Relay Sketch:
When you are turning off the controller by itself I do not think that is a true real world test, if the gateway and controller share the same power supply then this is not likely to happen.
In any case you may need to implement some form of code on Dometicz to push the occurrence of a controller reboot to your nodes. The nodes will not detect a missing controller unless your nodes are constantly pinging the controller to see if it is there.
I do have the other sketch using a time request to check for the presence of the controller, I will post that code in my Synchronising Light switch thread for you to try.Ok i wait for your sketch using a time request...
I have Domoticz on Raspberry Pi3 and to this Raspberry i have connected Gateway MySensors on Arduino Nano by USB from Rasspberry.
Can you ready code for delay start gateway and node ?
And tell me when i restart Gateway , it ceck status NODE ? How i can restart gateway on my raspberry without disable raspberry and domoticz ?
-
hello,
I made this code it save state in EEPROM after reboot it load previous state saved .
I share you my sketch is made for 4 relays an 4 momentary button.// Enable debug prints to serial monitor #define MY_DEBUG // Enable and select radio type attached #define MY_RADIO_NRF24 //#define MY_RADIO_RFM69 // Enabled repeater feature for this node #define MY_REPEATER_FEATURE #include <SPI.h> #include <MySensors.h> #include <Bounce2.h> #define RELAY_PIN0 5 // Arduino Digital I/O pin number for relay #define RELAY_PIN1 6 #define RELAY_PIN2 7 #define RELAY_PIN3 8 #define BUTTON_PIN0 A0 // Arduino Digital I/O pin number for button #define BUTTON_PIN1 A1 // Arduino Digital I/O pin number for button #define BUTTON_PIN2 A2 // Arduino Digital I/O pin number for button #define BUTTON_PIN3 A3 // Arduino Digital I/O pin number for button #define CHILD0_ID 50 // Id of the sensor child #define CHILD1_ID 51 // Id of the sensor child #define CHILD2_ID 52 // Id of the sensor child #define CHILD3_ID 53 // Id of the sensor child #define RELAY_ON 1 #define RELAY_OFF 0 Bounce debouncerA = Bounce(); Bounce debouncerB = Bounce(); Bounce debouncerC = Bounce(); Bounce debouncerD = Bounce(); int oldValueA = 0; int oldValueB = 0; int oldValueC = 0; int oldValueD = 0; bool stateA; bool stateB; bool stateC; bool stateD; MyMessage msgA(CHILD0_ID, V_LIGHT); MyMessage msgB(CHILD1_ID, V_LIGHT); MyMessage msgC(CHILD2_ID, V_LIGHT); MyMessage msgD(CHILD3_ID, V_LIGHT); void setup() { // Setup the button pinMode(BUTTON_PIN0, INPUT_PULLUP); pinMode(BUTTON_PIN1, INPUT_PULLUP); pinMode(BUTTON_PIN2, INPUT_PULLUP); pinMode(BUTTON_PIN3, INPUT_PULLUP); // After setting up the button, setup debouncer debouncerA.attach(BUTTON_PIN0); debouncerA.interval(5); debouncerB.attach(BUTTON_PIN1); debouncerB.interval(5); debouncerC.attach(BUTTON_PIN2); debouncerC.interval(5); debouncerD.attach(BUTTON_PIN3); debouncerD.interval(5); // Make sure relays are off when starting up digitalWrite(RELAY_PIN0, RELAY_OFF); digitalWrite(RELAY_PIN1, RELAY_OFF); digitalWrite(RELAY_PIN2, RELAY_OFF); digitalWrite(RELAY_PIN3, RELAY_OFF); // Then set relay pins in output mode pinMode(RELAY_PIN0, OUTPUT); pinMode(RELAY_PIN1, OUTPUT); pinMode(RELAY_PIN2, OUTPUT); pinMode(RELAY_PIN3, OUTPUT); // Set relay to last known state (using eeprom storage) stateA = loadState(CHILD0_ID); digitalWrite(RELAY_PIN0, stateA ? RELAY_ON : RELAY_OFF); stateB = loadState(CHILD1_ID); digitalWrite(RELAY_PIN1, stateB ? RELAY_ON : RELAY_OFF); stateC = loadState(CHILD2_ID); digitalWrite(RELAY_PIN2, stateC ? RELAY_ON : RELAY_OFF); stateD = loadState(CHILD3_ID); digitalWrite(RELAY_PIN3, stateD ? RELAY_ON : RELAY_OFF); } void presentation() { // Send the sketch version information to the gateway and Controller sendSketchInfo("4 Relay & button", "1.0"); // Register all sensors to gw (they will be created as child devices) present(CHILD0_ID, S_LIGHT); present(CHILD1_ID, S_LIGHT); present(CHILD2_ID, S_LIGHT); present(CHILD3_ID, S_LIGHT); } /* Example on how to asynchronously check for new messages from gw */ void loop() { debouncerA.update(); // Get the update value int valueA = debouncerA.read(); if (valueA != oldValueA && valueA == 0) { send(msgA.set(stateA ? false : true), true); // Send new state and request ack back } oldValueA = valueA; debouncerB.update(); // Get the update value int valueB = debouncerB.read(); if (valueB != oldValueB && valueB == 0) { send(msgB.set(stateB ? false : true), true); // Send new state and request ack back } oldValueB = valueB; debouncerC.update(); // Get the update value int valueC = debouncerC.read(); if (valueC != oldValueC && valueC == 0) { send(msgC.set(stateC ? false : true), true); // Send new state and request ack back } oldValueC = valueC; debouncerD.update(); // Get the update value int valueD = debouncerD.read(); if (valueD != oldValueD && valueD == 0) { send(msgD.set(stateD ? false : true), true); // Send new state and request ack back } oldValueD = valueD; } void receive(const MyMessage &message) { // We only expect one type of message from controller. But we better check anyway. if (message.type == V_LIGHT) { switch (message.sensor) { case CHILD0_ID: stateA = message.getBool(); digitalWrite(RELAY_PIN0, stateA ? RELAY_ON : RELAY_OFF); saveState(CHILD0_ID, stateA); break; case CHILD1_ID: stateB = message.getBool(); digitalWrite(RELAY_PIN1, stateB ? RELAY_ON : RELAY_OFF); saveState(CHILD1_ID, stateB); break; case CHILD2_ID: stateC = message.getBool(); digitalWrite(RELAY_PIN2, stateC ? RELAY_ON : RELAY_OFF); saveState(CHILD2_ID, stateC); break; case CHILD3_ID: stateD = message.getBool(); digitalWrite(RELAY_PIN3, stateD ? RELAY_ON : RELAY_OFF); saveState(CHILD3_ID, stateD); break; } // Write some debug info Serial.print("Incoming change for sensor:"); Serial.print(message.sensor); Serial.print(", New status: "); Serial.println(message.getBool()); } } -
hello,
I made this code it save state in EEPROM after reboot it load previous state saved .
I share you my sketch is made for 4 relays an 4 momentary button.// Enable debug prints to serial monitor #define MY_DEBUG // Enable and select radio type attached #define MY_RADIO_NRF24 //#define MY_RADIO_RFM69 // Enabled repeater feature for this node #define MY_REPEATER_FEATURE #include <SPI.h> #include <MySensors.h> #include <Bounce2.h> #define RELAY_PIN0 5 // Arduino Digital I/O pin number for relay #define RELAY_PIN1 6 #define RELAY_PIN2 7 #define RELAY_PIN3 8 #define BUTTON_PIN0 A0 // Arduino Digital I/O pin number for button #define BUTTON_PIN1 A1 // Arduino Digital I/O pin number for button #define BUTTON_PIN2 A2 // Arduino Digital I/O pin number for button #define BUTTON_PIN3 A3 // Arduino Digital I/O pin number for button #define CHILD0_ID 50 // Id of the sensor child #define CHILD1_ID 51 // Id of the sensor child #define CHILD2_ID 52 // Id of the sensor child #define CHILD3_ID 53 // Id of the sensor child #define RELAY_ON 1 #define RELAY_OFF 0 Bounce debouncerA = Bounce(); Bounce debouncerB = Bounce(); Bounce debouncerC = Bounce(); Bounce debouncerD = Bounce(); int oldValueA = 0; int oldValueB = 0; int oldValueC = 0; int oldValueD = 0; bool stateA; bool stateB; bool stateC; bool stateD; MyMessage msgA(CHILD0_ID, V_LIGHT); MyMessage msgB(CHILD1_ID, V_LIGHT); MyMessage msgC(CHILD2_ID, V_LIGHT); MyMessage msgD(CHILD3_ID, V_LIGHT); void setup() { // Setup the button pinMode(BUTTON_PIN0, INPUT_PULLUP); pinMode(BUTTON_PIN1, INPUT_PULLUP); pinMode(BUTTON_PIN2, INPUT_PULLUP); pinMode(BUTTON_PIN3, INPUT_PULLUP); // After setting up the button, setup debouncer debouncerA.attach(BUTTON_PIN0); debouncerA.interval(5); debouncerB.attach(BUTTON_PIN1); debouncerB.interval(5); debouncerC.attach(BUTTON_PIN2); debouncerC.interval(5); debouncerD.attach(BUTTON_PIN3); debouncerD.interval(5); // Make sure relays are off when starting up digitalWrite(RELAY_PIN0, RELAY_OFF); digitalWrite(RELAY_PIN1, RELAY_OFF); digitalWrite(RELAY_PIN2, RELAY_OFF); digitalWrite(RELAY_PIN3, RELAY_OFF); // Then set relay pins in output mode pinMode(RELAY_PIN0, OUTPUT); pinMode(RELAY_PIN1, OUTPUT); pinMode(RELAY_PIN2, OUTPUT); pinMode(RELAY_PIN3, OUTPUT); // Set relay to last known state (using eeprom storage) stateA = loadState(CHILD0_ID); digitalWrite(RELAY_PIN0, stateA ? RELAY_ON : RELAY_OFF); stateB = loadState(CHILD1_ID); digitalWrite(RELAY_PIN1, stateB ? RELAY_ON : RELAY_OFF); stateC = loadState(CHILD2_ID); digitalWrite(RELAY_PIN2, stateC ? RELAY_ON : RELAY_OFF); stateD = loadState(CHILD3_ID); digitalWrite(RELAY_PIN3, stateD ? RELAY_ON : RELAY_OFF); } void presentation() { // Send the sketch version information to the gateway and Controller sendSketchInfo("4 Relay & button", "1.0"); // Register all sensors to gw (they will be created as child devices) present(CHILD0_ID, S_LIGHT); present(CHILD1_ID, S_LIGHT); present(CHILD2_ID, S_LIGHT); present(CHILD3_ID, S_LIGHT); } /* Example on how to asynchronously check for new messages from gw */ void loop() { debouncerA.update(); // Get the update value int valueA = debouncerA.read(); if (valueA != oldValueA && valueA == 0) { send(msgA.set(stateA ? false : true), true); // Send new state and request ack back } oldValueA = valueA; debouncerB.update(); // Get the update value int valueB = debouncerB.read(); if (valueB != oldValueB && valueB == 0) { send(msgB.set(stateB ? false : true), true); // Send new state and request ack back } oldValueB = valueB; debouncerC.update(); // Get the update value int valueC = debouncerC.read(); if (valueC != oldValueC && valueC == 0) { send(msgC.set(stateC ? false : true), true); // Send new state and request ack back } oldValueC = valueC; debouncerD.update(); // Get the update value int valueD = debouncerD.read(); if (valueD != oldValueD && valueD == 0) { send(msgD.set(stateD ? false : true), true); // Send new state and request ack back } oldValueD = valueD; } void receive(const MyMessage &message) { // We only expect one type of message from controller. But we better check anyway. if (message.type == V_LIGHT) { switch (message.sensor) { case CHILD0_ID: stateA = message.getBool(); digitalWrite(RELAY_PIN0, stateA ? RELAY_ON : RELAY_OFF); saveState(CHILD0_ID, stateA); break; case CHILD1_ID: stateB = message.getBool(); digitalWrite(RELAY_PIN1, stateB ? RELAY_ON : RELAY_OFF); saveState(CHILD1_ID, stateB); break; case CHILD2_ID: stateC = message.getBool(); digitalWrite(RELAY_PIN2, stateC ? RELAY_ON : RELAY_OFF); saveState(CHILD2_ID, stateC); break; case CHILD3_ID: stateD = message.getBool(); digitalWrite(RELAY_PIN3, stateD ? RELAY_ON : RELAY_OFF); saveState(CHILD3_ID, stateD); break; } // Write some debug info Serial.print("Incoming change for sensor:"); Serial.print(message.sensor); Serial.print(", New status: "); Serial.println(message.getBool()); } } -
Here is an example that I'm using with 4 relays and 4 monostable buttons:
// Enable debug prints to serial monitor #define MY_DEBUG // Enable and select radio type attached #define MY_RADIO_NRF24 #define SN "RelayButtonArray" #define SV "1.0" #include <MySensors.h> #include <SPI.h> #include <Bounce2.h> #define RELAY_ON 0 // switch around for ACTIVE LOW / ACTIVE HIGH relay #define RELAY_OFF 1 // #define noRelays 4 //2-4 const int relayPin[] = {14, 15, 16, 17}; // switch around pins to your desire const int buttonPin[] = {6, 7, 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 boolean relayState; // relay status (also stored in EEPROM) }; Relay Relays[noRelays]; Bounce debouncer[noRelays]; MyMessage msg[noRelays]; /* void before() { for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS;sensor++, pin++) { // Then set relay pins in output mode pinMode(pin, OUTPUT); // Set relay to last known state (using eeprom storage) digitalWrite(pin, loadState(sensor)?RELAY_ON:RELAY_OFF); } }*/ void setup() { wait(100); // 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; pinMode(Relays[i].buttonPin, INPUT_PULLUP); wait(100); pinMode(Relays[i].relayPin, OUTPUT); Relays[i].relayState = loadState(i); // retrieve last values from EEPROM digitalWrite(Relays[i].relayPin, Relays[i].relayState ? RELAY_ON : RELAY_OFF); // and set relays accordingly send(msg[i].set(Relays[i].relayState ? true : false)); // make controller aware of last status wait(50); debouncer[i] = Bounce(); // initialize debouncer debouncer[i].attach(buttonPin[i]); debouncer[i].interval(30); wait(50); } } void presentation() { // Send the sketch version information to the gateway and Controller sendSketchInfo(SN, SV); wait(100); for (int i = 0; i < noRelays; i++) present(i, S_LIGHT); // present sensor to gateway wait(100); } void loop() { for (byte i = 0; i < noRelays; i++) { if (debouncer[i].update()) { int value = debouncer[i].read(); if ( value == LOW) { Relays[i].relayState = !Relays[i].relayState; digitalWrite(Relays[i].relayPin, Relays[i].relayState ? RELAY_ON : RELAY_OFF); send(msg[i].set(Relays[i].relayState ? true : false)); // save sensor state in EEPROM (location == sensor number) saveState( i, Relays[i].relayState ); } } } //wait(20); } void receive(const MyMessage &message) { if (message.type == V_LIGHT) { if (message.sensor < noRelays) { // check if message is valid for relays..... previous line [[[ if (message.sensor <=noRelays){ ]]] Relays[message.sensor].relayState = message.getBool(); digitalWrite(Relays[message.sensor].relayPin, Relays[message.sensor].relayState ? RELAY_ON : RELAY_OFF); // and set relays accordingly saveState( message.sensor, Relays[message.sensor].relayState ); // save sensor state in EEPROM (location == sensor number) } } wait(20); }@korttoma Two years later.... I just wanted to say that your sketch is elegant and beautiful. Using arrays is an idea I had as well, but I was just starting to write something when I thought about looking to see if someone had already done it. You saved me days of yelling at the monitor trying work it out for myself. You should consider making a topic out of this script.
-
hello,
I made this code it save state in EEPROM after reboot it load previous state saved .
I share you my sketch is made for 4 relays an 4 momentary button.// Enable debug prints to serial monitor #define MY_DEBUG // Enable and select radio type attached #define MY_RADIO_NRF24 //#define MY_RADIO_RFM69 // Enabled repeater feature for this node #define MY_REPEATER_FEATURE #include <SPI.h> #include <MySensors.h> #include <Bounce2.h> #define RELAY_PIN0 5 // Arduino Digital I/O pin number for relay #define RELAY_PIN1 6 #define RELAY_PIN2 7 #define RELAY_PIN3 8 #define BUTTON_PIN0 A0 // Arduino Digital I/O pin number for button #define BUTTON_PIN1 A1 // Arduino Digital I/O pin number for button #define BUTTON_PIN2 A2 // Arduino Digital I/O pin number for button #define BUTTON_PIN3 A3 // Arduino Digital I/O pin number for button #define CHILD0_ID 50 // Id of the sensor child #define CHILD1_ID 51 // Id of the sensor child #define CHILD2_ID 52 // Id of the sensor child #define CHILD3_ID 53 // Id of the sensor child #define RELAY_ON 1 #define RELAY_OFF 0 Bounce debouncerA = Bounce(); Bounce debouncerB = Bounce(); Bounce debouncerC = Bounce(); Bounce debouncerD = Bounce(); int oldValueA = 0; int oldValueB = 0; int oldValueC = 0; int oldValueD = 0; bool stateA; bool stateB; bool stateC; bool stateD; MyMessage msgA(CHILD0_ID, V_LIGHT); MyMessage msgB(CHILD1_ID, V_LIGHT); MyMessage msgC(CHILD2_ID, V_LIGHT); MyMessage msgD(CHILD3_ID, V_LIGHT); void setup() { // Setup the button pinMode(BUTTON_PIN0, INPUT_PULLUP); pinMode(BUTTON_PIN1, INPUT_PULLUP); pinMode(BUTTON_PIN2, INPUT_PULLUP); pinMode(BUTTON_PIN3, INPUT_PULLUP); // After setting up the button, setup debouncer debouncerA.attach(BUTTON_PIN0); debouncerA.interval(5); debouncerB.attach(BUTTON_PIN1); debouncerB.interval(5); debouncerC.attach(BUTTON_PIN2); debouncerC.interval(5); debouncerD.attach(BUTTON_PIN3); debouncerD.interval(5); // Make sure relays are off when starting up digitalWrite(RELAY_PIN0, RELAY_OFF); digitalWrite(RELAY_PIN1, RELAY_OFF); digitalWrite(RELAY_PIN2, RELAY_OFF); digitalWrite(RELAY_PIN3, RELAY_OFF); // Then set relay pins in output mode pinMode(RELAY_PIN0, OUTPUT); pinMode(RELAY_PIN1, OUTPUT); pinMode(RELAY_PIN2, OUTPUT); pinMode(RELAY_PIN3, OUTPUT); // Set relay to last known state (using eeprom storage) stateA = loadState(CHILD0_ID); digitalWrite(RELAY_PIN0, stateA ? RELAY_ON : RELAY_OFF); stateB = loadState(CHILD1_ID); digitalWrite(RELAY_PIN1, stateB ? RELAY_ON : RELAY_OFF); stateC = loadState(CHILD2_ID); digitalWrite(RELAY_PIN2, stateC ? RELAY_ON : RELAY_OFF); stateD = loadState(CHILD3_ID); digitalWrite(RELAY_PIN3, stateD ? RELAY_ON : RELAY_OFF); } void presentation() { // Send the sketch version information to the gateway and Controller sendSketchInfo("4 Relay & button", "1.0"); // Register all sensors to gw (they will be created as child devices) present(CHILD0_ID, S_LIGHT); present(CHILD1_ID, S_LIGHT); present(CHILD2_ID, S_LIGHT); present(CHILD3_ID, S_LIGHT); } /* Example on how to asynchronously check for new messages from gw */ void loop() { debouncerA.update(); // Get the update value int valueA = debouncerA.read(); if (valueA != oldValueA && valueA == 0) { send(msgA.set(stateA ? false : true), true); // Send new state and request ack back } oldValueA = valueA; debouncerB.update(); // Get the update value int valueB = debouncerB.read(); if (valueB != oldValueB && valueB == 0) { send(msgB.set(stateB ? false : true), true); // Send new state and request ack back } oldValueB = valueB; debouncerC.update(); // Get the update value int valueC = debouncerC.read(); if (valueC != oldValueC && valueC == 0) { send(msgC.set(stateC ? false : true), true); // Send new state and request ack back } oldValueC = valueC; debouncerD.update(); // Get the update value int valueD = debouncerD.read(); if (valueD != oldValueD && valueD == 0) { send(msgD.set(stateD ? false : true), true); // Send new state and request ack back } oldValueD = valueD; } void receive(const MyMessage &message) { // We only expect one type of message from controller. But we better check anyway. if (message.type == V_LIGHT) { switch (message.sensor) { case CHILD0_ID: stateA = message.getBool(); digitalWrite(RELAY_PIN0, stateA ? RELAY_ON : RELAY_OFF); saveState(CHILD0_ID, stateA); break; case CHILD1_ID: stateB = message.getBool(); digitalWrite(RELAY_PIN1, stateB ? RELAY_ON : RELAY_OFF); saveState(CHILD1_ID, stateB); break; case CHILD2_ID: stateC = message.getBool(); digitalWrite(RELAY_PIN2, stateC ? RELAY_ON : RELAY_OFF); saveState(CHILD2_ID, stateC); break; case CHILD3_ID: stateD = message.getBool(); digitalWrite(RELAY_PIN3, stateD ? RELAY_ON : RELAY_OFF); saveState(CHILD3_ID, stateD); break; } // Write some debug info Serial.print("Incoming change for sensor:"); Serial.print(message.sensor); Serial.print(", New status: "); Serial.println(message.getBool()); } }Hi
I change your sketch to working wirg serial wire gateway on my Arduino Mega 2560 but not working.
Why...
In home assistant found 4 childs number:50, 51, 52, 53 but when try change state relay by button or by Home Assistant , state relay not change. Please look.// Enable debug prints to serial monitor #define MY_DEBUG // Enable serial gateway #define MY_GATEWAY_SERIAL // Define a lower baud rate for Arduino's running on 8 MHz (Arduino Pro Mini 3.3V & SenseBender) #if F_CPU == 8000000L #define MY_BAUD_RATE 38400 #endif // Enable debug prints to serial monitor #define MY_DEBUG #include <SPI.h> #include <MySensors.h> #include <Bounce2.h> #define RELAY_PIN0 5 // Arduino Digital I/O pin number for relay #define RELAY_PIN1 6 #define RELAY_PIN2 7 #define RELAY_PIN3 8 #define BUTTON_PIN0 A0 // Arduino Digital I/O pin number for button #define BUTTON_PIN1 A1 // Arduino Digital I/O pin number for button #define BUTTON_PIN2 A2 // Arduino Digital I/O pin number for button #define BUTTON_PIN3 A3 // Arduino Digital I/O pin number for button #define CHILD0_ID 50 // Id of the sensor child #define CHILD1_ID 51 // Id of the sensor child #define CHILD2_ID 52 // Id of the sensor child #define CHILD3_ID 53 // Id of the sensor child #define RELAY_ON 1 #define RELAY_OFF 0 Bounce debouncerA = Bounce(); Bounce debouncerB = Bounce(); Bounce debouncerC = Bounce(); Bounce debouncerD = Bounce(); int oldValueA = 0; int oldValueB = 0; int oldValueC = 0; int oldValueD = 0; bool stateA; bool stateB; bool stateC; bool stateD; MyMessage msgA(CHILD0_ID, V_LIGHT); MyMessage msgB(CHILD1_ID, V_LIGHT); MyMessage msgC(CHILD2_ID, V_LIGHT); MyMessage msgD(CHILD3_ID, V_LIGHT); void setup() { // Setup the button pinMode(BUTTON_PIN0, INPUT_PULLUP); pinMode(BUTTON_PIN1, INPUT_PULLUP); pinMode(BUTTON_PIN2, INPUT_PULLUP); pinMode(BUTTON_PIN3, INPUT_PULLUP); // After setting up the button, setup debouncer debouncerA.attach(BUTTON_PIN0); debouncerA.interval(5); debouncerB.attach(BUTTON_PIN1); debouncerB.interval(5); debouncerC.attach(BUTTON_PIN2); debouncerC.interval(5); debouncerD.attach(BUTTON_PIN3); debouncerD.interval(5); // Make sure relays are off when starting up digitalWrite(RELAY_PIN0, RELAY_OFF); digitalWrite(RELAY_PIN1, RELAY_OFF); digitalWrite(RELAY_PIN2, RELAY_OFF); digitalWrite(RELAY_PIN3, RELAY_OFF); // Then set relay pins in output mode pinMode(RELAY_PIN0, OUTPUT); pinMode(RELAY_PIN1, OUTPUT); pinMode(RELAY_PIN2, OUTPUT); pinMode(RELAY_PIN3, OUTPUT); // Set relay to last known state (using eeprom storage) stateA = loadState(CHILD0_ID); digitalWrite(RELAY_PIN0, stateA ? RELAY_ON : RELAY_OFF); stateB = loadState(CHILD1_ID); digitalWrite(RELAY_PIN1, stateB ? RELAY_ON : RELAY_OFF); stateC = loadState(CHILD2_ID); digitalWrite(RELAY_PIN2, stateC ? RELAY_ON : RELAY_OFF); stateD = loadState(CHILD3_ID); digitalWrite(RELAY_PIN3, stateD ? RELAY_ON : RELAY_OFF); } void presentation() { // Send the sketch version information to the gateway and Controller sendSketchInfo("4 Relay & button", "1.0"); // Register all sensors to gw (they will be created as child devices) present(CHILD0_ID, S_LIGHT); present(CHILD1_ID, S_LIGHT); present(CHILD2_ID, S_LIGHT); present(CHILD3_ID, S_LIGHT); } /* Example on how to asynchronously check for new messages from gw */ void loop() { debouncerA.update(); // Get the update value int valueA = debouncerA.read(); if (valueA != oldValueA && valueA == 0) { send(msgA.set(stateA ? false : true), true); // Send new state and request ack back } oldValueA = valueA; debouncerB.update(); // Get the update value int valueB = debouncerB.read(); if (valueB != oldValueB && valueB == 0) { send(msgB.set(stateB ? false : true), true); // Send new state and request ack back } oldValueB = valueB; debouncerC.update(); // Get the update value int valueC = debouncerC.read(); if (valueC != oldValueC && valueC == 0) { send(msgC.set(stateC ? false : true), true); // Send new state and request ack back } oldValueC = valueC; debouncerD.update(); // Get the update value int valueD = debouncerD.read(); if (valueD != oldValueD && valueD == 0) { send(msgD.set(stateD ? false : true), true); // Send new state and request ack back } oldValueD = valueD; } void receive(const MyMessage &message) { // We only expect one type of message from controller. But we better check anyway. if (message.type == V_LIGHT) { switch (message.sensor) { case CHILD0_ID: stateA = message.getBool(); digitalWrite(RELAY_PIN0, stateA ? RELAY_ON : RELAY_OFF); saveState(CHILD0_ID, stateA); break; case CHILD1_ID: stateB = message.getBool(); digitalWrite(RELAY_PIN1, stateB ? RELAY_ON : RELAY_OFF); saveState(CHILD1_ID, stateB); break; case CHILD2_ID: stateC = message.getBool(); digitalWrite(RELAY_PIN2, stateC ? RELAY_ON : RELAY_OFF); saveState(CHILD2_ID, stateC); break; case CHILD3_ID: stateD = message.getBool(); digitalWrite(RELAY_PIN3, stateD ? RELAY_ON : RELAY_OFF); saveState(CHILD3_ID, stateD); break; } // Write some debug info Serial.print("Incoming change for sensor:"); Serial.print(message.sensor); Serial.print(", New status: "); Serial.println(message.getBool()); } }``` -
Here is an example that I'm using with 4 relays and 4 monostable buttons:
// Enable debug prints to serial monitor #define MY_DEBUG // Enable and select radio type attached #define MY_RADIO_NRF24 #define SN "RelayButtonArray" #define SV "1.0" #include <MySensors.h> #include <SPI.h> #include <Bounce2.h> #define RELAY_ON 0 // switch around for ACTIVE LOW / ACTIVE HIGH relay #define RELAY_OFF 1 // #define noRelays 4 //2-4 const int relayPin[] = {14, 15, 16, 17}; // switch around pins to your desire const int buttonPin[] = {6, 7, 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 boolean relayState; // relay status (also stored in EEPROM) }; Relay Relays[noRelays]; Bounce debouncer[noRelays]; MyMessage msg[noRelays]; /* void before() { for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS;sensor++, pin++) { // Then set relay pins in output mode pinMode(pin, OUTPUT); // Set relay to last known state (using eeprom storage) digitalWrite(pin, loadState(sensor)?RELAY_ON:RELAY_OFF); } }*/ void setup() { wait(100); // 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; pinMode(Relays[i].buttonPin, INPUT_PULLUP); wait(100); pinMode(Relays[i].relayPin, OUTPUT); Relays[i].relayState = loadState(i); // retrieve last values from EEPROM digitalWrite(Relays[i].relayPin, Relays[i].relayState ? RELAY_ON : RELAY_OFF); // and set relays accordingly send(msg[i].set(Relays[i].relayState ? true : false)); // make controller aware of last status wait(50); debouncer[i] = Bounce(); // initialize debouncer debouncer[i].attach(buttonPin[i]); debouncer[i].interval(30); wait(50); } } void presentation() { // Send the sketch version information to the gateway and Controller sendSketchInfo(SN, SV); wait(100); for (int i = 0; i < noRelays; i++) present(i, S_LIGHT); // present sensor to gateway wait(100); } void loop() { for (byte i = 0; i < noRelays; i++) { if (debouncer[i].update()) { int value = debouncer[i].read(); if ( value == LOW) { Relays[i].relayState = !Relays[i].relayState; digitalWrite(Relays[i].relayPin, Relays[i].relayState ? RELAY_ON : RELAY_OFF); send(msg[i].set(Relays[i].relayState ? true : false)); // save sensor state in EEPROM (location == sensor number) saveState( i, Relays[i].relayState ); } } } //wait(20); } void receive(const MyMessage &message) { if (message.type == V_LIGHT) { if (message.sensor < noRelays) { // check if message is valid for relays..... previous line [[[ if (message.sensor <=noRelays){ ]]] Relays[message.sensor].relayState = message.getBool(); digitalWrite(Relays[message.sensor].relayPin, Relays[message.sensor].relayState ? RELAY_ON : RELAY_OFF); // and set relays accordingly saveState( message.sensor, Relays[message.sensor].relayState ); // save sensor state in EEPROM (location == sensor number) } } wait(20); }@korttoma Hello Sir, many thanks for such an elegant piece of code for controlling multiple relays.
I would greatly appreciate if you provide me some tips or updated code on using your code for a "Bi stable" Button setup, i.e. using conventional home switches (ON or OFF states) for controlling relays.Thanks
T