7 Commits
Author SHA1 Message Date
MightyPork fd2ae72b79 use timeout in socket_recv fail loop 2017-09-02 14:35:28 +02:00
MightyPork 4256b6cef7 fixed the examples 2016-11-20 11:29:09 +01:00
MightyPork 61e7a690eb Minor cleanup, removed duplicate timeout vars & replaced with float [sec], added socket Tout setter 2016-11-18 16:06:15 +01:00
toimtoimtoim 7365700b72 cleanup 2016-11-05 18:00:41 +02:00
toimtoimtoim cff8493205 refactor timeout_usec to millisecond precision and add setter for ms. 2016-11-05 17:57:19 +02:00
toimtoimtoim e10bb250d8 Use microsecond precision instead of second for timeout when reading from sockets.
Expose variables to configure socket read and write timeouts in  sec and usec (microseconds) precision
2016-11-04 22:02:04 +02:00
MightyPork c18696a718 added myself to composer json 2016-03-11 23:11:21 +01:00
15 changed files with 302 additions and 232 deletions
+23 -10
View File
@@ -2,15 +2,15 @@
Implementation of the basic functionality of the Modbus TCP and UDP based protocol using PHP. Implementation of the basic functionality of the Modbus TCP and UDP based protocol using PHP.
This is a fork of the original project at https://code.google.com/p/phpmodbus/ **NOTE: This is a fork to fix & update the library code (and code alone). Notably, the tests are probably all broken.**
> **What's new** > **What's new**
> >
> This fork adds a namespace and fixes issues encountered when porting to PHP 7 > This fork adds a namespace and fixes issues encountered when porting to PHP 7
**WARNING: Everything except the actual code in this repo may be broken and outdated.**
Implemented features: ## Implemented features
* Modbus master * Modbus master
* FC1 - Read coils * FC1 - Read coils
* FC2 - Read input discretes * FC2 - Read input discretes
@@ -22,18 +22,24 @@ Implemented features:
* FC16 - Write multiple registers * FC16 - Write multiple registers
* FC23 - Read/Write multiple registers * FC23 - Read/Write multiple registers
Example:
## Requirements
* The PHP extension php_sockets.dll should be enabled (server php.ini file)
## Example
```php ```php
require_once dirname(__FILE__) . '/Phpmodbus/ModbusMaster.php'; use PHPModbus/ModbusMaster;
use PHPModbus/PhpType;
// Modbus master UDP // Modbus master UDP
$modbus = new ModbusMaster("192.168.1.1", "UDP"); $modbus = new ModbusMaster("192.168.1.1", "UDP");
// Read multiple registers // Read multiple registers
try { try {
$recData = $modbus->readMultipleRegisters(0, 12288, 5); $recData = $modbus->readMultipleRegisters(0, 12288, 5);
} } catch (Exception $e) {
catch (Exception $e) {
// Print error information if any // Print error information if any
echo $modbus; echo $modbus;
echo $e; echo $e;
@@ -43,7 +49,14 @@ catch (Exception $e) {
echo PhpType::bytes2string($recData); echo PhpType::bytes2string($recData);
``` ```
For more see [http://code.google.com/p/phpmodbus/downloads/list documentation] or [http://code.google.com/p/phpmodbus/wiki/FAQ FAQ]. Use the `setTimeout($seconds)` and `setSocketTimeout($read_timeout_sec, $write_timeout_sec)` methods to adjust wait times.
Most of the code is (to some extent) commented and documented with PhpDoc. You should get useful tooltips in your IDE.
## GoogleCode legacy docs & downloads
This project was originally hosted on (now defunct) Google Code. It's still archived here:
* [GoogleCode Archived Repo](http://code.google.com/p/phpmodbus)
Note:
* The PHP extension php_sockets.dll should be enabled (server php.ini file)
+4
View File
@@ -11,6 +11,10 @@
{ {
"name": "Honza Krakora", "name": "Honza Krakora",
"email": "krakora.jan@googlemail.com" "email": "krakora.jan@googlemail.com"
},
{
"name": "Ondřej Hruška",
"email": "ondra@ondrovo.com"
} }
], ],
"autoload": { "autoload": {
+12 -14
View File
@@ -1,6 +1,6 @@
<?php <?php
require_once dirname(__FILE__) . '/../Phpmodbus/ModbusMaster.php'; use PHPModbus\ModbusMaster;
// Create Modbus object // Create Modbus object
$ip = "192.192.15.51"; $ip = "192.192.15.51";
@@ -13,8 +13,7 @@ try {
$mw0address = 12288; $mw0address = 12288;
$quantity = 6; $quantity = 6;
$recData = $modbus->readMultipleRegisters($moduleId, $reference, $quantity); $recData = $modbus->readMultipleRegisters($moduleId, $reference, $quantity);
} } catch (Exception $e) {
catch (Exception $e) {
echo $modbus; echo $modbus;
echo $e; echo $e;
exit; exit;
@@ -31,10 +30,10 @@ catch (Exception $e) {
<h1>Dump of M-memory from WAGO 750-84x series coupler.</h1> <h1>Dump of M-memory from WAGO 750-84x series coupler.</h1>
<ul> <ul>
<li>PLC: 750-84x series</li> <li>PLC: 750-84x series</li>
<li>IP: <?php echo $ip?></li> <li>IP: <?php echo $ip ?></li>
<li>Modbus module ID: <?php echo $moduleId?></li> <li>Modbus module ID: <?php echo $moduleId ?></li>
<li>Modbus memory reference: <?php echo $reference?></li> <li>Modbus memory reference: <?php echo $reference ?></li>
<li>Modbus memory quantity: <?php echo $quantity?></li> <li>Modbus memory quantity: <?php echo $quantity ?></li>
</ul> </ul>
<h2>M-memory dump</h2> <h2>M-memory dump</h2>
@@ -46,12 +45,12 @@ catch (Exception $e) {
<td>value</td> <td>value</td>
</tr> </tr>
<?php <?php
for($i=0;$i<count($recData);$i+=2) { for ($i = 0; $i < count($recData); $i += 2) {
?> ?>
<tr> <tr>
<td><?php echo $i+$reference?></td> <td><?php echo $i + $reference ?></td>
<td>MW<?php echo ($i + $reference - $mw0address)/2?></td> <td>MW<?php echo ($i + $reference - $mw0address) / 2 ?></td>
<td><?php echo ($recData[$i] << 8)+ $recData[$i+1]?></td> <td><?php echo ($recData[$i] << 8) + $recData[$i + 1] ?></td>
</tr> </tr>
<?php <?php
} }
@@ -59,9 +58,8 @@ catch (Exception $e) {
</table> </table>
<h2>Modbus class status</h2> <h2>Modbus class status</h2>
<?php
echo $modbus; <pre><?= $modbus ?></pre>
?>
</body> </body>
</html> </html>
+8 -9
View File
@@ -1,6 +1,7 @@
<?php <?php
require_once dirname(__FILE__) . '/../Phpmodbus/ModbusMaster.php'; use PHPModbus\ModbusMaster;
use PHPModbus\PhpType;
// Create Modbus object // Create Modbus object
$modbus = new ModbusMaster("192.192.15.51", "UDP"); $modbus = new ModbusMaster("192.192.15.51", "UDP");
@@ -9,8 +10,7 @@ try {
// FC 3 // FC 3
// read 10 words (20 bytes) from device ID=0, address=12288 // read 10 words (20 bytes) from device ID=0, address=12288
$recData = $modbus->readMultipleRegisters(0, 12288, 10); $recData = $modbus->readMultipleRegisters(0, 12288, 10);
} } catch (Exception $e) {
catch (Exception $e) {
// Print error information if any // Print error information if any
echo $modbus; echo $modbus;
echo $e; echo $e;
@@ -28,17 +28,17 @@ $values = array_chunk($recData, 4);
// Get float from REAL interpretation // Get float from REAL interpretation
echo "<h3>REAL to Float</h3>\n"; echo "<h3>REAL to Float</h3>\n";
foreach($values as $bytes) foreach ($values as $bytes)
echo PhpType::bytes2float($bytes) . "</br>"; echo PhpType::bytes2float($bytes) . "</br>";
// Get integer from DINT interpretation // Get integer from DINT interpretation
echo "<h3>DINT to integer </h3>\n"; echo "<h3>DINT to integer </h3>\n";
foreach($values as $bytes) foreach ($values as $bytes)
echo PhpType::bytes2signedInt($bytes) . "</br>"; echo PhpType::bytes2signedInt($bytes) . "</br>";
// Get integer of float from DINT interpretation // Get integer of float from DINT interpretation
echo "<h3>DWORD to integer (or float) </h3>\n"; echo "<h3>DWORD to integer (or float) </h3>\n";
foreach($values as $bytes) foreach ($values as $bytes)
echo PhpType::bytes2unsignedInt($bytes) . "</br>"; echo PhpType::bytes2unsignedInt($bytes) . "</br>";
echo "<h2>16 bit types</h2>\n"; echo "<h2>16 bit types</h2>\n";
@@ -47,15 +47,14 @@ $values = array_chunk($recData, 2);
// Get signed integer from INT interpretation // Get signed integer from INT interpretation
echo "<h3>INT to integer </h3>\n"; echo "<h3>INT to integer </h3>\n";
foreach($values as $bytes) foreach ($values as $bytes)
echo PhpType::bytes2signedInt($bytes) . "</br>"; echo PhpType::bytes2signedInt($bytes) . "</br>";
// Get unsigned integer from WORD interpretation // Get unsigned integer from WORD interpretation
echo "<h3>WORD to integer </h3>\n"; echo "<h3>WORD to integer </h3>\n";
foreach($values as $bytes) foreach ($values as $bytes)
echo PhpType::bytes2unsignedInt($bytes) . "</br>"; echo PhpType::bytes2unsignedInt($bytes) . "</br>";
// Get string from STRING interpretation // Get string from STRING interpretation
echo "<h3>STRING to string </h3>\n"; echo "<h3>STRING to string </h3>\n";
echo PhpType::bytes2string($recData) . "</br>"; echo PhpType::bytes2string($recData) . "</br>";
?>
+2 -3
View File
@@ -1,6 +1,6 @@
<?php <?php
require_once dirname(__FILE__) . '/../Phpmodbus/ModbusMaster.php'; use PHPModbus\ModbusMaster;
// Create Modbus object // Create Modbus object
$modbus = new ModbusMaster("192.192.15.51", "UDP"); $modbus = new ModbusMaster("192.192.15.51", "UDP");
@@ -8,8 +8,7 @@ $modbus = new ModbusMaster("192.192.15.51", "UDP");
try { try {
// FC 1 // FC 1
$recData = $modbus->readCoils(0, 12288, 12); $recData = $modbus->readCoils(0, 12288, 12);
} } catch (Exception $e) {
catch (Exception $e) {
// Print error information if any // Print error information if any
echo $modbus; echo $modbus;
echo $e; echo $e;
+9 -8
View File
@@ -1,21 +1,22 @@
<?php <?php
require_once dirname(__FILE__) . '/../Phpmodbus/ModbusMaster.php'; use PHPModbus\ModbusMaster;
// Create Modbus object // Create Modbus object
$modbus = new ModbusMaster("192.192.15.51", "UDP"); $modbus = new ModbusMaster("192.192.15.51", "UDP");
// Data to be writen // Data to be written - supports both 0/1 and booleans (true, false)
$data = array(TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, $data = array(
TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, 1, 0, 1, 1, 0, 1, 1, 1,
FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, 1, 1, 1, 1, 0, 0, 0, 0,
TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE); 0, 0, 0, 0, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
);
try { try {
// FC15 // FC15
$modbus->writeMultipleCoils(0, 12288, $data); $modbus->writeMultipleCoils(0, 12288, $data);
} } catch (Exception $e) {
catch (Exception $e) {
// Print error information if any // Print error information if any
echo $modbus; echo $modbus;
echo $e; echo $e;
+2 -3
View File
@@ -1,6 +1,6 @@
<?php <?php
require_once dirname(__FILE__) . '/../Phpmodbus/ModbusMaster.php'; use PHPModbus\ModbusMaster;
// Create Modbus object // Create Modbus object
$modbus = new ModbusMaster("192.192.15.51", "UDP"); $modbus = new ModbusMaster("192.192.15.51", "UDP");
@@ -12,8 +12,7 @@ $dataTypes = array("WORD", "INT", "DINT", "REAL");
try { try {
// FC16 // FC16
$modbus->writeMultipleRegister(0, 12288, $data, $dataTypes); $modbus->writeMultipleRegister(0, 12288, $data, $dataTypes);
} } catch (Exception $e) {
catch (Exception $e) {
// Print error information if any // Print error information if any
echo $modbus; echo $modbus;
echo $e; echo $e;
+2 -3
View File
@@ -1,6 +1,6 @@
<?php <?php
require_once dirname(__FILE__) . '/../Phpmodbus/ModbusMaster.php'; use PHPModbus\ModbusMaster;
// Create Modbus object // Create Modbus object
$modbus = new ModbusMaster("192.192.15.51", "UDP"); $modbus = new ModbusMaster("192.192.15.51", "UDP");
@@ -9,8 +9,7 @@ try {
// FC 2 // FC 2
// read 2 input bits from address 0x0 (Wago input image) // read 2 input bits from address 0x0 (Wago input image)
$recData = $modbus->readInputDiscretes(0, 0, 2); $recData = $modbus->readInputDiscretes(0, 0, 2);
} } catch (Exception $e) {
catch (Exception $e) {
// Print error information if any // Print error information if any
echo $modbus; echo $modbus;
echo $e; echo $e;
+4 -7
View File
@@ -1,6 +1,6 @@
<?php <?php
require_once dirname(__FILE__) . '/../Phpmodbus/ModbusMaster.php'; use PHPModbus\ModbusMaster;
// Create Modbus object // Create Modbus object
$modbus = new ModbusMaster("192.192.15.51", "UDP"); $modbus = new ModbusMaster("192.192.15.51", "UDP");
@@ -8,14 +8,13 @@ $modbus = new ModbusMaster("192.192.15.51", "UDP");
// Data to be writen // Data to be writen
$bitValue = true; $bitValue = true;
$bitNumber = 2; $bitNumber = 2;
$andMask = 0xFFFF ^ pow(2, $bitNumber) ; $andMask = 0xFFFF ^ pow(2, $bitNumber);
$orMask = 0x0000 ^ (pow(2, $bitNumber) * $bitValue ) ; $orMask = 0x0000 ^ (pow(2, $bitNumber) * $bitValue);
try { try {
// FC22 // FC22
$modbus->maskWriteRegister(0, 12288, $andMask, $orMask); $modbus->maskWriteRegister(0, 12288, $andMask, $orMask);
} } catch (Exception $e) {
catch (Exception $e) {
// Print error information if any // Print error information if any
echo $modbus; echo $modbus;
echo $e; echo $e;
@@ -24,5 +23,3 @@ catch (Exception $e) {
// Print status information // Print status information
echo $modbus; echo $modbus;
?>
+2 -5
View File
@@ -1,6 +1,6 @@
<?php <?php
require_once dirname(__FILE__) . '/../Phpmodbus/ModbusMaster.php'; use PHPModbus\ModbusMaster;
// Create Modbus object // Create Modbus object
$modbus = new ModbusMaster("192.192.15.51", "UDP"); $modbus = new ModbusMaster("192.192.15.51", "UDP");
@@ -12,8 +12,7 @@ $dataTypes = array("WORD", "INT", "DINT", "REAL");
try { try {
// FC23 // FC23
$recData = $modbus->readWriteRegisters(0, 12288, 6, 12288, $data, $dataTypes); $recData = $modbus->readWriteRegisters(0, 12288, 6, 12288, $data, $dataTypes);
} } catch (Exception $e) {
catch (Exception $e) {
// Print error information if any // Print error information if any
echo $modbus; echo $modbus;
echo $e; echo $e;
@@ -27,5 +26,3 @@ echo "</br>Status:</br>" . $modbus;
echo "</br>Data:</br>"; echo "</br>Data:</br>";
print_r($recData); print_r($recData);
echo "</br>"; echo "</br>";
?>
+2 -4
View File
@@ -1,6 +1,6 @@
<?php <?php
require_once dirname(__FILE__) . '/../Phpmodbus/ModbusMaster.php'; use PHPModbus\ModbusMaster;
// Create Modbus object // Create Modbus object
$modbus = new ModbusMaster("192.192.15.51", "UDP"); $modbus = new ModbusMaster("192.192.15.51", "UDP");
@@ -8,8 +8,7 @@ $modbus = new ModbusMaster("192.192.15.51", "UDP");
try { try {
// FC 3 // FC 3
$recData = $modbus->readMultipleRegisters(0, 12288, 6); $recData = $modbus->readMultipleRegisters(0, 12288, 6);
} } catch (Exception $e) {
catch (Exception $e) {
// Print error information if any // Print error information if any
echo $modbus; echo $modbus;
echo $e; echo $e;
@@ -23,4 +22,3 @@ echo "</br>Status:</br>" . $modbus;
echo "</br>Data:</br>"; echo "</br>Data:</br>";
print_r($recData); print_r($recData);
echo "</br>"; echo "</br>";
?>
+2 -3
View File
@@ -1,6 +1,6 @@
<?php <?php
require_once dirname(__FILE__) . '/../../Phpmodbus/ModbusMasterUdp.php'; use PHPModbus\ModbusMasterUdp;
// Create Modbus object // Create Modbus object
$modbus = new ModbusMasterUdp("192.192.15.51"); $modbus = new ModbusMasterUdp("192.192.15.51");
@@ -8,8 +8,7 @@ $modbus = new ModbusMasterUdp("192.192.15.51");
try { try {
// Read input discretes - FC 4 // Read input discretes - FC 4
$recData = $modbus->readMultipleInputRegisters(0, 0, 2); $recData = $modbus->readMultipleInputRegisters(0, 0, 2);
} } catch (Exception $e) {
catch (Exception $e) {
// Print error information if any // Print error information if any
echo $modbus; echo $modbus;
echo $e; echo $e;
+4 -5
View File
@@ -1,13 +1,13 @@
<?php <?php
require_once dirname(__FILE__) . '/../../Phpmodbus/ModbusMasterUdp.php'; use PHPModbus\ModbusMasterUdp;
// Create Modbus object // Create Modbus object
$modbus = new ModbusMasterUdp("192.192.15.51"); $modbus = new ModbusMasterUdp("192.192.15.51");
// Data to be writen - TRUE, FALSE // Data to be writen - TRUE, FALSE
$data_true = array(TRUE); $data_true = array(true);
$data_false = array(FALSE); $data_false = array(false);
try { try {
// Write single coil - FC5 // Write single coil - FC5
@@ -15,8 +15,7 @@ try {
$modbus->writeSingleCoil(0, 12289, $data_false); $modbus->writeSingleCoil(0, 12289, $data_false);
$modbus->writeSingleCoil(0, 12290, $data_true); $modbus->writeSingleCoil(0, 12290, $data_true);
$modbus->writeSingleCoil(0, 12291, $data_false); $modbus->writeSingleCoil(0, 12291, $data_false);
} } catch (Exception $e) {
catch (Exception $e) {
// Print error information if any // Print error information if any
echo $modbus; echo $modbus;
echo $e; echo $e;
+3 -7
View File
@@ -1,19 +1,17 @@
<?php <?php
require_once dirname(__FILE__) . '/../Phpmodbus/ModbusMaster.php'; use PHPModbus\ModbusMaster;
// Create Modbus object // Create Modbus object
$modbus = new ModbusMaster("192.192.15.51", "UDP"); $modbus = new ModbusMaster("192.192.15.51", "UDP");
// Data to be writen // Data to be writen
$data = array(-1000); $data = array(-1000);
$dataTypes = array("INT");
try { try {
// FC6 // FC6
$modbus->writeSingleRegister(0, 12288, $data, $dataTypes); $modbus->writeSingleRegister(0, 12288, $data);
} } catch (Exception $e) {
catch (Exception $e) {
// Print error information if any // Print error information if any
echo $modbus; echo $modbus;
echo $e; echo $e;
@@ -22,5 +20,3 @@ catch (Exception $e) {
// Print status information // Print status information
echo $modbus; echo $modbus;
?>
+95 -23
View File
@@ -45,23 +45,38 @@ use Exception;
*/ */
class ModbusMaster class ModbusMaster
{ {
/** @var resource Communication socket */
private $sock; private $sock;
/** @var string Modbus device IP address */
public $host = "192.168.1.1"; public $host = "192.168.1.1";
public $port = "502"; /** @var string gateway port */
public $port = 502;
public $client = ""; /** @var string (optional) client IP address */
public $client = ""; // TODO explanation?
public $client_port = "502"; /** @var string client port */
public $client_port = 502;
/** @var string ModbusMaster status messages (echo for debugging) */
public $status; public $status;
public $timeout_sec = 5; // Timeout 5 sec /** @var float Total response timeout (seconds, decimals allowed) */
public $timeout_sec = 3;
public $endianness = 0; // Endianness codding (little endian == 0, big endian == 1) /** @var float Socket read timeout (seconds, decimals allowed) */
public $socket_read_timeout_sec = 0.3; // 300 ms
public $socket_protocol = "UDP"; // Socket protocol (TCP, UDP) /** @var float Socket write timeout (seconds, decimals allowed) */
public $socket_write_timeout_sec = 1;
/** @var int Endianness codding (0 = little endian = 0, 1 = big endian) */
public $endianness = 0; //
/** @var string Socket protocol (TCP, UDP) */
public $socket_protocol = "UDP";
/** /**
* ModbusMaster * ModbusMaster
@@ -87,6 +102,22 @@ class ModbusMaster
return "<pre>" . $this->status . "</pre>"; return "<pre>" . $this->status . "</pre>";
} }
/**
* Convert float in seconds to array
*
* @param float $secs
* @return array {sec: ..., usec: ...}
*/
private function secsToSecUsecArray($secs)
{
$remainder = $secs - floor($secs);
return [
'sec' => round($secs - $remainder),
'usec' => round($remainder * 1e6),
];
}
/** /**
* connect * connect
* *
@@ -111,18 +142,21 @@ class ModbusMaster
if (strlen($this->client) > 0) { if (strlen($this->client) > 0) {
$result = socket_bind($this->sock, $this->client, $this->client_port); $result = socket_bind($this->sock, $this->client, $this->client_port);
if ($result === false) { if ($result === false) {
throw new Exception("socket_bind() failed.</br>Reason: ($result)" . throw new Exception("socket_bind() failed. Reason: ($result)" .
socket_strerror(socket_last_error($this->sock))); socket_strerror(socket_last_error($this->sock)));
} else { } else {
$this->status .= "Bound\n"; $this->status .= "Bound\n";
} }
} }
// Socket settings
socket_set_option($this->sock, SOL_SOCKET, SO_SNDTIMEO, array('sec' => 1, 'usec' => 0)); // Socket settings (send/write timeout)
$writeTimeout = $this->secsToSecUsecArray($this->socket_write_timeout_sec);
socket_set_option($this->sock, SOL_SOCKET, SO_SNDTIMEO, $writeTimeout);
// Connect the socket // Connect the socket
$result = @socket_connect($this->sock, $this->host, $this->port); $result = @socket_connect($this->sock, $this->host, $this->port);
if ($result === false) { if ($result === false) {
throw new Exception("socket_connect() failed.</br>Reason: ($result)" . throw new Exception("socket_connect() failed. Reason: ($result)" .
socket_strerror(socket_last_error($this->sock))); socket_strerror(socket_last_error($this->sock)));
} else { } else {
$this->status .= "Connected\n"; $this->status .= "Connected\n";
@@ -169,20 +203,26 @@ class ModbusMaster
$writesocks = null; $writesocks = null;
$exceptsocks = null; $exceptsocks = null;
$rec = ""; $rec = "";
$lastAccess = time(); $totalReadTimeout = $this->timeout_sec;
while (socket_select($readsocks, $writesocks, $exceptsocks, 0, 300000) !== false) { $lastAccess = microtime(true);
$this->status .= "Wait data ... \n"; $readStart = microtime(true);
$readTout = $this->secsToSecUsecArray($this->socket_read_timeout_sec);
while (false !== socket_select($readsocks, $writesocks, $exceptsocks, $readTout['sec'], $readTout['usec'])) {
if (in_array($this->sock, $readsocks)) { if (in_array($this->sock, $readsocks)) {
while (@socket_recv($this->sock, $rec, 2000, 0)) { if ($recn = @socket_recv($this->sock, $rec, 2000, 0)) { // read max 2000 bytes
$this->status .= "Data received\n"; $this->status .= "Data received \n";
return $rec; return $rec;
} }
$lastAccess = time(); $lastAccess = microtime(true);
if (microtime(true) - $readStart > $totalReadTimeout) {
throw new Exception("Read timed out, last error: " . socket_strerror(socket_last_error($this->sock)));
}
} else { } else {
if (time() - $lastAccess >= $this->timeout_sec) { $timeSpentWaiting = microtime(true) - $lastAccess;
throw new Exception("Watchdog time expired [ " . if ($timeSpentWaiting >= $totalReadTimeout) {
$this->timeout_sec . " sec]!!! Connection to " . throw new Exception(
$this->host . " is not established."); "Watchdog time expired [ $totalReadTimeout sec ]!!! " .
"Connection to $this->host:$this->port is not established.");
} }
} }
$readsocks[] = $this->sock; $readsocks[] = $this->sock;
@@ -215,7 +255,7 @@ class ModbusMaster
0x06 => "SLAVE DEVICE BUSY", 0x06 => "SLAVE DEVICE BUSY",
0x08 => "MEMORY PARITY ERROR", 0x08 => "MEMORY PARITY ERROR",
0x0A => "GATEWAY PATH UNAVAILABLE", 0x0A => "GATEWAY PATH UNAVAILABLE",
0x0B => "GATEWAY TARGET DEVICE FAILED TO RESPOND" 0x0B => "GATEWAY TARGET DEVICE FAILED TO RESPOND",
); );
// get failure string // get failure string
if (key_exists($failure_code, $failures)) { if (key_exists($failure_code, $failures)) {
@@ -1277,7 +1317,8 @@ class ModbusMaster
$referenceWrite, $referenceWrite,
$data, $data,
$dataTypes $dataTypes
) { )
{
$dataLen = 0; $dataLen = 0;
// build data section // build data section
$buffer1 = ""; $buffer1 = "";
@@ -1324,7 +1365,7 @@ class ModbusMaster
* FC23 response parser * FC23 response parser
* *
* @param string $packet * @param string $packet
* @return array * @return array|false
*/ */
private function readWriteRegistersParser($packet) private function readWriteRegistersParser($packet)
{ {
@@ -1373,4 +1414,35 @@ class ModbusMaster
$str .= "\n"; $str .= "\n";
return $str; return $str;
} }
/**
* Set data receive timeout.
* Writes property timeout_sec
*
* @param float $seconds seconds
*/
public function setTimeout($seconds)
{
$this->timeout_sec = $seconds;
}
/**
* Set socket read/write timeout. Null = no change.
*
* @param float|null $read_timeout_sec data read timeout (seconds, default 0.3)
* @param float|null $write_timeout_sec data write timeout (seconds, default 1.0)
* @internal param float $seconds seconds
*/
public function setSocketTimeout($read_timeout_sec, $write_timeout_sec)
{
// Set read timeout if given
if ($read_timeout_sec !== null) {
$this->socket_read_timeout_sec = $read_timeout_sec;
}
// Set write timeout if given
if ($write_timeout_sec !== null) {
$this->socket_write_timeout_sec = $write_timeout_sec;
}
}
} }