Mega2560 Modbus server from 1756-L81E

Hi all.

I can get MODbus data to the PLC from the mega but I can't get the mega to act as a server. I'm using the Arduino library.

PLC is using raC_Opr_NetModbusTCPClient_Rung.L5X from Rockwell.

Client_01_Parameters.LocalSlot == 0
Client_01_Parameters.LocalAddress == Null
Client_01_Parameters.DestAddress == 192.168.2.8
Client_01_Parameters.DestinationPort == 502
Client_01_Data.Coils_0xxx[0] (On for 1 second, off for 1 second)

All of the above settings work with the mega as the client. PLC client AOI has a different port specified and is disabled to avoid conflicts. AOI shows enabled and connected on its side. Disconnecting the mega ethernet faults the AOI and clears when reconnected.

Serial.println(client); returns "0"

I'm going to keep fiddling with parameters but I'm hoping someone has an idea.

Thanks.

/*
  Ethernet Modbus TCP Server LED

  This sketch creates a Modbus TCP Server with a simulated coil.
  The value of the simulated coil is set on the LED

  Circuit:
   - Any Arduino MKR Board
   - MKR ETH Shield

  created 16 July 2018
  by Sandeep Mistry
*/

#include <SPI.h>
#include <Ethernet.h>

#include <ArduinoRS485.h> // ArduinoModbus depends on the ArduinoRS485 library
#include <ArduinoModbus.h>

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
// The IP address will be dependent on your local network:
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(192, 168, 2, 8);

EthernetServer ethServer(502);

ModbusTCPServer modbusTCPServer;

// const int ledPin = LED_BUILTIN;
const int ledPin = 53;

void setup() {
  // You can use Ethernet.init(pin) to configure the CS pin
  //Ethernet.init(10);  // Most Arduino shields
  //Ethernet.init(5);   // MKR ETH shield
  //Ethernet.init(0);   // Teensy 2.0
  //Ethernet.init(20);  // Teensy++ 2.0
  //Ethernet.init(15);  // ESP8266 with Adafruit Featherwing Ethernet
  //Ethernet.init(33);  // ESP32 with Adafruit Featherwing Ethernet

  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  Serial.println("Ethernet Modbus TCP Example");

  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);

  // Check for Ethernet hardware present
  if (Ethernet.hardwareStatus() == EthernetNoHardware) {
    Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
    while (true) {
      delay(1); // do nothing, no point running without Ethernet hardware
    }
  }
  if (Ethernet.linkStatus() == LinkOFF) {
    Serial.println("Ethernet cable is not connected.");
  }

  // start the server
  ethServer.begin();
  Serial.println("started server");
  
  // start the Modbus TCP server
  if (!modbusTCPServer.begin()) {
    Serial.println("Failed to start Modbus TCP Server!");
    while (1);
  }
  Serial.println("started modbus server");
  // configure the LED
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);

  // configure a single coil at address 0x00
  modbusTCPServer.configureCoils(0x00, 1);
}

void loop() {
  // listen for incoming clients
  EthernetClient client = ethServer.available();
  Serial.println(client);
  
  if (client) {
    // a new client connected
    Serial.println("new client");

    // let the Modbus TCP accept the connection 
    modbusTCPServer.accept(client);

    while (client.connected()) {
      // poll for Modbus TCP requests, while client connected
      modbusTCPServer.poll();

      // update the LED
      updateLED();
    }

    Serial.println("client disconnected");
  }
}

void updateLED() {
  // read the current value of the coil
  int coilValue = modbusTCPServer.coilRead(0x00);

  if (coilValue) {
    // coil value set, turn LED on
    digitalWrite(ledPin, HIGH);
  } else {
    // coild value clear, turn LED off
    digitalWrite(ledPin, LOW);
  }
}

That library is designed for the MKR series of Arduinos. You shouldn't use it on AVR Arduinos because it's quite wasteful with memory (RAM).

Nevertheless that small setup should work (at least for some time) as it's mostly the example of the library.
Consult the manual of your PLC to find the error on that side (you didn't post the manual so we cannot help there).

"Consult the manual of your PLC to find the error on that side"

The only time the PLC faults is if I disconnect the mega from the network

That means you simply ignore the possibility that the PLC implementation might be wrong? My experience is that most PLC implementations of the Modbus standard are wrong in one or another way.

Use WireShark to sniff the network and post the the packets of at least two requests. Without such information we have no chance to see what exactly the PLC does as you probably have no access to it's source code.

I answered your specific question. I never said, nor implied the PLC couldn't be the issue. I'd like you to not assume what I might be thinking please. I even said I was going to continue to continue fiddling with parameters which should indicate to you I haven't stopped working on the PLC side.

I tried to shark the data but it's using a unicast connection and I'm working on turning off IGMP in the switch. More data to follow.

I didn't ask a question about when your PLC goes into error state. But if you say that the only error on the PLC side is if you disconnect the Mega, I must assume that you think the PLC does everything right if it doesn't show an error. As I wrote, my experience is that most PLC Modbus implementations are broken in some way. If the manual doesn't tell you in what way it's broken (we don't have the manual) you must sniff the network to find out yourself.

IGMP is for multicast traffic so that wouldn't help here. Turn on port mirroring on your switch to be able to see everything that's passing the switch.

It seems that Rockwell only allows MODbus connections to other AB products or devices that use its specific standard. I'm giving up and trying to use TCP connections.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.