Go Down

Topic: Modbus TCP Client - Read and Write Holding Regsiters (Read 206 times) previous topic - next topic

Arickzon93

Hello,
i need your help. I have a Controllino MAXI (Arduino Mega based Industrial PLC) PinOut and i need to create a Modbus TCP communication with a Robot (AGV) to control the Top Module i created.
The Controllino has to be the Client, because the Robot is the Server (fixed in the Software).

First of all i creat a Ethernet connection wich is running quite good.

The fixed IP of the Robot is 192.168.12.20 (111.png)
The IP of the Controllino is 192.168.12.251 (222.png)

I´m connected via WiFi to the Robot and can Ping the Robot and the Controllino, furthermore the Sketch gives me a failure if the Client can´t connect.
Code: [Select]
void setup() {
 
// Open serial communications and wait for port to open:
  Serial.begin(9600);
  // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    // try to congifure using IP address instead of DHCP:
    Ethernet.begin(mac, ip);
  }

  Serial.print("Controllino (Client) IP address: ");
  Serial.println(Ethernet.localIP());
 
  Serial.println();
 
  Serial.print("MiR (Server) IP address: ");
  Serial.println("192.168.12.20");

  Serial.println();
  // give the Ethernet shield a second to initialize:
  delay(1000);
  Serial.println("Client connecting to Server...");
 
  client.connect(server, 502);

  // if you get a connection, report back via serial:

   if (client.connect(server, 502))
   {
     Serial.println("connected");     
   }
   else
   {
     Serial.println("connection failed");
   };
}


The result on the Serial monitor is:

Controllino (Client) IP address: 192.168.12.251

MiR (Server) IP address: 192.168.12.20

Client connecting to Server...
connected

This shows me that the Ethernet communication between this 2 devices is available.

Now my main problem:

I need to Read and Write holding registers. I try to use the ArduinoModbus.h lib, but i can´t get any result..
ArduinoModbus.h

This is the Sketch i have at the moment
Code: [Select]
/*Modbus TCP Sketch for Client/Server communication between
 * Controllino (Client) and MiR (Server)
 */

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

#include "ModbusClient.h"
#include "ModbusTCPClient.h"

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

// use the numeric IP instead of the name for the server:
byte server[] = { 192,168,12,20 };    // MiR

// Set the static IP address to use if the DHCP fails to assign
IPAddress ip(192,168,12,30);

// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):

EthernetClient client;



 

void setup() {
 
// Open serial communications and wait for port to open:
  Serial.begin(9600);
  // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    // try to congifure using IP address instead of DHCP:
    Ethernet.begin(mac, ip);
  }

  Serial.print("Controllino (Client) IP address: ");
  Serial.println(Ethernet.localIP());
 
  Serial.println();
 
  Serial.print("MiR (Server) IP address: ");
  Serial.println("192.168.12.20");

  Serial.println();
  // give the Ethernet shield a second to initialize:
  delay(1000);
  Serial.println("Client connecting to Server...");
 
  client.connect(server, 502);

  // if you get a connection, report back via serial:

   if (client.connect(server, 502))
   {
     Serial.println("connected");     
   }
   else
   {
     Serial.println("connection failed");
   };
}

void loop()
{
 
  delay(1000);


  // if the server's disconnected, stop the client:
  if (!client.connected()) {
    Serial.println();
    Serial.println("trennen.");
    client.stop();

    // do nothing forevermore:
    while(true);
  }
}


Picture (555.png) shows the PLC Regsiters on the Robot (Server). This PLC regsiters are fixed to the Modbus adress on the right side.

I now that this Server registers work because i did a simulation with a ModbusMasterprogram and Read and write the shown registers.

Everything i need to know at the moment is: How can i use the Modbus TCP lib to read and write holding registers?

It seems like the ModbusTCPClient class from the Modbus lib doesn´t work.

Can someone help me please?

Notice: i started Arduino 1 Week ago after i did the Java programming 5 years ago^^ so please don´t judge me.



Juraj

Code: [Select]
#include <Ethernet.h>

const int MODBUS_CONNECT_ERROR = -10;
const int MODBUS_NO_RESPONSE = -11;

const byte FNC_READ_REGS = 0x03;
const byte FNC_WRITE_SINGLE = 0x06;
const byte FNC_ERR_FLAG = 0x80;

const byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

const int ETH_CS_PIN = 10;

const IPAddress isgAddress(192, 168, 1, 7);

