Ethernet not connected cause lost connection IoT Cloud

Hi,

This is my equipment.

  • Portenta H7 Version 2
  • Portenta Mid Carrier
  • Portenta Pro 4G module.
  • PLC with modbus communication over Etherent.

Currently I have an issue that when the Etherent cable is unplugged or the IP is incorrect to the PLC the cellular connection of the 4G modem to the cloud is disconnected.

The mid carrier is connected to a PLC via Ethernet. The setup connects over Etherent to the PLC with Modbus TCP/IP. The data from this is send via cellular modem to the cloud and displayed on a dashboard.

If the cable is connected back in an/or the IP has been fixed. It start sending data again to the cloud. So it restores the data transmission via the modem after the Ethernet connections fixed.

To me it seems the H7 goes into a never ending loop when the Etherent connection is not operational. Probaly waiting for the Ethernet connection to be restored. This then is causing no other code to be exicuted. Including the cellular modem code.

This is used in remote areas where there is only cellular connection available to connect to the cloud.

Below is part of my code. My qeustions are the follwing;

1.) Can it be that the H7 goes into the never ending loop if the Etherent is not operation due to the cable not connected or the IP address of the server is incorrect?
2.) Can one add code or change code that keep the cellular connection to the cloud intact even if the ethenet connection is not operational? Basically prioritize the cell connection above the ethenet connection to the PLC?

any comments and suggestions are welcomed.

#include "thingProperties.h"
#include <SPI.h>
#include <PortentaEthernet.h>
#include <Ethernet.h>
#include <ArduinoRS485.h>
#include <ArduinoModbus.h>
#include "DHT.h"
#include "I2C_24LC1025.h"

I2C_24LC1025 myMem(0x50);

/************Modbus*************************/
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(192, 168, 100, 198);
EthernetClient ethClient;
ModbusTCPClient modbusTCPClient(ethClient);

IPAddress server(192, 168, 100, 9);  // Plc address

/**************DHT22 Config************************/
#define DHTPIN D0
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);

void setup() {
  
  Serial.begin(9600);
  delay(1500); 
  
  initProperties();
  ArduinoCloud.begin(ArduinoIoTPreferredConnection);
  setDebugMessageLevel(2);
  ArduinoCloud.printDebugInfo();

  Wire.begin();
  delay(1000);
  
  if(!myMem.begin()){
    Serial.println("EEPROM not found");
  } else {
    Serial.println("EEPROM good to go");
  }

  Ethernet.begin(mac, ip);

  modbusTCPClient.begin(server, 502);

  dht.begin();
  
}

void loop() {
  ArduinoCloud.update();

  if (Ethernet.linkStatus() == LinkOFF) { 
    systemMessages = "Cable not connected or damaged";
    } else { 
    if (!modbusTCPClient.connected()) { 
        systemMessages = "Attempting to reconnect Modbus...";
        delay(1000);
        Ethernet.begin(mac, ip); 
        delay(1000);
        modbusTCPClient.begin(server, 502);
      } 
    }
  

if(modbusTCPClient.connected()) {
  	doModbus();
    systemMessages = "Modbus Connected";
}
  
  doTime();
  doDHT22();
  doStatus();
  
  balesPerHour();
  balesPerDay();
  loading();
  eventLogging();
  doscaling();

}

I am not 100% sure I understand, but juggling two connections while maintaining connectivity to the cloud may be a problem. IIRC there is an API for doing that, but I don't know the name. Perusing the library you are using may reveal it, or you may need a different library. It seems like a natural thing to do, so I bet it exists.

1 Like

UDP works better when switching from one link to another. TCP is tricky with connection timeouts that makes the code wait and, possibly halt. This sketch uses TCP.

I guess there's some way to check if the TCP conn is unresponsive or a link goes down, close existing TCP conn, eventually switch to the other link, and open TCP again. Just don't ask me how to do it. :upside_down_face:

Is this what you're looking for?

Jip. I need to make sure that the TCP connection is to be second to my cellular connection to the cloud. If the cellular connection to the cloud is more importand.

So as your said there is a TCP connection to the PLC. When this connection is broken than the cellular connection to the cloud is negatively effected. What makes it worse is that once that connection to cloud is broken the OTA upload also do not work anymore and the system is dead in the water.

Lets use a common nomenclature here.

  1. Link = ethernet, mobile
  2. Connection = TCP etc.

A TCP connection works over a link, meaning a broken TCP connection cannot take down a link, but the opposite is true.

If a link goes down, the TCP connection will, since there's a timeout, be stale until the timout is passed. So check for a link lost, close the TCP connection, check if we have a working link and open up a new connection.

Ok cool I follow you. It makes sence what you say.

I will amend my code and let you know.

1 Like

Hi,

I changed my code to this and it works. The only thing is that it takes about 2 seconds to retry and the carry on excicuting my code.

if (Ethernet.linkStatus() == LinkOFF) { 
    systemMessages = "Cable not connected or damaged";
    ethClient.stop();
    } else { 
    if (!modbusTCPClient.connected()) { 
        systemMessages = "Attempting to reconnect Modbus...";
        Ethernet.begin(mac, ip); 
        modbusTCPClient.begin(server, 502);
      } else {
      	doModbus();
      systemMessages = "Modbus Connected";
      }
    }

I had a look at the Ethenet Class of the ethernet library. So I tried these functions to set my retries and time out. But I get errors when I compile.

  • Ethernet.setRetransmissionCount()
  • Ethernet.setRetransmissionTimeout()

In my setup loop. This is what I did.

  Ethernet.begin(mac, ip);
  Ethernet.setRetransmissionTimeout(10);
  Ethernet.setRetransmissionCount(3);
  modbusTCPClient.begin(server, 502);

So it compile with errors. This is the error.

/var/run/arduino/user-cache/sketches/096EF522CA3E27EE7D8409719A2E2D3E/sketch/objs.a(24EI44111_2_H25.50_ShopRite_PE_Wells_Estate_may05a.ino.cpp.o): In function `setup':
/run/arduino/sketches/24EI44111_2_H25.50_ShopRite_PE_Wells_Estate_may05a/24EI44111_2_H25.50_ShopRite_PE_Wells_Estate_may05a.ino:194: undefined reference to `arduino::EthernetClass::setRetransmissionTimeout(unsigned short)'
/run/arduino/sketches/24EI44111_2_H25.50_ShopRite_PE_Wells_Estate_may05a/24EI44111_2_H25.50_ShopRite_PE_Wells_Estate_may05a.ino:195: undefined reference to `arduino::EthernetClass::setRetransmissionCount(unsigned char)'
collect2: error: ld returned 1 exit status

Seems like its not part of the Library for the Portenta H7. But I'm not sure. I do not have extensive experience with Ethernet yet to understand if its included or not.

What is your take on the two functions that compile with errors?

That is correct. These functions are defined in the original "Ethernet" library for the WIZnet Ethernet controllers, but were never defined in the variant of the library for the Portenta H7.

This was reported to the developers of that library here:

1 Like

A delay is inevitable, but 2 seconds is quite good IMHO.

About the compilation errors, I believe that @ptillisch had a good answer on this.

Thanks Guys for the help. Its really appreaciated.