FieldTalk Modbus Slave C++ Library Library version 2.11.0

- Introduction
- Chapters
- Modules
- Classes

How to integrate the Protocol in your Application

# Using Serial Protocols

Let's assume we want to implement a Modbus slave device with slave address 1.

The registers for reading are in the reference range 4:00100 to 4:00119 and the registers for writing are in the range 4:00200 to 4:00219. The discretes for reading are in the reference range 0:00010 to 0:00019 and the discretes for writing are in the range 0:00020 to 0:00029.

1. Include the package header files

#include "MbusRtuSlaveProtocol.hpp"

2. Device data profile definition

Define the data sets which reflects the slave's data profile by type and size:

short readRegSet[20];
short writeRegSet[20];
char readBitSet[10];
char writeBitSet[10];

3. Declare a Data Provider

class MyDataProvider: public MbusDataTableInterface
{
public:
int readHoldingRegistersTable(int startRef, short regArr[], int refCnt)
{
// Adjust Modbus reference counting
startRef--;
// Our start address for reading is at 100, so deduct offset
startRef -= 100;
// Validate range
if (startRef + refCnt > (int) sizeof(readRegSet) / sizeof(short))
return (0);
// Copy data
memcpy(regArr, &readRegSet[startRef], refCnt * sizeof(short));
return (1);
}
int writeHoldingRegistersTable(int startRef,
const short regArr[],
int refCnt)
{
// Adjust Modbus reference counting
startRef--;
// Our start address for writing is at 200, so deduct offset
startRef -= 200;
// Validate range
if (startRef + refCnt > (int) sizeof(writeRegSet) / sizeof(short))
return (0);
// Copy data
memcpy(&writeRegSet[startRef], regArr, refCnt * sizeof(short));
return (1);
}
int readCoilsTable(int startRef,
char bitArr[],
int refCnt)
{
// Adjust Modbus reference counting
startRef--;
// Our start address for reading is at 10, so deduct offset
startRef -= 10;
// Validate range
if (startRef + refCnt > (int) sizeof(readBitSet) / sizeof(char))
return (0);
// Copy data
memcpy(bitArr, &readBitSet[startRef], refCnt * sizeof(char));
return (1);
}
int writeCoilsTable(int startRef,
const char bitArr[],
int refCnt)
{
// Adjust Modbus reference counting
startRef--;
// Our start address for writing is at 20, so deduct offset
startRef -= 20;
// Validate range
if (startRef + refCnt > (int) sizeof(writeBitSet) / sizeof(char))
return (0);
// Copy data
memcpy(&writeBitSet[startRef], bitArr, refCnt * sizeof(char));
return (1);
}
} dataProvider;

4. Declare and instantiate a server object and associate it with the Data Provider

MbusRtuSlaveProtocol mbusServer;
mbusServer.addDataTable(1, &dataProvider);

5. Start-up the server

int result;
result = mbusServer.startupServer(portName,
19200L, // Baudrate
8, // Databits
1, // Stopbits
2); // Even parity
if (result != FTALK_SUCCESS)
{
fprintf(stderr, "Error starting server: %s!\n",
getBusProtocolErrorText(result));
exit(EXIT_FAILURE);
}

6. Execute cyclically the server loop

int result = FTALK_SUCCESS;
while (result == FTALK_SUCCESS)
{
result = mbusServer.serverLoop();
if (result != FTALK_SUCCESS)
fprintf(stderr, "%s!\n", getBusProtocolErrorText(result));
}

7. Shutdown the server if not needed any more

mbusServer.shutdownServer();

# Using MODBUS/TCP Protocol

Let's assume we want to implement a Modbus slave device with slave address 1.

The registers for reading are in the reference range 4:00100 to 4:00119 and the registers for writing are in the range 4:00200 to 4:00219. The discretes for reading are in the reference range 0:00010 to 0:00019 and the discretes for writing are in the range 0:00020 to 0:00029.

1. Include the package header files

#include "MbusTcpSlaveProtocol.hpp"

2. Device data profile definition

Define the data sets which reflects the slave's data profile by type and size:

short readRegSet[20];
short writeRegSet[20];
char readBitSet[10];
char writeBitSet[10];

3. Declare a Data Provider

class MyDataProvider: public MbusDataTableInterface
{
public:
int readHoldingRegistersTable(int startRef, short regArr[], int refCnt)
{
// Adjust Modbus reference counting
startRef--;
// Our start address for reading is at 100, so deduct offset
startRef -= 100;
// Validate range
if (startRef + refCnt > (int) sizeof(readRegSet) / sizeof(short))
return (0);
// Copy data
memcpy(regArr, &readRegSet[startRef], refCnt * sizeof(short));
return (1);
}
int writeHoldingRegistersTable(int startRef,
const short regArr[],
int refCnt)
{
// Adjust Modbus reference counting
startRef--;
// Our start address for writing is at 200, so deduct offset
startRef -= 200;
// Validate range
if (startRef + refCnt > (int) sizeof(writeRegSet) / sizeof(short))
return (0);
// Copy data
memcpy(&writeRegSet[startRef], regArr, refCnt * sizeof(short));
return (1);
}
int readCoilsTable(int startRef,
char bitArr[],
int refCnt)
{
// Adjust Modbus reference counting
startRef--;
// Our start address for reading is at 10, so deduct offset
startRef -= 10;
// Validate range
if (startRef + refCnt > (int) sizeof(readBitSet) / sizeof(char))
return (0);
// Copy data
memcpy(bitArr, &readBitSet[startRef], refCnt * sizeof(char));
return (1);
}
int writeCoilsTable(int startRef,
const char bitArr[],
int refCnt)
{
// Adjust Modbus reference counting
startRef--;
// Our start address for writing is at 20, so deduct offset
startRef -= 20;
// Validate range
if (startRef + refCnt > (int) sizeof(writeBitSet) / sizeof(char))
return (0);
// Copy data
memcpy(&writeBitSet[startRef], bitArr, refCnt * sizeof(char));
return (1);
}
} dataProvider;

4. Declare and instantiate a server object and associate it with the Data Provider and the slave address.

MbusTcpSlaveProtocol mbusServer();
mbusServer.addDataTable(1, &dataProvider);

5. Change the default port from 502 to semething else if server shall not run as root. This step is not necessary when the server can run with root privilege.

mbusServer.setPort(5000);

6. Start-up the server

int result;
result = mbusServer.startupServer();
if (result != FTALK_SUCCESS)
{
fprintf(stderr, "Error starting server: %s!\n",
getBusProtocolErrorText(result));
exit(EXIT_FAILURE);
}

7. Execute cyclically the server loop

int result = FTALK_SUCCESS;
while (result == FTALK_SUCCESS)
{
result = mbusServer.serverLoop();
if (result != FTALK_SUCCESS)
fprintf(stderr, "%s!\n", getBusProtocolErrorText(result));
}

8. Shutdown the server if not needed any more

mbusServer.shutdownServer();