node disconnects - workaround?
-
Hi,
I have one node (controlls a roller shutter) which keeps disconnecting or is unavailable.As controller I use openHAB - but don't think that this is important.
My node with two relays should have enough power, changed the power supply and radio connection should also be ok. I even switched the arduino which did not solve it.Issue:
OpenHAB controls it, up in the morning, down in the evening. Works most of the time. Sometimes after one day, somtimes after a week I can see in the log that the message failed.
When I press the physical up or down buttons on the node to control the rollershutter, it "reconnects" to the gateway and can be controlled as before until it fails again.When I power cycle the node, it is also back to live. When I initiate a connection via physical buttons, it is always working and gets the connection - so I think the uplink direction is fine and radio communication in general should be ok.
However on the downlink side it fails from time to time and does not get back to live - only after a uplink was initialized.
Do we have a solution here? Can I test a connection several times a day e.g?
A workaround could be attaching a temp sensor and just transmitt every 10-20 mins and I guess it should be fine but not really the solution to the RC.I am on 2.0x with my nodes and GW.
Thanks
Cheers,
SJ
-
@parachutesj
Could you please post your sketch?A wiring diagram or a picture of the node could be helpful too.
-
see my sketch below.
Don't have a wiring diagram. However it is simply a relay module connected to the digital pins and some physical switches with each a resistor on +5V/** The MySensors Arduino library handles the wireless radio link and protocol between your home built sensors/actuators and HA controller of choice. The sensors forms a self healing radio network with optional repeaters. Each repeater and gateway builds a routing tables in EEPROM which keeps track of the network topology allowing messages to be routed to nodes. Created by Henrik Ekblad <henrik.ekblad@mysensors.org> Copyright (C) 2013-2015 Sensnology AB Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors Documentation: http://www.mysensors.org Support Forum: http://forum.mysensors.org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. ******************************* REVISION HISTORY Version 1.0 - Henrik Ekblad DESCRIPTION Example sketch showing how to control physical relays. This example will remember relay state after power failure. http://www.mysensors.org/build/relay */ // Enable debug prints to serial monitor #define MY_DEBUG // Enable and select radio type attached #define MY_RADIO_NRF24 //#define MY_RADIO_RFM69 // Enable repeater functionality for this node #define MY_REPEATER_FEATURE #include <MySensors.h> #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 1 // GPIO value to write to turn on attached relay #define RELAY_OFF 0 // GPIO value to write to turn off attached relay MyMessage sensorMsg0(0, V_DIMMER); MyMessage sensorMsg1(1, V_DIMMER); static int currentLevel0 = 0; // Current dim level... static int currentLevel1 = 0; // Current dim level... int upPin0 = 14; // choose the input pin (for a up) int downPin0 = 15; // choose the input pin (for a down) int motorUp0 = 0; // variable for reading the pin status int motorDown0 = 0; // variable for reading the pin status int upPin1 = 15; // choose the input pin (for a up) int downPin1 = 16; // choose the input pin (for a down) int motorUp1 = 0; // variable for reading the pin status int motorDown1 = 0; // variable for reading the pin status int switchState0 = 0; //0=off, 1=up, 2=down int tempSwitchState0 = 0; //0=off, 1=up, 2=down int rUnitPos0 = 0; int switchState1 = 0; //0=off, 1=up, 2=down int tempSwitchState1 = 0; //0=off, 1=up, 2=down int rUnitPos1 = 0; void shuttersUp(int shutter) { if (shutter == 0) { Serial.println("A Shutter 0 going up."); digitalWrite (RELAY_1 + 1, LOW); delay(100); digitalWrite (RELAY_1, HIGH); send( sensorMsg0.set(0) ); } else { Serial.println("A Shutter 1 going up."); digitalWrite (RELAY_1 + 3, LOW); delay(100); digitalWrite (RELAY_1 + 2, HIGH); send( sensorMsg1.set(0) ); } } void shuttersDown(int shutter) { if (shutter == 0) { Serial.println("A Shutter 0 going down."); digitalWrite (RELAY_1, LOW); delay(100); digitalWrite (RELAY_1 + 1, HIGH); send( sensorMsg0.set(100) ); } else { Serial.println("A Shutter 1 going down."); digitalWrite (RELAY_1 + 2, LOW); delay(100); digitalWrite (RELAY_1 + 3, HIGH); send( sensorMsg1.set(100) ); } } void shuttersStop(int shutter) { if (shutter == 0) { Serial.println("A Shutter 0 halted."); digitalWrite (RELAY_1, LOW); digitalWrite (RELAY_1 + 1, LOW); } else { Serial.println("A Shutter 1 halted."); digitalWrite (RELAY_1 + 2, LOW); digitalWrite (RELAY_1 + 3, LOW); } } void setup() { } void presentation() { // Send the sketch version information to the gateway and Controller sendSketchInfo("RollerShutter AZ", "2.1"); pinMode(upPin0, INPUT); // declare pushbutton as input pinMode(downPin0, INPUT); // declare pushbutton as input // Fetch relay status 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_COVER); // Then set relay pins in output mode pinMode(pin, OUTPUT); // Set relay to last known state (using eeprom storage) digitalWrite(pin, LOW); } } void loop() { motorUp0 = digitalRead(upPin0); // read input value motorDown0 = digitalRead(downPin0); // read input value if (motorUp0 == LOW && motorDown0 == HIGH) { switchState0 = 1; //Serial.println("SWITCH: " + String(switchState0)); //Schalterposition } else if (motorDown0 == LOW && motorUp0 == HIGH) { switchState0 = 2; //Serial.println("SWITCH: " + String(switchState0)); //Schalterposition } else if (motorDown0 == HIGH && motorUp0 == HIGH) { switchState0 = 0; //Serial.println("SWITCH: " + String(switchState0)); //Schalterposition } if (tempSwitchState0 != switchState0) //man only needed in case of changed switch state { if (motorUp0 == LOW && rUnitPos0 != 1) //manuell hoch { switchState0 = 1; tempSwitchState0 = 1; delay(200); shuttersUp(0); rUnitPos0 = 1; Serial.println("//////////////man 0 hoch"); send( sensorMsg0.set(0) ); } if (motorDown0 == LOW && rUnitPos0 != 2) // manuell runter { switchState0 = 2; tempSwitchState0 = 2; delay(200); shuttersDown(0); rUnitPos0 = 2; Serial.println("//////////////man 0 down"); send( sensorMsg0.set(100) ); } if (motorUp0 == HIGH && motorDown0 == HIGH && rUnitPos0 != 0) //manuell stopp { switchState0 = 0; tempSwitchState0 = 0; delay(200); shuttersStop(0); rUnitPos0 = 0; Serial.println("//////////////man 0 stopp"); } } } void receive(const MyMessage &message) { // Let's check for the message type. if (message.type == V_DIMMER) { // Retrieve the power or dim level from the incoming request message int requestedLevel = atoi( message.data ); // Adjust incoming level if this is a V_LIGHT variable update [0 == off, 1 == on] requestedLevel *= ( message.type == V_LIGHT ? 100 : 1 ); // Clip incoming level to valid range of 0 to 100 requestedLevel = requestedLevel > 100 ? 100 : requestedLevel; requestedLevel = requestedLevel < 0 ? 0 : requestedLevel; Serial.print( "Changing level to " ); Serial.print( requestedLevel ); Serial.print( ", from " ); Serial.println("NodeID:" + String(message.sensor) + " " + currentLevel0 ); if (requestedLevel == 0) { // move up shuttersUp(message.sensor); } else if (requestedLevel == 100) { // move down shuttersDown(message.sensor); } else { // move percentage // Serial.println("currentLevel" + String(shutters.currentLevel())); Serial.println("move to desired postion"); //shutters.requestLevel(80); } currentLevel0 = requestedLevel; } else if (message.type == V_UP) { shuttersUp(message.sensor); Serial.println("going up:" + String(message.type)); } else if (message.type == V_DOWN) { shuttersDown(message.sensor); Serial.println("going down:" + String(message.type)); } else if (message.type == V_STOP) { shuttersStop(message.sensor); Serial.println("stopping:" + String(message.type)); } else { Serial.println("wrong data received:" + String(message.type)); } }
-
Try to replace all "delay" with "wait", as the node is not responsible, when you are in a delay.
Try to add a watchdog:
- add a a wdt_enable(WDTO_8S) in setup
- add a wdt_reset() at the start of the loop
I had several problems with relays and power spikes when they are switched. I changed them all to SSRs and the problems are gone.
Good luck
Markus
-
@FotoFieber
Thank you for your reply. I know delay is not optimal but there is not so much interaction that this would or should cause the node to hang. And if it hangs, also an additional comand later on sent via webinterface etc. fails. So if it would send a failing comand while it is busy with the delay I would understand but it will not come back to live at all.
The reason is avoiding power on both motor directions (up & down) for the same time as relays are slow.
However I will try a "wait" instead.Watchdog: I thought about that before but as mentioned when I press the manual up/down button it comes back to live. If the sketch would be blocked and resolved by a watchdog, I would expect different behaviour.
The power consumption related to classical relays might be influencing something - that is a chance. I have a bunch of SSRs laying around but was too lazy to build up something yet. Too many other unfinished projects in the pipeline...
But back to my original thought: is there a function which would test a connection to the gateway which could be triggered manually?
Thank you again
SJ
-
You can send heartbeats:
https://forum.mysensors.org/topic/2267/ping-function/3