void setup() {
  Serial.begin(115200);

  Ethernet.init(ETH_CS_PIN);
  Serial.println("Initialize Ethernet with DHCP:");
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    if (Ethernet.linkStatus() == LinkOFF) {
      Serial.println("Ethernet cable is not connected.");
    }
    while (true) {
      delay(1); // do nothing, no point running without Ethernet
    }
  } else {
    Serial.print("  DHCP assigned IP ");
    Serial.println(Ethernet.localIP());
  }

  EthernetClient client;

  if (client.connect(isgAddress, 502)) {

    client.setTimeout(2000);

    Serial.println(F("client connected"));
    int res = tests(client);
    Serial.println();
    if (res != 0) {
      Serial.print("modbus error ");
      Serial.println(res);
    }
    client.stop();
  } else {
    Serial.println("connection failed");
  }
}

int tests(Client& client) {


  short regs[16];
  int res = modbusRequest(client, 240, 40076, 16, regs);
  if (res != 0)
    return res;
  int voltage = regs[3] * pow(10, regs[8]); // ac voltage F3 * scale
  Serial.println(voltage);

  res = modbusWriteSingle(client, 40303 + 12, 50 * 100);
  if (res != 0)
    return res;

  return 0;
}

void loop() {
}

/*
 * return
 *   - 0 is success
 *   - negative is comm error
 *   - positive value is client protocol exception code
 */
int modbusRequest(Client& client, byte uid, unsigned int addr, byte len, short *regs) {

  const byte CODE_IX = 7;
  const byte ERR_CODE_IX = 8;
  const byte LENGTH_IX = 8;
  const byte DATA_IX = 9;

  byte request[] = {0, 1, 0, 0, 0, 6, uid, FNC_READ_REGS, (byte) (addr / 256), (byte) (addr % 256), 0, len};
  client.write(request, sizeof(request));

  int respDataLen = len * 2;
  byte response[max((int) DATA_IX, respDataLen)];
  int readLen = client.readBytes(response, DATA_IX);
  if (readLen < DATA_IX) {
    client.stop();
    return MODBUS_NO_RESPONSE;
  }
  switch (response[CODE_IX]) {
    case FNC_READ_REGS:
      break;
    case (FNC_ERR_FLAG | FNC_READ_REGS):
      return response[ERR_CODE_IX]; // 0x01, 0x02, 0x03 or 0x11
    default:
      return -3;
  }
  if (response[LENGTH_IX] != respDataLen)
    return -2;
  readLen = client.readBytes(response, respDataLen);
  if (readLen < respDataLen)
    return -4;
  for (int i = 0, j = 0; i < len; i++, j += 2) {
    regs[i] = response[j] * 256 + response[j + 1];
  }
  return 0;
}

int modbusWriteSingle(Client& modbus, unsigned int address, int val) {

  const byte CODE_IX = 7;
  const byte ERR_CODE_IX = 8;
  const byte RESPONSE_LENGTH = 9;

  byte req[] = { 0, 1, 0, 0, 0, 6, 1, FNC_WRITE_SINGLE, // header
        (byte) (address / 256), (byte) (address % 256),
        (byte) (val / 256), (byte) (val % 256)};

  modbus.write(req, sizeof(req));

  byte response[RESPONSE_LENGTH];
  int readLen = modbus.readBytes(response, RESPONSE_LENGTH);
  if (readLen < RESPONSE_LENGTH) {
    modbus.stop();
    return MODBUS_NO_RESPONSE;
  }
  switch (response[CODE_IX]) {
    case FNC_WRITE_SINGLE:
      break;
    case (FNC_ERR_FLAG | FNC_WRITE_SINGLE):
      return response[ERR_CODE_IX]; // 0x01, 0x02, 0x03, 0x04 or 0x11
    default:
      return -3;
  }
  while (modbus.read() != -1); // 4 more bytes address and reg value
  return 0;
}


Arickzon93

Thank you for the fast answer :)

Code: [Select]
#include <Ethernet.h>
#include <Controllino.h>

const int MODBUS_CONNECT_ERROR = -10;
const int MODBUS_NO_RESPONSE = -11;

const byte FNC_READ_REGS = 0x03;
const byte FNC_WRITE_SINGLE = 0x06;
const byte FNC_ERR_FLAG = 0x80;

const byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

//const int ETH_CS_PIN = 10;

const IPAddress isgAddress(192, 168, 12, 20);

void setup() {
  Serial.begin(115200);

  //Ethernet.init(ETH_CS_PIN);
  Serial.println("Initialize Ethernet with DHCP:");
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    if (Ethernet.linkStatus() == LinkOFF) {
      Serial.println("Ethernet cable is not connected.");
    }
    while (true) {
      delay(1); // do nothing, no point running without Ethernet
    }
  } else {
    Serial.print("  DHCP assigned IP ");
    Serial.println(Ethernet.localIP());
  }

  EthernetClient client;

  if (client.connect(isgAddress, 502)) {

    client.setTimeout(2000);

    Serial.println(F("client connected"));
    int res = tests(client);
    Serial.println();
    if (res != 0) {
      Serial.print("modbus error ");
      Serial.println(res);
    }
    client.stop();
  } else {
    Serial.println("connection failed");
  }
}

