- Modbus TCP/IP specification: http://www.modbus.org/specs.php
- Modbus TCP/IP simpler description: http://www.simplymodbus.ca/TCP.htm
- FC1 - Read Coils (ReadCoilsRequest / ReadCoilsResponse)
- FC2 - Read Input Discretes (ReadInputDiscretesRequest / ReadInputDiscretesResponse)
- FC3 - Read Holding Registers (ReadHoldingRegistersRequest / ReadHoldingRegistersResponse)
- FC4 - Read Input Registers (ReadInputRegistersRequest / ReadInputRegistersResponse)
- FC5 - Write Single Coil (WriteSingleCoilRequest / WriteSingleCoilResponse)
- FC6 - Write Single Register (WriteSingleRegisterRequest / WriteSingleRegisterResponse)
- FC15 - Write Multiple Coils (WriteMultipleCoilsRequest / WriteMultipleCoilsResponse)
- FC16 - Write Multiple Registers (WriteMultipleRegistersRequest / WriteMultipleRegistersResponse)
- PHP 5.6+ (64bit PHP! 32bit php does not support 64bit ints and overflows with 32bit unsigned integers when 32th bit is set)
This library is influenced by phpmodbus library and meant to be provide decoupled Modbus protocol (request/response packets) and networking related features so you could build modbus client with our own choice of networking code (ext_sockets/streams/Reactphp asynchronous streams) or use library provided networking classes (php Streams)
Library supports following byte and word orders:
- Big endian (ABCD)
- Big endian low word first (CDAB) (used by Wago-750)
- Little endian (DCBA)
- Little endian low word first (BADC)
See Endian.php for additional info and Types.php for supported data types.
Some of the Modbus function examples are in examples/
folder
$connection = BinaryStreamConnection::getBuilder()
->setHost('192.168.0.1')
->build();
$packet = new ReadHoldingRegistersRequest(256, 8); //create FC3 request packet
try {
$binaryData = $connection->connect()->sendAndReceive($packet);
//parse binary data to response object
$response = ResponseFactory::parseResponseOrThrow($binaryData);
//same as 'foreach ($response->getWords() as $word) {'
foreach ($response as $word) {
print_r($word->getInt16());
}
// print registers as double words in big endian low word first order (as WAGO-750 does)
foreach ($response->getDoubleWords() as $dword) {
print_r($dword->getInt32(Endian::BIG_ENDIAN_LOW_WORD_FIRST));
}
// set internal index to match start address to simplify array access
$responseWithStartAddress = $response->withStartAddress(256);
print_r($responseWithStartAddress[256]->getBytes()); // use array access to get word
print_r($responseWithStartAddress->getDoubleWordAt(257)->getFloat());
} catch (Exception $exception) {
echo $exception->getMessage() . PHP_EOL;
} finally {
$connection->close();
}
Examples folder has index.php which can be used with php built-in web server to test out communication with our own PLCs.
git clone https://github.com/aldas/modbus-tcp-client.git
cd modbus-tcp-client
composer install
php -S localhost:8080 -t examples/
Now open http://localhost:8080 in browser. See additional query parameters from index.php.
- all
composer test
- unit tests
composer test-unit
- integration tests
composer test-integration
For Windows users:
- all
vendor/bin/phpunit
- unit tests
vendor/bin/phpunit --testsuite 'unit-tests'
- integration tests
vendor/bin/phpunit --testsuite 'integration-tests'