Skip to content

Commit

Permalink
Allow unit ID to be in range of 0-255.
Browse files Browse the repository at this point in the history
Older MODBUS specification limited unit ID (slave id) in range of 0-247). See "Modicon Modbus Protocol Reference Guide PI–MBUS–300 Rev. J" page 19. But newer spec has that limitation removed.
  • Loading branch information
aldas committed Mar 10, 2024
1 parent 6704b45 commit d4a7345
Show file tree
Hide file tree
Showing 14 changed files with 21 additions and 17 deletions.
2 changes: 1 addition & 1 deletion examples/fc1.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

$startAddress = 12288;
$quantity = 16;
$unitID = 0;
$unitID = 1;
$packet = new ReadCoilsRequest($startAddress, $quantity, $unitID); // NB: This is Modbus TCP packet not Modbus RTU over TCP!
echo 'Packet to be sent (in hex): ' . $packet->toHex() . PHP_EOL;

Expand Down
2 changes: 1 addition & 1 deletion examples/fc15.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
0, 0, 0, 0, 0, 0, 0, 0, // dec: 0, hex x0
1, 0, 0, 1 // dec: 9, hex: x9
];
$unitID = 0;
$unitID = 1;
$packet = new WriteMultipleCoilsRequest($startAddress, $coils, $unitID); // NB: This is Modbus TCP packet not Modbus RTU over TCP!
echo 'Packet to be sent (in hex): ' . $packet->toHex() . PHP_EOL;

Expand Down
2 changes: 1 addition & 1 deletion examples/fc16.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
Types::toInt16(-1000), //hex: FC18 as word
Types::toInt32(2000), //dec: 2000 -> hex: 7d00 is as 2 word 7D00 0000
];
$unitID = 0;
$unitID = 1;
$packet = new WriteMultipleRegistersRequest($startAddress, $registers, $unitID); // NB: This is Modbus TCP packet not Modbus RTU over TCP!
echo 'Packet to be sent (in hex): ' . $packet->toHex() . PHP_EOL;

Expand Down
2 changes: 1 addition & 1 deletion examples/fc2.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

$startAddress = 12288;
$quantity = 16;
$unitID = 0;
$unitID = 1;
$packet = new ReadInputDiscretesRequest($startAddress, $quantity, $unitID); // NB: This is Modbus TCP packet not Modbus RTU over TCP!
echo 'Packet to be sent (in hex): ' . $packet->toHex() . PHP_EOL;

Expand Down
2 changes: 1 addition & 1 deletion examples/fc22.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
$ORMask = 0x0007; // 2 bytes, bin = 0b00000111
$ORMask &= ~(1 << $bitPosition); // clear the bit, set third bit to 0. $ORMask = 0x0003, 0b00000011

$unitID = 0;
$unitID = 1;
$packet = new MaskWriteRegisterRequest(
$readStartAddress,
$ANDMask,
Expand Down
2 changes: 1 addition & 1 deletion examples/fc23.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
Types::toInt16(10), //000a as word
Types::toInt16(-1000), //hex: FC18 as word
];
$unitID = 0;
$unitID = 1;
$packet = new ReadWriteMultipleRegistersRequest(
$readStartAddress,
$readQuantity,
Expand Down
2 changes: 1 addition & 1 deletion examples/fc3.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

$startAddress = 256;
$quantity = 6;
$unitID = 0;
$unitID = 1;
$packet = new ReadHoldingRegistersRequest($startAddress, $quantity, $unitID); // NB: This is Modbus TCP packet not Modbus RTU over TCP!

try {
Expand Down
2 changes: 1 addition & 1 deletion examples/fc4.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

$startAddress = 256;
$quantity = 6;
$unitID = 0;
$unitID = 1;
$packet = new ReadInputRegistersRequest($startAddress, $quantity, $unitID); // NB: This is Modbus TCP packet not Modbus RTU over TCP!
echo 'Packet to be sent (in hex): ' . $packet->toHex() . PHP_EOL;

Expand Down
2 changes: 1 addition & 1 deletion examples/fc5.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

$startAddress = 12288;
$coil = true;
$unitID = 0;
$unitID = 1;
$packet = new WriteSingleCoilRequest($startAddress, $coil, $unitID); // NB: This is Modbus TCP packet not Modbus RTU over TCP!
echo 'Packet to be sent (in hex): ' . $packet->toHex() . PHP_EOL;

Expand Down
2 changes: 1 addition & 1 deletion examples/fc6.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

$startAddress = 12288;
$value = 55;
$unitID = 0;
$unitID = 1;
$packet = new WriteSingleRegisterRequest($startAddress, $value, $unitID); // NB: This is Modbus TCP packet not Modbus RTU over TCP!
echo 'Packet to be sent (in hex): ' . $packet->toHex() . PHP_EOL;

Expand Down
8 changes: 6 additions & 2 deletions src/Packet/ModbusApplicationHeader.php
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,12 @@ private function validate(int $length, int $unitId, int|null $transactionId): vo
if (!$length || !($length > 0 && $length <= Types::MAX_VALUE_UINT16)) {
throw new InvalidArgumentException("length is not set or out of range (uint16): {$length}");
}
if (!($unitId >= 0 && $unitId <= 247)) {
throw new InvalidArgumentException("unitId is out of range (0-247): {$unitId}");
if (!($unitId >= 0 && $unitId <= 255)) {
// Older MODBUS specification limited unit ID (slave id) in range of 0-247)
// See "Modicon Modbus Protocol Reference Guide PI–MBUS–300 Rev. J" page 19
//
// but newer spec has that limitation removed.
throw new InvalidArgumentException("unitId is out of range (0-255): {$unitId}");
}
if ((null !== $transactionId) && !($transactionId >= 0 && $transactionId <= Types::MAX_VALUE_UINT16)) {
throw new InvalidArgumentException("transactionId is out of range (uint16): {$transactionId}");
Expand Down
6 changes: 3 additions & 3 deletions tests/unit/Packet/ModbusApplicationHeaderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,15 +82,15 @@ public function testLengthOverFlow()

public function testUnitIdOverFlow()
{
$this->expectExceptionMessage("unitId is out of range (0-247): 248");
$this->expectExceptionMessage("unitId is out of range (0-255): 256");
$this->expectException(InvalidArgumentException::class);

new ModbusApplicationHeader(1, 248, 1);
new ModbusApplicationHeader(1, 256, 1);
}

public function testUnitIdUnderFlow()
{
$this->expectExceptionMessage("unitId is out of range (0-247): -1");
$this->expectExceptionMessage("unitId is out of range (0-255): -1");
$this->expectException(InvalidArgumentException::class);

new ModbusApplicationHeader(1, -1, 1);
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/Packet/ProtocolDataUnitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public function testValidation()

public function testFailWithNegativeUnitID()
{
$this->expectExceptionMessage("unitId is out of range (0-247): -1");
$this->expectExceptionMessage("unitId is out of range (0-255): -1");
$this->expectException(InvalidArgumentException::class);

new ProtocolDataUnitImpl(-1);
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/Utils/TypesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ public function testShouldSeeIfBitIsNotSet()

public function testShouldExceptionWhenBitToHighNumber()
{
$this->expectErrorMessageMatches("/On .*bit PHP bit shifting more than .* bit is not possible as int size is .* bytes/");
$this->expectExceptionMessageMatches("/On .*bit PHP bit shifting more than .* bit is not possible as int size is .* bytes/");
$this->expectException(InvalidArgumentException::class);

if (PHP_INT_SIZE === 4) {
Expand Down

0 comments on commit d4a7345

Please sign in to comment.