int tests(Client& client) {


  short regs[16];
  int res = modbusRequest(client, 240, 41002, 16, regs);
  if (res != 0)
    return res;
  int voltage = regs[3] * pow(10, regs[8]); // ac voltage F3 * scale
  Serial.println(voltage);

  res = modbusWriteSingle(client, 40303 + 12, 50 * 100);
  if (res != 0)
    return res;

  return 0;
}

void loop() {
}

/*
 * return
 *   - 0 is success
 *   - negative is comm error
 *   - positive value is client protocol exception code
 */
int modbusRequest(Client& client, byte uid, unsigned int addr, byte len, short *regs) {

  const byte CODE_IX = 7;
  const byte ERR_CODE_IX = 8;
  const byte LENGTH_IX = 8;
  const byte DATA_IX = 9;

  byte request[] = {0, 1, 0, 0, 0, 6, uid, FNC_READ_REGS, (byte) (addr / 256), (byte) (addr % 256), 0, len};
  client.write(request, sizeof(request));

  int respDataLen = len * 2;
  byte response[max((int) DATA_IX, respDataLen)];
  int readLen = client.readBytes(response, DATA_IX);
  if (readLen < DATA_IX) {
    client.stop();
    return MODBUS_NO_RESPONSE;
  }
  switch (response[CODE_IX]) {
    case FNC_READ_REGS:
      break;
    case (FNC_ERR_FLAG | FNC_READ_REGS):
      return response[ERR_CODE_IX]; // 0x01, 0x02, 0x03 or 0x11
    default:
      return -3;
  }
  if (response[LENGTH_IX] != respDataLen)
    return -2;
  readLen = client.readBytes(response, respDataLen);
  if (readLen < respDataLen)
    return -4;
  for (int i = 0, j = 0; i < len; i++, j += 2) {
    regs[i] = response[j] * 256 + response[j + 1];
  }
  return 0;
}

int modbusWriteSingle(Client& modbus, unsigned int address, int val) {

  const byte CODE_IX = 7;
  const byte ERR_CODE_IX = 8;
  const byte RESPONSE_LENGTH = 9;

  byte req[] = { 0, 1, 0, 0, 0, 6, 1, FNC_WRITE_SINGLE, // header
        (byte) (address / 256), (byte) (address % 256),
        (byte) (val / 256), (byte) (val % 256)};

  modbus.write(req, sizeof(req));

  byte response[RESPONSE_LENGTH];
  int readLen = modbus.readBytes(response, RESPONSE_LENGTH);
  if (readLen < RESPONSE_LENGTH) {
    modbus.stop();
    return MODBUS_NO_RESPONSE;
  }
  switch (response[CODE_IX]) {
    case FNC_WRITE_SINGLE:
      break;
    case (FNC_ERR_FLAG | FNC_WRITE_SINGLE):
      return response[ERR_CODE_IX]; // 0x01, 0x02, 0x03, 0x04 or 0x11
    default:
      return -3;
  }
  while (modbus.read() != -1); // 4 more bytes address and reg value
  return 0;
}


I did the "const int ETH_CS_PIN = 10;" as a comment because i don´t need to configure pins, right?
as well as the "Ethernet.init(ETH_CS_PIN);"

Serial Monitor:

et with DHCP:
Initialize Ethernet with DHCP:
  DHCP assigned IP 192.168.12.254
client connected

modbus error 2

So the connection is working, but what is Modbus error 2?

It is the answer of
Code: [Select]
int res = tests(client); right?

Juraj

Thank you for the fast answer :)

Code: [Select]
#include <Ethernet.h>
#include <Controllino.h>

const int MODBUS_CONNECT_ERROR = -10;
const int MODBUS_NO_RESPONSE = -11;

const byte FNC_READ_REGS = 0x03;
const byte FNC_WRITE_SINGLE = 0x06;
const byte FNC_ERR_FLAG = 0x80;

const byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

//const int ETH_CS_PIN = 10;

const IPAddress isgAddress(192, 168, 12, 20);

