[SOLVED]Two nodes with relays interfering
-
Sure. Here it is. Slight mod from MQTT sketch with Relay sketch parts.
#define MY_DEBUG // Enables and select radio type (if attached) #define MY_RADIO_NRF24 //#define MY_RADIO_RFM69 #define MY_GATEWAY_MQTT_CLIENT // Set this node's subscribe and publish topic prefix #define MY_MQTT_PUBLISH_TOPIC_PREFIX "domoticz/in/MyMQTT" #define MY_MQTT_SUBSCRIBE_TOPIC_PREFIX "domoticz/out/MyMQTT" // Set MQTT client id #define MY_MQTT_CLIENT_ID "mysensors-1" // W5100 Ethernet module SPI enable (optional if using a shield/module that manages SPI_EN signal) //#define MY_W5100_SPI_EN 4 // Enable Soft SPI for NRF radio (note different radio wiring is required) // The W5100 ethernet module seems to have a hard time co-operate with // radio on the same spi bus. #if !defined(MY_W5100_SPI_EN) && !defined(ARDUINO_ARCH_SAMD) #define MY_SOFTSPI #define MY_SOFT_SPI_SCK_PIN 14 #define MY_SOFT_SPI_MISO_PIN 16 #define MY_SOFT_SPI_MOSI_PIN 15 #endif // When W5100 is connected we have to move CE/CSN pins for NRF radio #ifndef MY_RF24_CE_PIN #define MY_RF24_CE_PIN 5 #endif #ifndef MY_RF24_CS_PIN #define MY_RF24_CS_PIN 6 #endif // Enable MY_IP_ADDRESS here if you want a static ip address (no DHCP) #define MY_IP_ADDRESS 192,168,0,201 #define MY_MAC_ADDRESS 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED // If using static ip you need to define Gateway and Subnet address as well #define MY_IP_GATEWAY_ADDRESS 192,168,0,254 #define MY_IP_SUBNET_ADDRESS 255,255,255,0 // MQTT broker ip address or url. Define one or the other. //#define MY_CONTROLLER_URL_ADDRESS "m20.cloudmqtt.com" #define MY_CONTROLLER_IP_ADDRESS 192, 168, 0, 200 // The MQTT broker port to to open #define MY_PORT 1883 /* // Enable inclusion mode #define MY_INCLUSION_MODE_FEATURE // Enable Inclusion mode button on gateway //#define MY_INCLUSION_BUTTON_FEATURE // Set inclusion mode duration (in seconds) #define MY_INCLUSION_MODE_DURATION 60 // Digital pin used for inclusion mode button //#define MY_INCLUSION_MODE_BUTTON_PIN 3 // Set blinking period #define MY_DEFAULT_LED_BLINK_PERIOD 300 // Flash leds on rx/tx/err // Uncomment to override default HW configurations //#define MY_DEFAULT_ERR_LED_PIN 16 // Error led pin //#define MY_DEFAULT_RX_LED_PIN 16 // Receive led pin //#define MY_DEFAULT_TX_LED_PIN 16 // the PCB, on board LED */ #define RELAY_1 3 // Arduino Digital I/O pin number for first relay (second on pin+1 etc) #define NUMBER_OF_RELAYS 2 // Total number of attached relays #define RELAY_ON 0 // GPIO value to write to turn on attached relay #define RELAY_OFF 1 // GPIO value to write to turn off attached relay // #define CHILD_ID_RELAY1 1 // #define CHILD_ID_RELAY2 2 #include <Ethernet.h> #include <MySensors.h> 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() { } void presentation() { // Send the sketch version information to the gateway and Controller sendSketchInfo("MQTT_GWAndRelay", "vMasi"); for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) { // Register all sensors to gw (they will be created as child devices) present(sensor, S_BINARY); } } void loop() { } void receive(const MyMessage &message) { // We only expect one type of message from controller. But we better check anyway. if (message.type==V_STATUS) { // Change relay state digitalWrite(message.sensor-1+RELAY_1, message.getBool()?RELAY_ON:RELAY_OFF); // Store state in eeprom saveState(message.sensor, message.getBool()); // Write some debug info Serial.print("Incoming change for sensor:"); Serial.print(message.sensor); Serial.print(", New status: "); Serial.println(message.getBool()); } }@MasMat Looks like the gateway's receive function is called even when the gateway is the destination of the message. That results in the gateway updating its relay even though it shouldn't.
I think you could do something like this:
if (message.type==V_STATUS) { if (message.sensor == 0) { // Only switch the relay if the message is for myself Serial.print("Updating relay state"); // Change relay state digitalWrite(message.sensor-1+RELAY_1, message.getBool()?RELAY_ON:RELAY_OFF); // Store state in eeprom saveState(message.sensor, message.getBool()); // Write some debug info } // Write some debug info Serial.print("Incoming change for sensor:"); Serial.print(message.sensor); Serial.print(", New status: "); Serial.println(message.getBool()); } -
@MasMat Looks like the gateway's receive function is called even when the gateway is the destination of the message. That results in the gateway updating its relay even though it shouldn't.
I think you could do something like this:
if (message.type==V_STATUS) { if (message.sensor == 0) { // Only switch the relay if the message is for myself Serial.print("Updating relay state"); // Change relay state digitalWrite(message.sensor-1+RELAY_1, message.getBool()?RELAY_ON:RELAY_OFF); // Store state in eeprom saveState(message.sensor, message.getBool()); // Write some debug info } // Write some debug info Serial.print("Incoming change for sensor:"); Serial.print(message.sensor); Serial.print(", New status: "); Serial.println(message.getBool()); }@mfalkvidd All this under "void loop"? Do I remove the "void receive"?
I added (and commented out previous) under "void receive": the relay became unresponsive.
debug:0;255;3;0;9;Message arrived on topic: domoticz/out/MyMQTT/0/2/1/0/2 Incoming change for sensor:2, New status: 1 0;255;3;0;9;Message arrived on topic: domoticz/out/MyMQTT/0/2/1/0/2 Incoming change for sensor:2, New status: 0 -
@gohan I did. Relay unresponsive but clearly the messages are coming thru. Went back, relay works so not mechanical/electrical.
Current code:void receive(const MyMessage &message) { if (message.type==V_STATUS) { if (message.sensor == 0) { // Only switch the relay if the message is for myself Serial.print("Updating relay state"); // Change relay state digitalWrite(message.sensor-1+RELAY_1, message.getBool()?RELAY_ON:RELAY_OFF); // Store state in eeprom saveState(message.sensor, message.getBool()); // Write some debug info } // Write some debug info Serial.print("Incoming change for sensor:"); Serial.print(message.sensor); Serial.print(", New status: "); Serial.println(message.getBool()); } -
@MasMat Looks like the gateway's receive function is called even when the gateway is the destination of the message. That results in the gateway updating its relay even though it shouldn't.
I think you could do something like this:
if (message.type==V_STATUS) { if (message.sensor == 0) { // Only switch the relay if the message is for myself Serial.print("Updating relay state"); // Change relay state digitalWrite(message.sensor-1+RELAY_1, message.getBool()?RELAY_ON:RELAY_OFF); // Store state in eeprom saveState(message.sensor, message.getBool()); // Write some debug info } // Write some debug info Serial.print("Incoming change for sensor:"); Serial.print(message.sensor); Serial.print(", New status: "); Serial.println(message.getBool()); }@mfalkvidd I've been reviewing this: I have two relays actually attached, so this code will ignore the other completely, right? I think that's why it's not working. Or the numbering for the sensors is different?
Am I wrong or does the "message.sensor" actually refer to child_id rather than node_id? Or am I following this wrong?
-
@mfalkvidd I've been reviewing this: I have two relays actually attached, so this code will ignore the other completely, right? I think that's why it's not working. Or the numbering for the sensors is different?
Am I wrong or does the "message.sensor" actually refer to child_id rather than node_id? Or am I following this wrong?
-
@MasMat I have trouble finding documentation explaining the details, but I think you are right. See if message.destination works better.
@mfalkvidd That fixed it right up and makes complete sense. I couldn't find docs either on message.sensor or message.destination...
The problem now appears more complex...
The GW (node 0) relay STILL follows the other nodes (node 4) commands (completely different circuits, so no electrical connection at all).GW debug (first a on & off test for gw-relay, then clicked the node4-relay, on comes OK (gwrelay follows) but off reboots gw)
0;255;3;0;9;Message arrived on topic: domoticz/out/MyMQTT/0/1/1/0/2 Updating relay stateIncoming change for sensor:1, New status: 1 0;255;3;0;9;Message arrived on topic: domoticz/out/MyMQTT/0/1/1/0/2 Updating relay stateIncoming change for sensor:1, New status: 0 0;255;3;0;9;TSF:MSG:READ,4-4-0,s=1,c=1,t=0,pt=7,l=5,sg=0:16.6 0;255;3;0;9;Sending message on topic: domoticz/in/MyMQTT/4/1/1/0/0 0;255;3;0;9;TSF:MSG:READ,4-4-0,s=0,c=1,t=1,pt=7,l=5,sg=0:69.8 0;255;3;0;9;Sending message on topic: domoticz/in/MyMQTT/4/0/1/0/1 0;255;3;0;9;Message arrived on topic: domoticz/out/MyMQTT/4/1/1/1/2 0;255;3;0;9;TSF:MSG:SEND,0-0-4-4,s=1,c=1,t=2,pt=0,l=1,sg=0,ft=0,st=OK:1 0;255;3;0;9;TSF:MSG:READ,4-4-0,s=1,c=1,t=2,pt=0,l=1,sg=0:1 0;255;3;0;9;TSF:MSG:ACK 0;255;3;0;9;Sending message on topic: domoticz/in/MyMQTT/4/1/1/1/2 Updating relay stateIncoming change for sensor:1, New status: 1 0;255;3;0;9;Message arrived on topic: domoticz/out/MyMQTT/4/1/1/1/2 0;255;3;0;9;!TSF:MSG:SEND,0-0-4-4,s=1,c=1,t=2,pt=0,l=1,sg=0,ft=0,st=NACK:1 0;255;3;0;9;MCO:BGN:INIT GW,CP=RNNGA--,VER=2.1.1 0;255;3;0;9;MCO:BGN:BFR``` -
Nevermind. Whined too soon.
Completely worked over the node4 code, moved "include"s around and eventually changed the relay presentations and receive clauses. Hope this helps someone with their problems later:
Thanks a millions!void before() { // Set relay pin in output mode pinMode(RELAY_1, OUTPUT); // Set relay to last known state (using eeprom storage) digitalWrite(RELAY_1, loadState(CHILD_ID_RELAY)?RELAY_ON:RELAY_OFF); } later this.... present(CHILD_ID_RELAY, S_BINARY); ....and ending with this... void receive(const MyMessage &message) { if (message.type==V_STATUS) { if (message.destination == MY_NODE_ID) { // Only switch the relay if the message is for this node Serial.print("Updating relay state"); // Change relay state digitalWrite(RELAY_1, message.getBool()?RELAY_ON:RELAY_OFF); // Store state in eeprom saveState(CHILD_ID_RELAY, message.getBool()); // Write some debug info } // Write some debug info Serial.print("Incoming change for sensor:"); Serial.print(message.sensor); Serial.print(", New status: "); Serial.println(message.getBool()); } } -
Nevermind. Whined too soon.
Completely worked over the node4 code, moved "include"s around and eventually changed the relay presentations and receive clauses. Hope this helps someone with their problems later:
Thanks a millions!void before() { // Set relay pin in output mode pinMode(RELAY_1, OUTPUT); // Set relay to last known state (using eeprom storage) digitalWrite(RELAY_1, loadState(CHILD_ID_RELAY)?RELAY_ON:RELAY_OFF); } later this.... present(CHILD_ID_RELAY, S_BINARY); ....and ending with this... void receive(const MyMessage &message) { if (message.type==V_STATUS) { if (message.destination == MY_NODE_ID) { // Only switch the relay if the message is for this node Serial.print("Updating relay state"); // Change relay state digitalWrite(RELAY_1, message.getBool()?RELAY_ON:RELAY_OFF); // Store state in eeprom saveState(CHILD_ID_RELAY, message.getBool()); // Write some debug info } // Write some debug info Serial.print("Incoming change for sensor:"); Serial.print(message.sensor); Serial.print(", New status: "); Serial.println(message.getBool()); } }@MasMat great work! Maybe change this to make the output more complete?
// Write some debug info Serial.print("Incoming change for sensor:");to
// Write some debug info Serial.print("Incoming change for node: "); Serial.print(message.destination); Serial.print(", sensor:"); -
@MasMat great work! Maybe change this to make the output more complete?
// Write some debug info Serial.print("Incoming change for sensor:");to
// Write some debug info Serial.print("Incoming change for node: "); Serial.print(message.destination); Serial.print(", sensor:");@mfalkvidd That would definitely polish it up! :D
Cheers!!