Anyone help with 4 relays please?
-
Thanks for the idea and moral support!
With due respect to all involved I found this thread from last year.....
https://forum.mysensors.org/topic/1299/array-relay-button-actuator
The code didn't compile at first due to a typo and then when loaded it didn't work due to deprecated sensor-type and variable-type. I updated it for compatibility with 2.2.0-rc.1 and it nearly all works.
It compiles and loads.
The gw and controller see it and buttons made in the controller switch the relays fine.
The local physical buttons also toggle the relays just fine.
But when the physical buttons are used to toggle the relays, the controller does not update the status on the screen so any changes made locally are not known by the controller.Here is the updated code, if anyone can see an issue in the void loop() then might be causeing this I would love to hear about it!
#define MY_RADIO_NRF24 #define MY_RF24_PA_LEVEL RF24_PA_LOW //#define MY_REPEATER_FEATURE #include <MySensors.h> #define MY_NODE_ID 140 #include <SPI.h> #include <Bounce2.h> #define RELAY_ON 0 // switch around for relay HIGH/LOW state #define RELAY_OFF 1 // #define noRelays 4 //2-4 const int relayPin[] = {4,5,6,7}; // switch around pins to your desire const int buttonPin[] = {A0,A1,A2,A3}; // switch around pins to your desire class Relay // relay class, store all relevant data (equivalent to struct) { public: int buttonPin; // physical pin number of button int relayPin; // physical pin number of relay byte oldValue; // last Values for key (debounce) boolean relayState; // relay status (also stored in EEPROM) }; Relay Relays[noRelays]; Bounce debouncer[noRelays]; MyMessage msg[noRelays]; void setup(){ sendHeartbeat(); wait(250); // Initialize Relays with corresponding buttons for (int i = 0; i < noRelays; i++){ Relays[i].buttonPin = buttonPin[i]; // assign physical pins Relays[i].relayPin = relayPin[i]; msg[i].sensor = i; // initialize messages msg[i].type = V_STATUS; debouncer[i] = Bounce(); // initialize debouncer debouncer[i].attach(buttonPin[i]); debouncer[i].interval(5); pinMode(Relays[i].buttonPin, INPUT_PULLUP); //digitalWrite(Relays[i].relayPin, RELAY_OFF); wait(250); pinMode(Relays[i].relayPin, OUTPUT); Relays[i].relayState = loadState(i); // retrieve last values from EEPROM digitalWrite(Relays[i].relayPin, Relays[i].relayState? RELAY_ON:RELAY_OFF); // and set relays accordingly send(msg[i].set(Relays[i].relayState? true : false)); // make controller aware of last status wait(250); } } void presentation() { sendSketchInfo("MYS-4-Relay", "0.1"); wait(250); for (int i = 0; i < noRelays; i++) present(i, S_BINARY); // present sensor to gateway } void loop() { for (byte i = 0; i < noRelays; i++){ debouncer[i].update(); byte value = debouncer[i].read(); if (value != Relays[i].oldValue && value==0){ Relays[i].relayState = !Relays[i].relayState; digitalWrite(Relays[i].relayPin, Relays[i].relayState?RELAY_ON:RELAY_OFF); send(msg[i].set(Relays[i].relayState? true : false)); saveState( i, Relays[i].relayState );} // save sensor state in EEPROM (location == sensor number) Relays[i].oldValue = value; } } // process incoming message void receive(const MyMessage &message){ if (message.type == V_STATUS){ 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) } } } -
If anyone is interested this now works perfectly with mycontroller, local buttons and remote buttons too.....
@skywatch Hi, I was trying to follow your findings as I have exactly the same issue, but unfortunately, although I basically used the same setup as you did, it still misbehaves. Sometimes is reacts immediately, 5 times in a row, and sometimes it simply does not work for 10 attempts. My 8 relay sketch is so simple that it can not be simpler. Also using the capacitor - still no effect. Other relay sketch - same code, same everything - works as expected :( Really no idea.
-
If anyone is interested this now works perfectly with mycontroller, local buttons and remote buttons too.....
@skywatch said in Anyone help with 4 relays please?:
If anyone is interested this now works perfectly with mycontroller, local buttons and remote buttons too.....
Any modification to the above code? This could be very handy for me!
EDIT: does each button pin correspond to a relay? So in your example A0 relates to 4?
Or can I use the rules in MC to dynamically assign buttons to operations?
-
@petr nosek
You can only compare the one that works with the one that doesn't and see if you can figure out what is different and causing the problems.
Yes pins A0-A3 are button inputs for relay 1-4.
Yes, works from mycontroller and buttons - I am re-learning all this again now as my controller sd card died and I lost a lot of settings - still it will be worth it. -
@petr nosek
You can only compare the one that works with the one that doesn't and see if you can figure out what is different and causing the problems.
Yes pins A0-A3 are button inputs for relay 1-4.
Yes, works from mycontroller and buttons - I am re-learning all this again now as my controller sd card died and I lost a lot of settings - still it will be worth it.@skywatch thanks for the answer. I did compare all and they all share teh same code. Pretty much. Some work for year or two without being touched and they are even further away from the gateway. I do think, that there is either HW problem with the arduino or the radio module. Before I touch it - which of those two determine what ID is the sensor? Is it the Radio module or arduino? I ask because when I change the one which delivers the ID, all the relays on the controller will be lost and I will have to rewrite all related dependencies etc.
Regarding your further not on the lost configuration. I found somewhere a piece of code - a script, which does upload daily the current full database and configuration to dropbox - so in case I loose the raspberry Pi or SD card, I can restore it in a minute with the history. If you ned I can find it and send it.
-
My currnet setup is running fine although there are occasional dropouts and that needs investigation.
I added a heartbeat for the controller as the node often has no communications for hours at a time.
I also tried to get 'ack' working with the node and gw/controller and this gave me some issues that I didn't have any time to really look into (World Cup etc....) ;)
Hopefully I get some more time soon to look into this again.
-
Hi skywatch,
would you be so kind and share your ack and heart beat code snippets? I tried to use the code from examples, but it seems teh heartbeat never worked as expected. Regarding the ack - I am getting constantly a message: Error: MySensors: Repeating previous command (2/2) - seems to me to be related to ack as it simply does not get acknowledgement from the node and repeats the command again. But in 99% cases the command seems to be executed fine. -
My currnet setup is running fine although there are occasional dropouts and that needs investigation.
I added a heartbeat for the controller as the node often has no communications for hours at a time.
I also tried to get 'ack' working with the node and gw/controller and this gave me some issues that I didn't have any time to really look into (World Cup etc....) ;)
Hopefully I get some more time soon to look into this again.
@skywatch P.S. I have one more theory I need to prove. Based on another discussion where my sauna control display fails to display properly after several relay switch on and off which according to many users is caused by the use of common power source for arduino/LCD and the relays which create short but noticeable power peaks. So I will try to power my 8 node relay board from a independent power source from the power used for arduino... A little chance, but worth testing.
-
Hi skywatch,
would you be so kind and share your ack and heart beat code snippets? I tried to use the code from examples, but it seems teh heartbeat never worked as expected. Regarding the ack - I am getting constantly a message: Error: MySensors: Repeating previous command (2/2) - seems to me to be related to ack as it simply does not get acknowledgement from the node and repeats the command again. But in 99% cases the command seems to be executed fine.See below for the current code I run for my 4 relay test node.....
#define MY_DEBUG #define MY_RADIO_NRF24 #define MY_RF24_PA_LEVEL RF24_PA_HIGH #define MY_NODE_ID 140 #define MY_RF24_CHANNEL (97) #define MY_PARENT_NODE_ID 0 #define MY_PARENT_NODE_IS_STATIC //#define MY_REPEATER_FEATURE //#define MY_SIGNING_ATSHA204 //#define MY_SIGNING_REQUEST_SIGNATURES #include <MySensors.h> #include <SPI.h> #include <Bounce2.h> #define RELAY_ON 1 // switch around for relay HIGH/LOW state #define RELAY_OFF 0 // unsigned long HEARTBEAT_TIME = 60000*10; //every 10 mins. unsigned long last_heartbeat_time = 0; #define noRelays 4 //2-4 const int relayPin[] = {4,5,6,7}; // switch around pins to your desire const int buttonPin[] = {A0,A1,A2,A3}; // 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(){ wait(250); // Initialize Relays with corresponding buttons for (int i = 0; i < noRelays; i++){ Relays[i].buttonPin = buttonPin[i]; // assign physical pins Relays[i].relayPin = relayPin[i]; msg[i].sensor = i; // initialize messages msg[i].type = V_STATUS; debouncer[i] = Bounce(); // initialize debouncer debouncer[i].attach(buttonPin[i]); debouncer[i].interval(5); pinMode(Relays[i].buttonPin, INPUT_PULLUP); digitalWrite(Relays[i].relayPin, RELAY_OFF); wait(250); pinMode(Relays[i].relayPin, OUTPUT); Relays[i].relayState = loadState(i); // retrieve last values from EEPROM digitalWrite(Relays[i].relayPin, Relays[i].relayState? RELAY_ON:RELAY_OFF); // and set relays accordingly send(msg[i].set(Relays[i].relayState? true : false),true); // make controller aware of last status wait(250); } } void presentation() { sendSketchInfo("MYS-4-Relay", "0.2"); wait(250); present(0, S_BINARY,"Relay 1"); wait(150); present(1, S_BINARY,"Relay 2"); wait(150); present(2, S_BINARY,"Relay 3"); wait(150); present(3, S_BINARY,"Relay 4"); } void loop() { // Send heartbeat if ((millis() - last_heartbeat_time) > HEARTBEAT_TIME) { sendHeartbeat(); last_heartbeat_time = millis(); #ifdef MY_DEBUG Serial.println("Sent heartbeat"); #endif } for (byte i = 0; i < noRelays; i++){ debouncer[i].update(); byte value = debouncer[i].read(); if (value != Relays[i].oldValue && value==0){ Relays[i].relayState = !Relays[i].relayState; digitalWrite(Relays[i].relayPin, Relays[i].relayState?RELAY_ON:RELAY_OFF); send(msg[i].set(Relays[i].relayState? true : false),true); saveState( i, Relays[i].relayState );} // save sensor state in EEPROM (location == sensor number) Relays[i].oldValue = value; wait(50); } } // process incoming message void receive(const MyMessage &message){ if (message.type == V_STATUS){ 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) } } }This includes my latest attempt at heartbeat and ack. Heartbeat works fine, but ack is still a problem with mycontroller.
I can't risk using it until ack and signing are implemented and fully reliable as it will be controlling mains devices and that needs to be done securely.As for your sauna problem don't forget to connect the grounds between power supplies. You could try adding a 0.1uF capacitor across the 5v supply along with a nice big 220uF 6.3V or higher electrolytic. That might help with spikes or momentary sags in the voltage caused by current rush.
-
Good day everyone,
in case someone faces the same issues I did:- controlling multiple relays from one arduino and sharing the same power (powering relay board from Arduino
or - controlling relay which switches high loads circuit causing connected LCD to show garbage and again powering the relay from Arduino...
...the solution proposed above is the only one which helps - provide separated power supply for the relay boards. Once this is done with an extra little bucket power source for 5V (3W) all the issues with relays not working, domoticz not switching relays, LCD going crazy - all solved. I should have done this long before.
Thanks everyone!
P.S. For those, who still do not follow, the relay boards for Arduino contain extra jumper connecting VCC and JD-VCC (plus sometimes extra GND pin). So remove the jumper and connect the standalone, not common sharing 5V power source to this extra JD-VCC and GND (or GND near the IN1 pin) and disconnect the GND from Arduino and then you have a full optosiolation and then there are no interferences and other garbage breaking the Arduino functionality by switching relays coils. (also explained here: https://forum.arduino.cc/index.php?topic=470134.0)
- controlling multiple relays from one arduino and sharing the same power (powering relay board from Arduino
-
If this really solves the problem...would have saved me a lot of headaches. Got rid of all my relay nodes in the meantime.
-
If this really solves the problem...would have saved me a lot of headaches. Got rid of all my relay nodes in the meantime.
@parachutesj I do say it does. I have about 50 nodes in my house, 15 relays or so, temperature sensors and some others. All the relays i power now with standalone little china made 5V, 3W adapters and as I sit now in my house I do switch on and off lights, turn on gate, control pumps in greenhouse, all works on the first tap. I am finally happy with my mysensors equipped domoticz, first after 2 years. It took my so long to just give it a try.
-
@parachutesj I do say it does. I have about 50 nodes in my house, 15 relays or so, temperature sensors and some others. All the relays i power now with standalone little china made 5V, 3W adapters and as I sit now in my house I do switch on and off lights, turn on gate, control pumps in greenhouse, all works on the first tap. I am finally happy with my mysensors equipped domoticz, first after 2 years. It took my so long to just give it a try.
@petr-nosek my problem was maily unrealiability. They worked for minutes or weeks and then stopped (or anything in between).
All other nodes work flawless.
Maybe give it a try at next project -
@gohan I have tried all kinds of things. I believe that the fact that I used watchdogs which checked the MySensors nodes every 8 seconds (or less) helped me to recover from relay failures so the nodes appeared to be functional, but only randomly. In real life it looked good when I started them. did several turn on and off and it worked. In 2-3 minutes I did try again, it worked for 2 out of 4 attempts and then it stopped responding. In another 20-30 seconds I did try again and then again it appeared to work - I believe it was thanks to the watchdogs recovering the frozen node after the relay peak caused them to stop working. But only a theory, I have no deeper knowledge to prove this.