void setup() {
  Serial.begin(115200);

  //Ethernet.init(ETH_CS_PIN);
  Serial.println("Initialize Ethernet with DHCP:");
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    if (Ethernet.linkStatus() == LinkOFF) {
      Serial.println("Ethernet cable is not connected.");
    }
    while (true) {
      delay(1); // do nothing, no point running without Ethernet
    }
  } else {
    Serial.print("  DHCP assigned IP ");
    Serial.println(Ethernet.localIP());
  }

  EthernetClient client;

  if (client.connect(isgAddress, 502)) {

    client.setTimeout(2000);

    Serial.println(F("client connected"));
    int res = tests(client);
    Serial.println();
    if (res != 0) {
      Serial.print("modbus error ");
      Serial.println(res);
    }
    client.stop();
  } else {
    Serial.println("connection failed");
  }
}

int tests(Client& client) {


  short regs[16];
  int res = modbusRequest(client, 240, 41002, 16, regs);
  if (res != 0)
    return res;
  int voltage = regs[3] * pow(10, regs[8]); // ac voltage F3 * scale
  Serial.println(voltage);

  res = modbusWriteSingle(client, 40303 + 12, 50 * 100);
  if (res != 0)
    return res;

  return 0;
}

void loop() {
}

/*
 * return
 *   - 0 is success
 *   - negative is comm error
 *   - positive value is client protocol exception code
 */
int modbusRequest(Client& client, byte uid, unsigned int addr, byte len, short *regs) {

  const byte CODE_IX = 7;
  const byte ERR_CODE_IX = 8;
  const byte LENGTH_IX = 8;
  const byte DATA_IX = 9;

  byte request[] = {0, 1, 0, 0, 0, 6, uid, FNC_READ_REGS, (byte) (addr / 256), (byte) (addr % 256), 0, len};
  client.write(request, sizeof(request));

  int respDataLen = len * 2;
  byte response[max((int) DATA_IX, respDataLen)];
  int readLen = client.readBytes(response, DATA_IX);
  if (readLen < DATA_IX) {
    client.stop();
    return MODBUS_NO_RESPONSE;
  }
  switch (response[CODE_IX]) {
    case FNC_READ_REGS:
      break;
    case (FNC_ERR_FLAG | FNC_READ_REGS):
      return response[ERR_CODE_IX]; // 0x01, 0x02, 0x03 or 0x11
    default:
      return -3;
  }
  if (response[LENGTH_IX] != respDataLen)
    return -2;
  readLen = client.readBytes(response, respDataLen);
  if (readLen < respDataLen)
    return -4;
  for (int i = 0, j = 0; i < len; i++, j += 2) {
    regs[i] = response[j] * 256 + response[j + 1];
  }
  return 0;
}

int modbusWriteSingle(Client& modbus, unsigned int address, int val) {

  const byte CODE_IX = 7;
  const byte ERR_CODE_IX = 8;
  const byte RESPONSE_LENGTH = 9;

  byte req[] = { 0, 1, 0, 0, 0, 6, 1, FNC_WRITE_SINGLE, // header
        (byte) (address / 256), (byte) (address % 256),
        (byte) (val / 256), (byte) (val % 256)};

  modbus.write(req, sizeof(req));

  byte response[RESPONSE_LENGTH];
  int readLen = modbus.readBytes(response, RESPONSE_LENGTH);
  if (readLen < RESPONSE_LENGTH) {
    modbus.stop();
    return MODBUS_NO_RESPONSE;
  }
  switch (response[CODE_IX]) {
    case FNC_WRITE_SINGLE:
      break;
    case (FNC_ERR_FLAG | FNC_WRITE_SINGLE):
      return response[ERR_CODE_IX]; // 0x01, 0x02, 0x03, 0x04 or 0x11
    default:
      return -3;
  }
  while (modbus.read() != -1); // 4 more bytes address and reg value
  return 0;
}


I did the "const int ETH_CS_PIN = 10;" as a comment because i don´t need to configure pins, right?
as well as the "Ethernet.init(ETH_CS_PIN);"

Serial Monitor:

et with DHCP:
Initialize Ethernet with DHCP:
  DHCP assigned IP 192.168.12.254
client connected

modbus error 2

So the connection is working, but what is Modbus error 2?

It is the answer of
Code: [Select]
int res = tests(client); right?
it is response from the server. it doesn't know the register or the count of registers runs out of valid addresses.
it is my test sketch. use your slave id and register addresses

Arickzon93

I´m a little bit lost at the moment..
Can you explain me what this means:
Code: [Select]
modbusWriteSingle(client, 40303 + 12, 50 * 100);
modbusWriteSingle is the function. What does this "client" mean in this case?

Code: [Select]
int modbusRequest(Client& client, byte uid, unsigned int addr, byte len, short *regs)
const byte CODE_IX = 7;
  const byte ERR_CODE_IX = 8;
  const byte LENGTH_IX = 8;
  const byte DATA_IX = 9;

  byte request[] = {0, 1, 0, 0, 0, 6, uid, FNC_READ_REGS, (byte) (addr / 256), (byte) (addr % 256), 0, len};


