Ethernet Gateway delay issue



  • Hi All,

    I currently have a full home automation system running on pi with domoticz and use arduino based mysensor nodes as expansions.
    Some of these go through USB communication but i also have several wired up as an ethernet gateway using a big W5100 ethernet shield.
    I used the example sketch from the mysensors site and just added devices and all is working well except for one issue...

    Sometimes when i switch a relay device from domoticz its instantaneous... but other times i get the following error messages:
    2019-09-20 20:54:42.414 Status: User: Admin initiated a switch command (854/Heating Zone3/On)
    2019-09-20 20:54:43.616 Error: MySensors: Repeating previous command (2/2)
    2019-09-20 20:54:44.817 Error: MySensors: Command not received by Node !! (node_id: 0, child_id: 3)

    If you wait a few seconds to a minute it will eventually send the command succesfully and all will work but this is quite an anoying delay that shouldn't be there in my opinion... I have been looking everywhere on forums and found input to other users about baudrate and how you should lower it from 115200 in the Myconfig.h file of the mysensors library and i have tried going to 9600 and 57600 but this did no change the situation for me...
    If anybody has any idea what else i could be doing wrong please feel free to share. Or if i can find it somewhere on this forum already written and i looked over it... my sincere apologies and thanks for pointing me in the right direction!

    Kind regards
    Jasper


  • Mod

    Hi @atermentis, welcome to the forum!

    Which of the example sketches are you using? Could youpost the full sketch here?

    Are the relays wired directly to the ethernet gateway? If not, could you describe your setup? (What arduinos, what transport, how are the nodes powered)

    Does the problem happen only with the ethernet gateways, only with the usb gateways or both types?

    Turning on debug log is usually the quickest way to troubleshoot. Use the log parser to make it easier to interpret the logs.



  • Hi mfalkvidd!

    The sketch i am using is the following and is derived from the ethernet gateway and includes relays buttons and a one wire bus. I have tried excluding all different parts from the sketch so that only the relays where present to make sure that no delays or millis type of factors would cause any issues but it all remains the same and the delay i observe ocasionally is still present.

    /**
     * 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 for a "light switch" where you can control light or something 
     * else from both HA controller and a local physical button 
     * (connected between digital pin 3 and GND).
     * This node also works as a repeader for other nodes
     * 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_NRF5_ESB
    //#define MY_RADIO_RFM69
    //#define MY_RADIO_RFM95
    
    // Enable gateway ethernet module type
    #define MY_GATEWAY_W5100
    
    // 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
    
    // Enable UDP communication
    //#define MY_USE_UDP  // If using UDP you need to set MY_CONTROLLER_IP_ADDRESS below
    
    // Enable MY_IP_ADDRESS here if you want a static ip address (no DHCP)
    #define MY_IP_ADDRESS 192,168,0,165
    
    // If using static ip you can define Gateway and Subnet address as well
    //#define MY_IP_GATEWAY_ADDRESS 192,168,0,1
    //#define MY_IP_SUBNET_ADDRESS 255,255,255,0
    
    // Renewal period if using DHCP
    //#define MY_IP_RENEWAL_INTERVAL 60000
    
    // The port to keep open on node server mode / or port to contact in client mode
    #define MY_PORT 5003
    
    // Controller ip address. Enables client mode (default is "server" mode).
    // Also enable this if MY_USE_UDP is used and you want sensor data sent somewhere.
    //#define MY_CONTROLLER_IP_ADDRESS 192, 168, 178, 254
    
    // The MAC address can be anything you want but should be unique on your network.
    // Newer boards have a MAC address printed on the underside of the PCB, which you can (optionally) use.
    // Note that most of the Arduino examples use  "DEAD BEEF FEED" for the MAC address.
    #define MY_MAC_ADDRESS 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
    
    // 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 7  // Error led pin
    //#define MY_DEFAULT_RX_LED_PIN  8  // Receive led pin
    //#define MY_DEFAULT_TX_LED_PIN  9  // Transmit led pin
    
    #if defined(MY_USE_UDP)
    #include <EthernetUdp.h>
    #endif
    #include <Ethernet.h>
    #include <MySensors.h>
    #include <DallasTemperature.h>
    #include <OneWire.h>
    #include <Bounce2.h>
    
    /*DEFINITION OF TEMPSENS*/
    #define COMPARE_TEMP 1 // Send temperature only if changed? 1 = Yes 0 = No
    #define ONE_WIRE_BUS 2 // Pin where dallase sensor is connected 
    #define MAX_ATTACHED_DS18B20 16
    /*STUFF FOR TEMP */
    unsigned long MEASUREMENT_INTERVAL = 30000;       // Time to wait between reads (in milliseconds).
    OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
    DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature. 
    float lastTemperature[MAX_ATTACHED_DS18B20];
    int numSensors=0;
    bool receivedConfig = false;
    bool metric = true;
    boolean CURRENTLY_MEASURING = true;               // Used to indicate when the time is right for a new measurement to be made.
    boolean CURRENTLY_CALCULATING = false;            // Used to bridge the time that is needed to calculate the temperature values by the Dallas library.
    unsigned long CURRENT_MILLIS = 0;                 // The millisecond clock in the main loop.
    unsigned long PREVIOUS_MEASUREMENT_MILLIS = 0;    // Used to remember the time of the last temperature measurement.
    int16_t CONVERSION_TIME = 0;                      // Used to store the time needed to calculate the temperature from measurements.
    // Initialize temperature message
    MyMessage msgTEMP(0,V_TEMP);
    
    
    /*RELAY CODE*/
    #define RELAY_PIN 3  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
    #define NUMBER_OF_RELAYS 7 // 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
    
    //BUTTON CODE
    #define CHILD_ID_B1 10
    #define BUTTON_PIN1  14  // Arduino Digital I/O pin for button/reed switch
    #define CHILD_ID_B2 11
    #define BUTTON_PIN2  15  // Arduino Digital I/O pin for button/reed switch
    #define CHILD_ID_B3 12
    #define BUTTON_PIN3  16  // Arduino Digital I/O pin for button/reed switch
    
    Bounce debouncerB1 = Bounce(); 
    Bounce debouncerB2 = Bounce(); 
    Bounce debouncerB3 = Bounce(); 
    int oldValueB1=-1;
    int oldValueB2=-1;
    int oldValueB3=-1;
    // Change to V_LIGHT if you use S_LIGHT in presentation below
    MyMessage msgBUTTON1(CHILD_ID_B1,V_LIGHT);
    MyMessage msgBUTTON2(CHILD_ID_B2,V_LIGHT);
    MyMessage msgBUTTON3(CHILD_ID_B3,V_LIGHT);
    
    void before()
    {
        for (int sensor=1, pin=RELAY_PIN; 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+20)?RELAY_ON:RELAY_OFF);
        }
        // Startup up the OneWire library
      sensors.begin();
    }
    
    
    void setup()
    {
      for(int i=0;i<MAX_ATTACHED_DS18B20;i++){lastTemperature[i] = 0;} //Pre-filling array with 0's.
      sensors.setWaitForConversion(false);  // requestTemperatures() will not block current thread
      
     // Setup the button
      pinMode(BUTTON_PIN1,INPUT);
      pinMode(BUTTON_PIN2,INPUT);
      pinMode(BUTTON_PIN3,INPUT);
      // Activate internal pull-up
      digitalWrite(BUTTON_PIN1,HIGH);
      digitalWrite(BUTTON_PIN2,HIGH);
      digitalWrite(BUTTON_PIN3,HIGH);
    
      // After setting up the button, setup debouncer
      debouncerB1.attach(BUTTON_PIN1);
      debouncerB2.attach(BUTTON_PIN2);
      debouncerB3.attach(BUTTON_PIN3);
      debouncerB1.interval(5);
      debouncerB2.interval(5);
      debouncerB3.interval(5);
    }
    
    void presentation()
    {
        // Send the sketch version information to the gateway and Controller
      sendSketchInfo("Mysensors Garage", "1");
       
       // Fetch the number of attached temperature sensors  
      numSensors = sensors.getDeviceCount();
    
      // Present all sensors to controller
      for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {   
         present(i, S_TEMP);
      }
    
    for (int sensor=1, pin=RELAY_PIN; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
            // Register all sensors to gw (they will be created as child devices)
            present(sensor+20, S_BINARY);
        }
    
        // Register binary input sensor to gw (they will be created as child devices)
      // You can use S_DOOR, S_MOTION or S_LIGHT here depending on your usage. 
      // If S_LIGHT is used, remember to update variable type you send in. See "msg" above.
      present(CHILD_ID_B1, S_LIGHT);  
      present(CHILD_ID_B2, S_LIGHT);
      present(CHILD_ID_B3, S_LIGHT);
    }
    
    void loop()
    {
     debouncerB1.update();
      // Get the update value
      int valueB1 = debouncerB1.read();
    
      if (valueB1 != oldValueB1) {
         // Send in the new value
         send(msgBUTTON1.set(valueB1==HIGH ? 1 : 0));
         oldValueB1 = valueB1;
      }
      debouncerB2.update();
      // Get the update value
      int valueB2 = debouncerB2.read();
    
      if (valueB2 != oldValueB2) {
         // Send in the new value
         send(msgBUTTON2.set(valueB2==HIGH ? 1 : 0));
         oldValueB2 = valueB2;
      }
      debouncerB3.update();
      // Get the update value
      int valueB3 = debouncerB3.read();
    
      if (valueB3 != oldValueB3) {
         // Send in the new value
         send(msgBUTTON3.set(valueB3==HIGH ? 1 : 0));
         oldValueB3 = valueB3;
    }
    
    CURRENT_MILLIS = millis(); // The time since the sensor started, counted in milliseconds. This script tries to avoid using the Sleep function, so that it could at the same time be a MySensors repeater.
    
    // Let's measure the temperature
      if(CURRENTLY_MEASURING == true && CURRENT_MILLIS - PREVIOUS_MEASUREMENT_MILLIS >= MEASUREMENT_INTERVAL){ // If we'e not calculating, and enough time has passed, we'll start again.
        CURRENTLY_MEASURING == false; // We're measuring, so let's take it off our to-do list.
        Serial.print("Starting new measurement(s)\n");
        PREVIOUS_MEASUREMENT_MILLIS = CURRENT_MILLIS; // Mark the time of the initialiation of this measurement.
        
      // Fetch temperatures from Dallas sensors
      sensors.requestTemperatures();
    
       // query conversion time. Apparently it takes a while to calculate?
        CONVERSION_TIME = sensors.millisToWaitForConversion(sensors.getResolution());
    
        CURRENTLY_CALCULATING = true; //Next step is to re-calculate the temperature again.
      }
    
    
      // Let's calculate and send the temperature
      if(CURRENTLY_CALCULATING == true && CURRENT_MILLIS > PREVIOUS_MEASUREMENT_MILLIS + CONVERSION_TIME ){
        CURRENTLY_CALCULATING = false; // check calculating off the to-do list too.
        for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {    // Loop through all the attached temperatur sensors.
        
          float temperature = static_cast<float>(static_cast<int>((getControllerConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.;   // Fetch and round temperature to one decimal
          
          Serial.print("Sensor #");
          Serial.print(i);
          Serial.print(" says it is ");
          Serial.print(temperature);
          Serial.print(" degrees\n");
          
          if(temperature != -127.00 && temperature != 85.00){ // avoid working with measurement errors.
            if (COMPARE_TEMP == 1 && lastTemperature[i] == temperature){
              Serial.print("Not sending it though, because it's the same temperature as before.\n");
            }
            else
            {
              Serial.print("Sending the temperature to the gateway.\n");
              send(msgTEMP.setSensor(i).set(temperature,1));
              lastTemperature[i] = temperature; // Save new temperatures to be able to compare in the next round.
            }
          }  
        }
        CURRENTLY_MEASURING = true; // Both tasks are done. Now we'll just wait for the measurement interval to be over.
      }
    }
    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-21+RELAY_PIN, 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());
        }
    }
    

    All the relays are wired directly to the arduino uno which also has the ethernet shield installed on top of it. Both arduino, ethernet board and relay board are powered through an external DIN rail power supply providing 5V at 0.88A. I also have another ethernet gateway showing the same issues that is powered by a 12V psu feeding into a buck boost converter that supplies everything with 5V at 3A. Would you recommend setting this up differently?

    Both gateways are interfaced over ethernet where one has a 3m long cable and the other around 20m of cables. So cable length didn't seem like the issue to me.

    The issue only occurs on the ethernet gateways and not on the usb... i have had the gateway connected to the pc to view the changes coming in live from the serial monitor and there i also see nothing coming in when domotics displays the error and after a few seconds to minutes when the relay does switch i see the command arrive. So i don't think the gateway itself or the code is doing something wrong but for some reason between the command being sent from domoticz to it arriving at the gateway it gets lost?? and when domoticz repeats the command then sometimes it does come through???

    Ethernet lines are connected through a gigabit ethernet switch...

    Thank you already for all the help!


  • Mod

    @atermentis I noticed the sketch has the ”demo” DEADBEEFFEED mac address. Do all sketches have the same address?

    All mac addresses on a ethernet network must be unique. If they are not unique, strange communication problems will occur.


 

175
Online

8.8k
Users

9.6k
Topics

100.3k
Posts