Arduino Modbus TCP/IP Client with Siemens PAC2200 as Server

Hello everybody.

I'm trying to connect an Arduino Uno with a W5100 shield with a SIEMENS PAC2200 (a flowmeter device) which works in MODBUS TCP/IP.

I'm using also the example of ArduinoModbus library (Ethernet Modbus TCP Client Toggle), but trying to read the correct data I need (the first one, for example):

In theory I'm corretly connected to the device (the serial shows the message Modbus TCP Client connected), but when I try to read the data from the PAC2200, the value of modbusTCPClient.requestFrom(0x00,0x04,0x01,0x02) is always "0".

If anyone could give me a clue about what is going on, I will be very grateful.

Enclosed I include the code:

#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};  // MAC de la tarjeta W5100 que es genérica
IPAddress ip(192, 168, 1, 47);                      // IP de la tarjeta W5100 que es la cliente


EthernetClient ethClient;                           //Strating client

ModbusTCPClient modbusTCPClient(ethClient); 
IPAddress server(192, 168, 1, 100); // update with the IP Address of your Modbus server

float Total_kWh_Pos0;
float Total_kWh_Pos1;


void setup() {

//Initialize serial and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
  }

  Serial.println("Inicio setup");
  pinMode(4, OUTPUT);
digitalWrite(4, HIGH);                      // To disable slave select for SD card; depricated.

// Starting shield Ethernet
  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
    }
  }
  
// Check if cable is onnected  
  if (Ethernet.linkStatus() == LinkOFF) {
    Serial.println("Ethernet cable is not connected.");
  }


// Check if server is connected
  if (!modbusTCPClient.connected()) {
    // client not connected, start the Modbus TCP client
    Serial.println("Attempting to connect to Modbus TCP server");
    
    if (!modbusTCPClient.begin(server, 502)) {
      Serial.println("Modbus TCP Client failed to connect!");
    } else {
      Serial.println("Modbus TCP Client connected");
    }
  } 
  
}

void loop() {


Serial.println("Starting the reading");

delay(1000);


Serial.println(modbusTCPClient.requestFrom(0x00,0x04,0x13,0x02) );


Total_kWh_Pos0 = modbusTCPClient.read();
Total_kWh_Pos1 = modbusTCPClient.read();


Serial.println(Total_kWh_Pos0);
Serial.println(Total_kWh_Pos1);

    
// wait for 3 second
delay(3000);
  
}escribe o pega el código aquí

That library is built for the MKR series of Arduinos. As it's rather wasteful with RAM it won't run reliably on AVR Arduinos (as the UNO). I strongly recommend to switch to another library more optimized for memory.

Type 4 isn't defined. There's a reason why you should use the symbolic names for such constants. The error is probably set to EINVAL but your code doesn't check that.

Hello, pylon.
Thank you very much for your quick reply.

I'm using this library because I don't know any other. According to your reply I need to investigate a bit more about different TCP libraries.

I don't understand what do you mean:

According to the documentation (or what I have understood), the line: modbusTCPClient.requestFrom(0x00,0x04,0x01,0x02) should include 0x00 as node (0x00 is by default), 0x04 is the Modbus mode, 0x01 the offset and 0x02 the number od records. I have tried removing the "0x" but the resut is the same.....

I need to investigate also how to check the EINVAL error.

Again, thank you very much for your reply and I will keep investigating

I quote the documentation in the .h file:

  /**
   * Read multiple coils, discrete inputs, holding registers, or input 
   * register values.
   *
   * Use available() and read() to process the read values.
   *
   * @param id (slave) id of target, defaults to 0x00 if not specified
   * @param type type of read to perform, either COILS, DISCRETE_INPUTS, 
   *             HOLDING_REGISTERS, or INPUT_REGISTERS
   * @param address start address to use for operation
   * @param nb number of values to read
   *
   * @return 0 on failure, number of values read on success
   */
  int requestFrom(int type, int address, int nb);
  int requestFrom(int id, int type, int address,int nb);

The slave ID is irrelevant for Modbus TCP but type must be one of the listed options.

Thanks a lot.

I have tryed all possible combinations (0,4,1,2). In some places I have seen 0x0? numbers... but no one is working. Probably the problem is the memory.
As you have proposed, I'm focusing in other llibrary for my project, but it is being quite difficult.

Maybe anyone could propose any library for my arduino Uno....

Have a good day

Hello again.

I have found the way to read data from the Sentron PAC with a Arduino Uno and the W5100 shield.
For that, I have found another MODBUS TCP/IP library from goddland16 in github, and with some clever instructions from Mr. Emelianov, all runs smooth. Enclosed I send all necessary to run it:

Sentron PAC.zip (3,2 MB)

Have a good day.

1 Like

hope this video lecture and code in the description may help you

Thanks a lot.

I will try it.

Have a very good day.

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