Here you create a modbus Request. What does this "Client&client" mean.

Code: [Select]
int res = modbusRequest(client, 240, 41002, 16, regs);
What does dies 240 mean? This is the uid byte i think. But why 240, or for what i will need this one?

Juraj

I´m a little bit lost at the moment..
Can you explain me what this means:
Code: [Select]
modbusWriteSingle(client, 40303 + 12, 50 * 100);
modbusWriteSingle is the function. What does this "client" mean in this case?

Code: [Select]
int modbusRequest(Client& client, byte uid, unsigned int addr, byte len, short *regs)
const byte CODE_IX = 7;
  const byte ERR_CODE_IX = 8;
  const byte LENGTH_IX = 8;
  const byte DATA_IX = 9;

  byte request[] = {0, 1, 0, 0, 0, 6, uid, FNC_READ_REGS, (byte) (addr / 256), (byte) (addr % 256), 0, len};


Here you create a modbus Request. What does this "Client&client" mean.

Code: [Select]
int res = modbusRequest(client, 240, 41002, 16, regs);
What does dies 240 mean? This is the uid byte i think. But why 240, or for what i will need this one?
sorry. this is a sketch I am working on right now. only the two modbus tcp functions are from my main project and are in use more then 2 years.

client is EthernetClient. class Client is a base class for all Arduino networking client implementations. (& Client& is reference (instead of copy))

the parameters of the test invocations are some addresses on my modbus server. 240 is 'slave id'

modbus tcp is binary protocol. I open a socket and send the array of bytes. it is really simple

https://en.wikipedia.org/wiki/Modbus

here I have a Java version of the request https://github.com/jandrassy/Regulator/blob/fe3c24570287d90607058cd812a5969c32ed8924/util/jregulator/src/rlk/RegulatorDev.java#L42




Arickzon93

First of all thank you! I´m now able to read my Holding Registers.
But the Write Register function still runs me into Error..

Failure message : 'modbus' was not declared in this scope

Code: [Select]
int modbusWriteSingle(Client& modbus, unsigned int address, int val)

How i can "activate" the "modbus" call?

Juraj

First of all thank you! I´m now able to read my Holding Registers.
But the Write Register function still runs me into Error..

Failure message : 'modbus' was not declared in this scope

Code: [Select]
int modbusWriteSingle(Client& modbus, unsigned int address, int val)

How i can "activate" the "modbus" call?
modbus is only a name of the parameter in the function. call it as

  res = modbusWriteSingle(client, registerAddress, value);
  if (res != 0)
    return res;

Arickzon93

Tank you !!
Now everything work´s like it should be.
Here´s my Sketch.
This Sketch is not as clean as you would do:D but it work´s for me.

Maybe you can give me an advice how to clean up my sketch and get rid of that much IF structures.

I read Register 1 to 20 all the time. If for ex. int res 14 gives me a 1, than i write register 8.

This Sketch is not finished yet. But the Basic function is available.

Again tank you for your help!

Code: [Select]
#include <Ethernet.h>     //Ethernet Bibliothek
#include <SPI.h>          //SPI Bibliothek
#include <Controllino.h>  //Controllino Bibliothek

const int MODBUS_CONNECT_ERROR = -10;
const int MODBUS_NO_RESPONSE = -11;

const byte FNC_READ_REGS = 0x03;
const byte FNC_WRITE_SINGLE = 0x06;
const byte FNC_ERR_FLAG = 0x80;

short regs[16]; // Array für den Wert der Register zu speichern
byte address3 = 0x03;//41001 bis 41024
byte address4 = 0x04;//41025 bis 41040
byte MiR1 = 0xE9; // 41002 mit address3
byte MiR2 = 0xEB; // 41004 mit address3
byte MiR3 = 0xED; // 41006 mit address3
byte MiR4 = 0xEF; // 41008 mit address3
byte MiR5 = 0xF1; // 41010 mit address3
byte MiR6 = 0xF3; // 41012 mit address3
byte MiR7 = 0xF5; // 41014 mit address3
byte MiR8 = 0xF7; // 41016 mit address3
byte MiR9 = 0xF9; // 41018 mit address3
byte MiR10 = 0xFB; // 41020 mit address3
byte MiR11 = 0xFD; // 41022 mit address3
byte MiR12 = 0xFF; // 41024 mit address3
byte MiR13 = 0x01; // 41026 mit address4
byte MiR14 = 0x03; // 41028 mit address4
byte MiR15 = 0x05; // 41030 mit address4
byte MiR16 = 0x07; // 41032 mit address4
byte MiR17 = 0x09; // 41034 mit address4
byte MiR18 = 0x0B; // 41036 mit address4
byte MiR19 = 0x0D; // 41038 mit address4
byte MiR20 = 0x0F; // 41040 mit address4

