Let's assume we want to talk to 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. Import the library packages
uses
MbusRtuMasterProtocol,
BusProtocolExceptions;
2. Device data profile definition
Define the data sets which reflects the slave's data profile by type and size:
var
readRegSet: array[1..20] of word;
writeRegSet: array[1..10] of word;
readBitSet: array[1..10] of boolean;
writeBitSet: array[1..10] of boolean;
If you are using floats instead of 16-bit words define:
var
readFloatSet: array[1..10] of single;
writeFloatSet: array[1..10] of single;
If you are using 32-bit ints instead of 16-bit words define:
var
readLongSet: array[1..10] of integer;
writeLongSet: array[1..10] of integer;
3. Declare and instantiate a protocol object
4. Instantiate and open the protocol
try
mbusProtocol := TMbusRtuMasterProtocol.Create(nil);
mbusProtocol.portName := 'COM1';
mbusProtocol.baudRate := 9600;
mbusProtocol.openProtocol;
except
on e: Exception do
begin
writeln('Error opening protocol: ', e.message, '!');
halt(1);
end;
end;
5. Perform the data transfer functions
- To read register values:
mbusProtocol.readMultipleRegisters(1, 100, readRegSet);
- To write a single register value:
mbusProtocol.writeSingleRegister(1, 200, 1234);
- To write mutliple register values:
mbusProtocol.writeMultipleRegisters(1, 200, writeRegSet);
- To read discrete values:
mbusProtocol.readCoils(1, 10, readBitSet);
- To write a single discrete value:
mbusProtocol.writeCoil(1, 20, true);
- To write multiple discrete values:
mbusProtocol.forceMultipleCoils(1, 20, writeBitSet);
- To read float values:
mbusProtocol.readMultipleFloats(1, 100, readFloatSet);
- To read long integer values:
mbusProtocol.readMultipleLongInts(1, 100, readLongSet);
6. Close the protocol port if not needed any more
mbusProtocol.closeProtocol;
7. Error Handling
Serial protocol errors like slave device failures, transmission failures, checksum errors and time-outs throw an exception. The following code snippet can handle and report these errors:
try
mbusProtocol.readMultipleRegisters(1, 100, dataSetArray);
except
on e: EBusProtocolException do
writeln(e.message, '!');
on e: Exception do
begin
writeln('Fatal error: ', e.message, '!');
halt(1);
end;
end;
An automatic retry mechanism is available and can be enabled with mbusProtocol.setRetryCnt(3) before opening the protocol port.
Let's assume we want to talk to a Modbus slave device with unit address 1 and IP address 10.0.0.11.
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. Import the library package
uses
MbusTcpMasterProtocol,
BusProtocolExceptions;
2. Device data profile definition
Define the data sets which reflects the slave's data profile by type and size:
var
readRegSet: array[1..20] of word;
writeRegSet: array[1..10] of word;
readBitSet: array[1..10] of boolean;
writeBitSet: array[1..10] of boolean;
If you are using floats instead of 16-bit words define:
var
readFloatSet: array[1..10] of single;
writeFloatSet: array[1..10] of single;
If you are using 32-bit ints instead of 16-bit words define:
var
readLongSet: array[1..10] of integer;
writeLongSet: array[1..10] of integer;
3. Declare and instantiate a protocol object
4. Open the protocol
mbusProtocol.hostName := ' 10.0.0.11';
mbusProtocol.openProtocol;
5. Perform the data transfer functions
- To read register values:
mbusProtocol.readMultipleRegisters(1, 100, readRegSet);
- To write a single register value:
mbusProtocol.writeSingleRegister(1, 200, 1234);
- To write mutliple register values:
mbusProtocol.writeMultipleRegisters(1, 200, writeRegSet);
- To read discrete values:
mbusProtocol.readCoils(1, 10, readBitSet);
- To write a single discrete value:
mbusProtocol.writeCoil(1, 20, true);
- To write multiple discrete values:
mbusProtocol.forceMultipleCoils(1, 20, writeBitSet);
- To read float values:
mbusProtocol.readMultipleFloats(1, 100, readFloatSet);
- To read long integer values:
mbusProtocol.readMultipleLongInts(1, 100, readLongSet);
6. Close the protocol port if not needed any more
mbusProtocol.closeProtocol;
7. Error Handling
TCP/IP protocol errors like slave failures, TCP/IP connection failures and time-outs return an error code. The following code snippet can handle these errors:
try
mbusProtocol.readMultipleRegisters(1, 100, dataSetArray);
except
on e: EBusProtocolException do
writeln(e.message, '!');
on e: Exception do
begin
writeln('Fatal error: ', e.message, '!');
halt(1);
end;
end;
If the method throws EConnectionWasClosed, it signals that the the TCP/IP connection was lost or closed by the remote end. Before using further data and control functions the connection has to be re-opened succesfully.