I’m developing a sensor that uses a Cerberus and ENC26 as it’s core that a PLC or PC can communicate with via ModbusTCP. Everything seemed to be working fine until I started having issues with the sensor becoming unresponsive after a day or two of running with the PLC taking readings. And when I mean unresponsive I mean that the Cerberus won’t even respond to a ICMP! This does not happen even after a week of running with a PC taking readings. So I fired up Wireshark to see what was happening.
My first test was to see what the PLC to a PC packet exchange looked like. I wrote a Win7 app that used the core “server” code that’s running in the Cerberus. In the attached image PLCToPCWireshark.jpg you can see a smooth exchange between the two devices. The PLC address is 34.34.34.23 and the PC address is 34.34.34.45. This configuration runs for days without issue.
The second test was to see what the PLC to one of the Cerberus sensors packet exchange looked like. You can see this in the attached image PLCToSensorWireshark.jpg.
PLC address is 34.34.34.23 and the Cerberus address is 34.34.34.134.
As you can see there is a difference in the packets as the Cerberus sensor has extra packets that it sends back to the PLC where the PC doesn’t.
So the question is, could these extra packets from the Cerberus cause the Cerberus communications to lock up? I’ve tried setting the DontLinger, Linger, KeepAlive, socket options on the Cerberus and nothing effects the outcome. One might be lead to believe that the PLC is the problem, but when it talks to the PC app after an extended period of time it keeps humming along.
12/22/2013 - Update.
In my continued testing I’ve found that even a PC after running for a week communicating with the Cerberus sensor will also result in the sensor locking up completely to the point it won’t even respond to an ICMP. So there is something going on with the ENC/NETMF stack or something. The only way to get the Cerberus back online is to cycle power on the unit. This is the code for the server:
Setup the listening socket:
tcpPort502ServerSocket = new Socket( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp );
tcpPort502LocalEndPoint = new IPEndPoint( IPAddress.Any, 502 );
tcpPort502ServerSocket.Bind( tcpPort502LocalEndPoint );
tcpPort502ServerSocket.Listen( 2 );
tcpPort502ListeningThread = new Thread( WaitForPort502Connections );
tcpPort502ListeningThread.Start();
Listening Thread:
private void WaitForPort502Connections()
{
while ( true )
{
Socket clientSocket = tcpPort502ServerSocket.Accept();
ProcessPort502ClientRequest( clientSocket );
clientSocket.Close();
clientSocket = null;
}
}