bool Abfrage1; // True or False Abfrage des Registers MiR1
bool Abfrage2; // True or False Abfrage des Registers MiR2
bool Abfrage3; // True or False Abfrage des Registers MiR3
bool Abfrage4; // True or False Abfrage des Registers MiR4
bool Abfrage5; // True or False Abfrage des Registers MiR5
bool Abfrage6; // True or False Abfrage des Registers MiR6
bool Abfrage7; // True or False Abfrage des Registers MiR7
bool Abfrage8; // True or False Abfrage des Registers MiR8
bool Abfrage9; // True or False Abfrage des Registers MiR9
bool Abfrage10; // True or False Abfrage des Registers MiR10
bool Abfrage11; // True or False Abfrage des Registers MiR11
bool Abfrage12; // True or False Abfrage des Registers MiR12
bool Abfrage13; // True or False Abfrage des Registers MiR13
bool Abfrage14; // True or False Abfrage des Registers MiR14
bool Abfrage15; // True or False Abfrage des Registers MiR15
bool Abfrage16; // True or False Abfrage des Registers MiR16
bool Abfrage17; // True or False Abfrage des Registers MiR17
bool Abfrage18; // True or False Abfrage des Registers MiR18
bool Abfrage19; // True or False Abfrage des Registers MiR19
bool Abfrage20; // True or False Abfrage des Registers MiR20


const byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //MAC Adresse Controllino

IPAddress serverIP (192, 168, 12, 20);  //Server IP Adresse MiR

int port = 502; //Server Port MiR

EthernetClient client;


void setup() {

Serial.begin(9600);

  Serial.println("Initialize Ethernet with DHCP:");
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    if (Ethernet.linkStatus() == LinkOFF) {
      Serial.println("Ethernet cable is not connected.");
    }
    while (true) {
      delay(1); // do nothing, no point running without Ethernet
    }
  } else {
    Serial.print("  DHCP assigned ClientIP: ");
    Serial.println(Ethernet.localIP());
    Serial.print("  ServerIP:               ");
    Serial.println(serverIP);
    Serial.print("  ServerPort:             ");
    Serial.println(port);
  }
if (client.connect(serverIP, port)) {
    client.setTimeout(2000);
    Serial.println(F("Client connected"));
}
}

Arickzon93

