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


  • Hardware Contributor

    @parachutesj
    Could you please post your sketch?

    A wiring diagram or a picture of the node could be helpful too.



  • @FotoFieber

    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));
      }
    }
    

  • Hardware Contributor

    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


  • Hardware Contributor


Log in to reply
 

Suggested Topics

  • 1
  • 3
  • 6
  • 1
  • 5
  • 1

11
Online

11.4k
Users

11.1k
Topics

112.7k
Posts