Code: [Select]
void loop() {

  int res1 = modbusRequest(client, 1, address3,MiR1, 1, regs);
  Abfrage1 = regs[0];
  if (Abfrage1 == 0)
  {
  Serial.print("Abfrage1 ");  
  Serial.print(Abfrage1);
  Serial.println(" ");
  }
  else
  {
  Serial.print("Abfrage1 ");
  Serial.print(Abfrage1);
  Serial.println(" ");  
  }
  //delay(1000);

  int res2 = modbusRequest(client, 1, address3,MiR2, 1, regs);
  Abfrage2 = regs[0];
  if (Abfrage2 == 0)
  {
  Serial.print("Abfrage2 ");  
  Serial.print(Abfrage2);
  Serial.println(" ");
  }
  else
  {
  Serial.print("Abfrage2 ");
  Serial.print(Abfrage2);
  Serial.println(" ");  
  }
  //delay(1000);

    int res3 = modbusRequest(client, 1, address3,MiR3, 1, regs);
  Abfrage3 = regs[0];
  if (Abfrage3 == 0)
  {
  Serial.print("Abfrage3 ");  
  Serial.print(Abfrage3);
  Serial.println(" ");
  }
  else
  {
  Serial.print("Abfrage3 ");
  Serial.print(Abfrage3);
  Serial.println(" ");  
  }
  //delay(1000);

    int res4 = modbusRequest(client, 1, address3,MiR4, 1, regs);
  Abfrage4 = regs[0];
  if (Abfrage4 == 0)
  {
  Serial.print("Abfrage4 ");  
  Serial.print(Abfrage4);
  Serial.println(" ");
  }
  else
  {
  Serial.print("Abfrage1 ");
  Serial.print(Abfrage1);
  Serial.println(" ");  
  }
  //delay(1000);

    int res5 = modbusRequest(client, 1, address3,MiR5, 1, regs);
  Abfrage5 = regs[0];
  if (Abfrage5 == 0)
  {
  Serial.print("Abfrage5 ");  
  Serial.print(Abfrage5);
  Serial.println(" ");
  }
  else
  {
  Serial.print("Abfrage5 ");
  Serial.print(Abfrage5);
  Serial.println(" ");  
  }
  //delay(1000);

    int res6 = modbusRequest(client, 1, address3,MiR6, 1, regs);
  Abfrage6 = regs[0];
  if (Abfrage6 == 0)
  {
  Serial.print("Abfrage6 ");  
  Serial.print(Abfrage6);
  Serial.println(" ");
  }
  else
  {
  Serial.print("Abfrage6 ");
  Serial.print(Abfrage6);
  Serial.println(" ");  
  }
  //delay(1000);

  int res7 = modbusRequest(client, 1, address3,MiR7, 1, regs);
  Abfrage7 = regs[0];
  if (Abfrage7 == 0)
  {
  Serial.print("Abfrage7 ");  
  Serial.print(Abfrage7);
  Serial.println(" ");
  }
  else
  {
  Serial.print("Abfrage7 ");
  Serial.print(Abfrage7);
  Serial.println(" ");  
  }
  //delay(1000);

  int res8 = modbusRequest(client, 1, address3,MiR8, 1, regs);
  Abfrage8 = regs[0];
  if (Abfrage8 == 0)
  {
  Serial.print("Abfrage8 ");  
  Serial.print(Abfrage8);
  Serial.println(" ");
  }
  else
  {
  Serial.print("Abfrage8 ");
  Serial.print(Abfrage8);
  Serial.println(" ");  
  }
  //delay(1000);

  int res9 = modbusRequest(client, 1, address3,MiR9, 1, regs);
  Abfrage9 = regs[0];
  if (Abfrage9 == 0)
  {
  Serial.print("Abfrage9 ");  
  Serial.print(Abfrage9);
  Serial.println(" ");
  }
  else
  {
  Serial.print("Abfrage9 ");
  Serial.print(Abfrage9);
  Serial.println(" ");  
  }
  //delay(1000);

  int res10 = modbusRequest(client, 1, address3,MiR10, 1, regs);
  Abfrage10 = regs[0];
  if (Abfrage10 == 0)
  {
  Serial.print("Abfrage10 ");  
  Serial.print(Abfrage10);
  Serial.println(" ");
  }
  else
  {
  Serial.print("Abfrage10 ");
  Serial.print(Abfrage10);
  Serial.println(" ");  
  }
  //delay(1000);

  int res11 = modbusRequest(client, 1, address3,MiR11, 1, regs);
  Abfrage11 = regs[0];
  if (Abfrage11 == 0)
  {
  Serial.print("Abfrage11 ");  
  Serial.print(Abfrage11);
  Serial.println(" ");
  }
  else
  {
  Serial.print("Abfrage11 ");
  Serial.print(Abfrage11);
  Serial.println(" ");  
  }
  //delay(1000);

  int res12 = modbusRequest(client, 1, address3,MiR12, 1, regs);
  Abfrage12 = regs[0];
  if (Abfrage12 == 0)
  {
  Serial.print("Abfrage12 ");  
  Serial.print(Abfrage12);
  Serial.println(" ");
  }
  else
  {
  Serial.print("Abfrage12 ");
  Serial.print(Abfrage12);
  Serial.println(" ");  
  }
  //delay(1000);

  int res13 = modbusRequest(client, 1, address4,MiR13, 1, regs);
  Abfrage13 = regs[0];
  if (Abfrage13 == 0)
  {
  Serial.print("Abfrage13 ");  
  Serial.print(Abfrage13);
  Serial.println(" ");
  }
  else
  {
  Serial.print("Abfrage13 ");
  Serial.print(Abfrage13);
  Serial.println(" ");  
    digitalWrite (23, HIGH);
  delay(5000);
  digitalWrite (23,LOW);
  modbusWriteSingle(client, address3, MiR7, 1);
  delay (1000);
  modbusWriteSingle(client, address3, MiR7, 0);
  }
  //delay(1000);

  int res14 = modbusRequest(client, 1, address4,MiR14, 1, regs);
  Abfrage14 = regs[0];
  if (Abfrage14 == 0)
  {
  Serial.print("Abfrage14 ");  
  Serial.print(Abfrage14);
  Serial.println(" ");
  }
  else
  {
  Serial.print("Abfrage14 ");
  Serial.print(Abfrage14);
  Serial.println(" ");
  digitalWrite (22, HIGH);
  delay(5000);
  digitalWrite (22,LOW);
  modbusWriteSingle(client, address3, MiR8, 1);
  delay (1000);
  modbusWriteSingle(client, address3, MiR8, 0);
  }
  //delay(1000);

  int res15 = modbusRequest(client, 1, address4,MiR15, 1, regs);
  Abfrage15 = regs[0];
  if (Abfrage15 == 0)
  {
  Serial.print("Abfrage15 ");  
  Serial.print(Abfrage15);
  Serial.println(" ");
  }
  else
  {
  Serial.print("Abfrage15 ");
  Serial.print(Abfrage15);
  Serial.println(" ");  
  }
  //delay(1000);

  int res16 = modbusRequest(client, 1, address4,MiR16, 1, regs);
  Abfrage16 = regs[0];
  if (Abfrage16 == 0)
  {
  Serial.print("Abfrage16 ");  
  Serial.print(Abfrage16);
  Serial.println(" ");
  }
  else
  {
  Serial.print("Abfrage16 ");
  Serial.print(Abfrage16);
  Serial.println(" ");  
  }
  //delay(1000);

  int res17 = modbusRequest(client, 1, address4,MiR17, 1, regs);
  Abfrage17 = regs[0];
  if (Abfrage17 == 0)
  {
  Serial.print("Abfrage17 ");  
  Serial.print(Abfrage17);
  Serial.println(" ");
  }
  else
  {
  Serial.print("Abfrage17 ");
  Serial.print(Abfrage17);
  Serial.println(" ");  
  }
  //delay(1000);

  int res18 = modbusRequest(client, 1, address4,MiR18, 1, regs);
  Abfrage18 = regs[0];
  if (Abfrage18 == 0)
  {
  Serial.print("Abfrage18 ");  
  Serial.print(Abfrage18);
  Serial.println(" ");
  }
  else
  {
  Serial.print("Abfrage18 ");
  Serial.print(Abfrage18);
  Serial.println(" ");
  }
  //delay(1000);

  int res19 = modbusRequest(client, 1, address4,MiR19, 1, regs);
  Abfrage19 = regs[0];
  if (Abfrage19 == 0)
  {
  Serial.print("Abfrage19 ");  
  Serial.print(Abfrage19);
  Serial.println(" ");
  }
  else
  {
  Serial.print("Abfrage19 ");
  Serial.print(Abfrage19);
  Serial.println(" ");  
  }
  //delay(1000);

  int res20 = modbusRequest(client, 1, address4,MiR20, 1, regs);
  Abfrage20 = regs[0];
  if (Abfrage20 == 0)
  {
  Serial.print("Abfrage20 ");  
  Serial.print(Abfrage20);
  Serial.println(" ");
  }
  else
  {
  Serial.print("Abfrage20 ");
  Serial.print(Abfrage20);
  Serial.println(" ");  
  }
  //delay(1000);
}
int modbusRequest(Client& client, byte uid, byte addr1, byte addr2, byte len, short *regs) {

  const byte CODE_IX = 7;
  const byte ERR_CODE_IX = 8;
  const byte LENGTH_IX = 8;
  const byte DATA_IX = 9;

  byte request[] = {0, 1, 0, 0, 0, 6, uid, FNC_READ_REGS, addr1, addr2, 0, len};
  client.write(request, sizeof(request));

  int respDataLen = len * 2;
  byte response[max((int) DATA_IX, respDataLen)];
  int readLen = client.readBytes(response, DATA_IX);
  if (readLen < DATA_IX) {
    client.stop();
    Serial.println("No response");
    return MODBUS_NO_RESPONSE;
  }
  switch (response[CODE_IX]) {
    case FNC_READ_REGS:
      break;
    case (FNC_ERR_FLAG | FNC_READ_REGS):
      Serial.println("Error");
      return response[ERR_CODE_IX]; // 0x01, 0x02, 0x03 or 0x11
    default:
      return -3;
  }
  if (response[LENGTH_IX] != respDataLen)
    return -2;
  readLen = client.readBytes(response, respDataLen);
  if (readLen < respDataLen)
    return -4;
  for (int i = 0, j = 0; i < len; i++, j += 2) {
    regs[i] = response[j] * 256 + response[j + 1];
  }
  return 0;
}

int modbusWriteSingle(Client& modbus, byte addr1, byte addr2, int val) {

  const byte CODE_IX = 7;
  const byte ERR_CODE_IX = 8;
  const byte RESPONSE_LENGTH = 9;

  byte req[] = { 0, 1, 0, 0, 0, 6, 1, FNC_WRITE_SINGLE, addr1, addr2, 0, val};

  modbus.write(req, sizeof(req));

Juraj

you can read subsequent registers with one request

  int regs[REGISTERS_COUNT];
  int res = modbusRequest(client, 1, address3, REGISTERS_COUNT, regs);

Go Up