8 Commits
20 changed files with 1992 additions and 1845 deletions
+1
View File
@@ -1,4 +1,5 @@
/vendor /vendor
composer.lock composer.lock
.idea/
*~ *~
+32 -19
View File
@@ -2,38 +2,44 @@
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
* FC3 - Read holding registers * FC3 - Read holding registers
* FC4 - Read holding input registers * FC4 - Read holding input registers
* FC5 - Write single coil * FC5 - Write single coil
* FC6 - Write single register * FC6 - Write single register
* FC15 - Write multiple coils * FC15 - Write multiple coils
* 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)
+5 -1
View File
@@ -1,5 +1,5 @@
{ {
"name": "MightyPork/phpmodbus", "name": "mightypork/phpmodbus",
"keywords": ["phpmodbus","modbus"], "keywords": ["phpmodbus","modbus"],
"description": "PhpModbus with namespaces and updated to PHP 7", "description": "PhpModbus with namespaces and updated to PHP 7",
"license": "LGPL", "license": "LGPL",
@@ -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": {
+49 -51
View File
@@ -1,67 +1,65 @@
<?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";
$modbus = new ModbusMaster($ip, "UDP"); $modbus = new ModbusMaster($ip, "UDP");
try { try {
// FC 3 // FC 3
$moduleId = 0; $moduleId = 0;
$reference = 12288; $reference = 12288;
$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;
} }
?> ?>
<html> <html>
<head> <head>
<meta http-equiv="content-type" content="text/html; charset=windows-1250"> <meta http-equiv="content-type" content="text/html; charset=windows-1250">
<meta name="generator" content="PSPad editor, www.pspad.com"> <meta name="generator" content="PSPad editor, www.pspad.com">
<title>WAGO 750-841 M-memory dump</title> <title>WAGO 750-841 M-memory dump</title>
</head> </head>
<body> <body>
<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>
<table border="1px" width="400px"> <table border="1px" width="400px">
<tr> <tr>
<td>Modbus address</td> <td>Modbus address</td>
<td>MWx</td> <td>MWx</td>
<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
} }
?> ?>
</table> </table>
<h2>Modbus class status</h2> <h2>Modbus class status</h2>
<?php
echo $modbus;
?>
</body> <pre><?= $modbus ?></pre>
</html>
</body>
</html>
+20 -21
View File
@@ -1,20 +1,20 @@
<?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");
try { 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; exit;
exit;
} }
// Received data // Received data
@@ -28,18 +28,18 @@ $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";
// Chunk the data array to set of 4 bytes // Chunk the data array to set of 4 bytes
@@ -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>";
?>
+10 -11
View File
@@ -1,19 +1,18 @@
<?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");
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; exit;
exit;
} }
// Print status information // Print status information
@@ -21,5 +20,5 @@ echo "</br>Status:</br>" . $modbus;
// Print read data // Print read data
echo "</br>Data:</br>"; echo "</br>Data:</br>";
var_dump($recData); var_dump($recData);
echo "</br>"; echo "</br>";
+15 -14
View File
@@ -1,25 +1,26 @@
<?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; exit;
exit;
} }
// Print status information // Print status information
+9 -10
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");
@@ -10,17 +10,16 @@ $data = array(10, -1000, 2000, 3.0);
$dataTypes = array("WORD", "INT", "DINT", "REAL"); $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; exit;
exit;
} }
// Print status information // Print status information
echo $modbus; echo $modbus;
?> ?>
+11 -12
View File
@@ -1,20 +1,19 @@
<?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");
try { 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; exit;
exit;
} }
// Print status information // Print status information
@@ -22,5 +21,5 @@ echo "</br>Status:</br>" . $modbus;
// Print read data // Print read data
echo "</br>Data:</br>"; echo "</br>Data:</br>";
var_dump($recData); var_dump($recData);
echo "</br>"; echo "</br>";
+10 -13
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,21 +8,18 @@ $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; exit;
exit;
} }
// Print status information // Print status information
echo $modbus; echo $modbus;
?>
+8 -11
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");
@@ -10,14 +10,13 @@ $data = array(10, -1000, 2000, 3.0);
$dataTypes = array("WORD", "INT", "DINT", "REAL"); $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; exit;
exit;
} }
// Print status information // Print status information
@@ -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>";
?>
+9 -11
View File
@@ -1,19 +1,18 @@
<?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");
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; exit;
exit;
} }
// Print status information // Print status information
@@ -21,6 +20,5 @@ echo "</br>Status:</br>" . $modbus;
// Print read data // Print read data
echo "</br>Data:</br>"; echo "</br>Data:</br>";
print_r($recData); print_r($recData);
echo "</br>"; echo "</br>";
?>
+9 -10
View File
@@ -1,19 +1,18 @@
<?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");
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; exit;
exit;
} }
var_dump($recData); var_dump($recData);
+13 -14
View File
@@ -1,24 +1,23 @@
<?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
$modbus->writeSingleCoil(0, 12288, $data_true); $modbus->writeSingleCoil(0, 12288, $data_true);
$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; exit;
exit;
} }
+8 -12
View File
@@ -1,26 +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 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; exit;
exit;
} }
// Print status information // Print status information
echo $modbus; echo $modbus;
?>
+114 -109
View File
@@ -8,12 +8,12 @@ namespace PHPModbus;
* This source file is subject to the "PhpModbus license" that is bundled * This source file is subject to the "PhpModbus license" that is bundled
* with this package in the file license.txt. * with this package in the file license.txt.
* *
* @author Jan Krakora * @author Jan Krakora
* @copyright Copyright (c) 2004, 2013 Jan Krakora * @copyright Copyright (c) 2004, 2013 Jan Krakora
* @license PhpModbus license * @license PhpModbus license
* @category Phpmodbus * @category Phpmodbus
* @package Phpmodbus * @package Phpmodbus
* @version $id$ * @version $id$
*/ */
/** /**
@@ -22,115 +22,120 @@ namespace PHPModbus;
* The class includes set of IEC-1131 data type functions that converts a PHP * The class includes set of IEC-1131 data type functions that converts a PHP
* data types to a IEC data type. * data types to a IEC data type.
* *
* @author Jan Krakora * @author Jan Krakora
* @copyright Copyright (c) 2004, 2010 Jan Krakora * @copyright Copyright (c) 2004, 2010 Jan Krakora
* @package Phpmodbus * @package Phpmodbus
*/ */
class IecType { class IecType
{
/**
* iecBYTE
*
* Converts a value to IEC-1131 BYTE data type
*
* @param int $value from 0 to 255
* @return int IEC BYTE data type
*
*/
public static function iecBYTE($value)
{
return chr($value & 0xFF);
}
/** /**
* iecBYTE * iecINT
* *
* Converts a value to IEC-1131 BYTE data type * Converts a value to IEC-1131 INT data type
* *
* @param value value from 0 to 255 * @param int $value to be converted
* @return value IEC BYTE data type * @return int IEC-1131 INT data type
* *
*/ */
public static function iecBYTE($value) { public static function iecINT($value)
return chr($value & 0xFF); {
} return self::iecBYTE(($value >> 8) & 0x00FF) .
self::iecBYTE(($value & 0x00FF));
}
/** /**
* iecINT * iecDINT
* *
* Converts a value to IEC-1131 INT data type * Converts a value to IEC-1131 DINT data type
* *
* @param value value to be converted * @param int $value to be converted
* @return value IEC-1131 INT data type * @param int $bigEndian defines endian codding (little endian == 0, big endian == 1)
* * @return int IEC-1131 INT data type
*/ *
public static function iecINT($value) { */
return self::iecBYTE(($value >> 8) & 0x00FF) . public static function iecDINT($value, $bigEndian = 0)
self::iecBYTE(($value & 0x00FF)); {
} // result with right endianness
return self::endianness($value, $bigEndian);
}
/** /**
* iecDINT * iecREAL
* *
* Converts a value to IEC-1131 DINT data type * Converts a value to IEC-1131 REAL data type. The function uses function @use float2iecReal.
* *
* @param value value to be converted * @param int $value to be converted
* @param value endianness defines endian codding (little endian == 0, big endian == 1) * @param bool $bigEndian defines endian codding (little endian == 0, big endian == 1)
* @return value IEC-1131 INT data type * @return int IEC-1131 REAL data type
* */
*/ public static function iecREAL($value, $bigEndian = 0)
public static function iecDINT($value, $endianness = 0) { {
// result with right endianness // iecREAL representation
return self::endianness($value, $endianness); $real = self::float2iecReal($value);
} // result with right endianness
return self::endianness($real, $bigEndian);
}
/** /**
* iecREAL * float2iecReal
* *
* Converts a value to IEC-1131 REAL data type. The function uses function @use float2iecReal. * This function converts float value to IEC-1131 REAL single precision form.
* *
* @param value value to be converted * For more see [{@link http://en.wikipedia.org/wiki/Single_precision Single precision on Wiki}] or
* @param value endianness defines endian codding (little endian == 0, big endian == 1) * [{@link http://de.php.net/manual/en/function.base-convert.php PHP base_convert function commentary}, Todd Stokes
* @return value IEC-1131 REAL data type * @ Georgia Tech 21-Nov-2007] or
*/ * [{@link http://www.php.net/manual/en/function.pack.php PHP pack/unpack functionality}]
public static function iecREAL($value, $endianness = 0) { *
// iecREAL representation * @param float $value to be converted
$real = self::float2iecReal($value); * @return int IEC REAL data type
// result with right endianness */
return self::endianness($real, $endianness); private static function float2iecReal($value)
} {
// get float binary string
/** $float = pack("f", $value);
* float2iecReal // set 32-bit unsigned integer of the float
* $w = unpack("L", $float);
* This function converts float value to IEC-1131 REAL single precision form. return $w[1];
* }
* For more see [{@link http://en.wikipedia.org/wiki/Single_precision Single precision on Wiki}] or
* [{@link http://de.php.net/manual/en/function.base-convert.php PHP base_convert function commentary}, Todd Stokes @ Georgia Tech 21-Nov-2007] or
* [{@link http://www.php.net/manual/en/function.pack.php PHP pack/unpack functionality}]
*
* @param float value to be converted
* @return value IEC REAL data type
*/
private static function float2iecReal($value) {
// get float binary string
$float = pack("f", $value);
// set 32-bit unsigned integer of the float
$w = unpack("L", $float);
return $w[1];
}
/**
* endianness
*
* Make endianess as required.
* For more see http://en.wikipedia.org/wiki/Endianness
*
* @param int $value
* @param bool $endianness
* @return int
*/
private static function endianness($value, $endianness = 0) {
if ($endianness == 0)
return
self::iecBYTE(($value >> 8) & 0x000000FF) .
self::iecBYTE(($value & 0x000000FF)) .
self::iecBYTE(($value >> 24) & 0x000000FF) .
self::iecBYTE(($value >> 16) & 0x000000FF);
else
return
self::iecBYTE(($value >> 24) & 0x000000FF) .
self::iecBYTE(($value >> 16) & 0x000000FF) .
self::iecBYTE(($value >> 8) & 0x000000FF) .
self::iecBYTE(($value & 0x000000FF));
}
/**
* endianness
*
* Make endianess as required.
* For more see http://en.wikipedia.org/wiki/Endianness
*
* @param int $value
* @param bool $bigEndian
* @return int
*/
private static function endianness($value, $bigEndian = 0)
{
if ($bigEndian == 0) {
return
self::iecBYTE(($value >> 8) & 0x000000FF) .
self::iecBYTE(($value & 0x000000FF)) .
self::iecBYTE(($value >> 24) & 0x000000FF) .
self::iecBYTE(($value >> 16) & 0x000000FF);
} else {
return
self::iecBYTE(($value >> 24) & 0x000000FF) .
self::iecBYTE(($value >> 16) & 0x000000FF) .
self::iecBYTE(($value >> 8) & 0x000000FF) .
self::iecBYTE(($value & 0x000000FF));
}
}
} }
?>
+1386 -1258
View File
File diff suppressed because it is too large Load Diff
+26 -25
View File
@@ -4,47 +4,48 @@ namespace PHPModbus;
/** /**
* Phpmodbus Copyright (c) 2004, 2012 Jan Krakora * Phpmodbus Copyright (c) 2004, 2012 Jan Krakora
* *
* This source file is subject to the "PhpModbus license" that is bundled * This source file is subject to the "PhpModbus license" that is bundled
* with this package in the file license.txt. * with this package in the file license.txt.
* *
* *
* @copyright Copyright (c) 2004, 2012 Jan Krakora * @copyright Copyright (c) 2004, 2012 Jan Krakora
* @license PhpModbus license * @license PhpModbus license
* @category Phpmodbus * @category Phpmodbus
* @tutorial Phpmodbus.pkg * @tutorial Phpmodbus.pkg
* @package Phpmodbus * @package Phpmodbus
* @version $id$ * @version $id$
* *
*/ */
/** /**
* ModbusMasterTcp * ModbusMasterTcp
* *
* This class deals with the MODBUS master using TCP. Extends ModbusMaster class. * This class deals with the MODBUS master using TCP. Extends ModbusMaster class.
* *
* Implemented MODBUS functions: * Implemented MODBUS functions:
* - FC 1: read coils * - FC 1: read coils
* - FC 3: read multiple registers * - FC 3: read multiple registers
* - FC 15: write multiple coils * - FC 15: write multiple coils
* - FC 16: write multiple registers * - FC 16: write multiple registers
* - FC 23: read write registers * - FC 23: read write registers
* *
* @author Jan Krakora * @author Jan Krakora
* @copyright Copyright (c) 2004, 2012 Jan Krakora * @copyright Copyright (c) 2004, 2012 Jan Krakora
* @package Phpmodbus * @package Phpmodbus
* *
*/ */
class ModbusMasterTcp extends ModbusMaster { class ModbusMasterTcp extends ModbusMaster
/** {
* ModbusMasterTcp /**
* * ModbusMasterTcp
* This is the constructor that defines {@link $host} IP address of the object. *
* * This is the constructor that defines {@link $host} IP address of the object.
* @param String $host An IP address of a Modbus TCP device. E.g. "192.168.1.1". *
*/ * @param String $host An IP address of a Modbus TCP device. E.g. "192.168.1.1".
function ModbusMasterTcp($host){ */
$this->host = $host; public function __construct($host)
$this->socket_protocol = "TCP"; {
} parent::__construct($host, "TCP");
}
} }
+26 -26
View File
@@ -4,48 +4,48 @@ namespace PHPModbus;
/** /**
* Phpmodbus Copyright (c) 2004, 2012 Jan Krakora * Phpmodbus Copyright (c) 2004, 2012 Jan Krakora
* *
* This source file is subject to the "PhpModbus license" that is bundled * This source file is subject to the "PhpModbus license" that is bundled
* with this package in the file license.txt. * with this package in the file license.txt.
* *
* *
* @copyright Copyright (c) 2004, 2012 Jan Krakora * @copyright Copyright (c) 2004, 2012 Jan Krakora
* @license PhpModbus license * @license PhpModbus license
* @category Phpmodbus * @category Phpmodbus
* @tutorial Phpmodbus.pkg * @tutorial Phpmodbus.pkg
* @package Phpmodbus * @package Phpmodbus
* @version $id$ * @version $id$
* *
*/ */
/** /**
* ModbusMasterUdp * ModbusMasterUdp
* *
* This class deals with the MODBUS master using UDP stack. * This class deals with the MODBUS master using UDP stack.
* *
* Implemented MODBUS master functions: * Implemented MODBUS master functions:
* - FC 1: read coils * - FC 1: read coils
* - FC 3: read multiple registers * - FC 3: read multiple registers
* - FC 15: write multiple coils * - FC 15: write multiple coils
* - FC 16: write multiple registers * - FC 16: write multiple registers
* - FC 23: read write registers * - FC 23: read write registers
* *
* @author Jan Krakora * @author Jan Krakora
* @copyright Copyright (c) 2004, 2012 Jan Krakora * @copyright Copyright (c) 2004, 2012 Jan Krakora
* @package Phpmodbus * @package Phpmodbus
* *
*/ */
class ModbusMasterUdp extends ModbusMaster { class ModbusMasterUdp extends ModbusMaster
{
/** /**
* ModbusMasterUdp * ModbusMasterUdp
* *
* This is the constructor that defines {@link $host} IP address of the object. * This is the constructor that defines {@link $host} IP address of the object.
* *
* @param String $host An IP address of a Modbus UDP device. E.g. "192.168.1.1". * @param String $host An IP address of a Modbus UDP device. E.g. "192.168.1.1".
*/ */
function ModbusMasterUdp($host){ public function __construct($host)
$this->host = $host; {
$this->socket_protocol = "UDP"; parent::__construct($host, "UDP");
} }
} }
+231 -217
View File
@@ -1,6 +1,7 @@
<?php <?php
namespace PHPModbus; namespace PHPModbus;
use Exception;
/** /**
* Phpmodbus Copyright (c) 2004, 2012 Jan Krakora * Phpmodbus Copyright (c) 2004, 2012 Jan Krakora
@@ -8,12 +9,12 @@ namespace PHPModbus;
* This source file is subject to the "PhpModbus license" that is bundled * This source file is subject to the "PhpModbus license" that is bundled
* with this package in the file license.txt. * with this package in the file license.txt.
* *
* @author Jan Krakora * @author Jan Krakora
* @copyright Copyright (c) 2004, 2012 Jan Krakora * @copyright Copyright (c) 2004, 2012 Jan Krakora
* @license PhpModbus license * @license PhpModbus license
* @category Phpmodbus * @category Phpmodbus
* @package Phpmodbus * @package Phpmodbus
* @version $id$ * @version $id$
* *
*/ */
@@ -23,230 +24,243 @@ namespace PHPModbus;
* The class includes set of methods that convert the received Modbus data * The class includes set of methods that convert the received Modbus data
* (array of bytes) to the PHP data type, i.e. signed int, unsigned int and float. * (array of bytes) to the PHP data type, i.e. signed int, unsigned int and float.
* *
* @author Jan Krakora * @author Jan Krakora
* @copyright Copyright (c) 2004, 2012 Jan Krakora * @copyright Copyright (c) 2004, 2012 Jan Krakora
* @package Phpmodbus * @package Phpmodbus
* *
*/ */
class PhpType { class PhpType
{
/**
* bytes2float
*
* The function converts array of 4 bytes to float. The return value
* depends on order of the input bytes (endianning).
*
* @param array $values
* @param bool $bigEndian
* @return float
*/
public static function bytes2float($values, $bigEndian = 0)
{
// Set the array to correct form
$data = self::checkData($values);
// Combine bytes
$real = self::combineBytes($data, $bigEndian);
// Convert the real value to float
return (float)self::real2float($real);
}
/** /**
* bytes2float * bytes2signedInt
* *
* The function converts array of 4 bytes to float. The return value * The function converts array of 2 or 4 bytes to signed integer.
* depends on order of the input bytes (endianning). * The return value depends on order of the input bytes (endianning).
* *
* @param array $values * @param array $values
* @param bool $endianness * @param bool $bigEndian
* @return float * @return int
*/ */
public static function bytes2float($values, $endianness = 0) { public static function bytes2signedInt($values, $bigEndian = 0)
$data = array(); {
$real = 0; $data = array();
$int = 0;
// Set the array to correct form
$data = self::checkData($values);
// Combine bytes
$int = self::combineBytes($data, $bigEndian);
// In the case of signed 2 byte value convert it to 4 byte one
if ((count($values) == 2) && ((0x8000 & $int) > 0)) {
$int = 0xFFFF8000 | $int;
}
// Convert the value
return (int)self::dword2signedInt($int);
}
// Set the array to correct form /**
$data = self::checkData($values); * bytes2unsignedInt
// Combine bytes *
$real = self::combineBytes($data, $endianness); * The function converts array of 2 or 4 bytes to unsigned integer.
// Convert the real value to float * The return value depends on order of the input bytes (endianning).
return (float) self::real2float($real); *
} * @param array $values
* @param bool $bigEndian
* @return int|float
*/
public static function bytes2unsignedInt($values, $bigEndian = 0)
{
$data = array();
$int = 0;
// Set the array to correct form
$data = self::checkData($values);
// Combine bytes
$int = self::combineBytes($data, $bigEndian);
// Convert the value
return self::dword2unsignedInt($int);
}
/** /**
* bytes2signedInt * bytes2string
* *
* The function converts array of 2 or 4 bytes to signed integer. * The function converts an values array to the string. The function detects
* The return value depends on order of the input bytes (endianning). * the end of the string by 0x00 character as defined by string standards.
* *
* @param array $values * @param array $values
* @param bool $endianness * @param bool $bigEndian
* @return int * @return string
*/ */
public static function bytes2signedInt($values, $endianness = 0) { public static function bytes2string($values, $bigEndian = 0)
$data = array(); {
$int = 0; // Prepare string variable
// Set the array to correct form $str = "";
$data = self::checkData($values); // Parse the received data word array
// Combine bytes for ($i = 0; $i < count($values); $i += 2) {
$int = self::combineBytes($data, $endianness); if ($bigEndian) {
// In the case of signed 2 byte value convert it to 4 byte one if ($values[$i] != 0) {
if ((count($values) == 2) && ((0x8000 & $int) > 0)) { $str .= chr($values[$i]);
$int = 0xFFFF8000 | $int; } else {
} break;
// Convert the value }
return (int) self::dword2signedInt($int); if ($values[$i + 1] != 0) {
} $str .= chr($values[$i + 1]);
} else {
break;
}
} else {
if ($values[$i + 1] != 0) {
$str .= chr($values[$i + 1]);
} else {
break;
}
if ($values[$i] != 0) {
$str .= chr($values[$i]);
} else {
break;
}
}
}
// return string
return $str;
}
/** /**
* bytes2unsignedInt * real2float
* *
* The function converts array of 2 or 4 bytes to unsigned integer. * This function converts a value in IEC-1131 REAL single precision form to float.
* The return value depends on order of the input bytes (endianning). *
* * For more see [{@link http://en.wikipedia.org/wiki/Single_precision Single precision on Wiki}] or
* @param array $values * [{@link http://de.php.net/manual/en/function.base-convert.php PHP base_convert function commentary}, Todd Stokes
* @param bool $endianness * @ Georgia Tech 21-Nov-2007] or
* @return int|float * [{@link http://www.php.net/manual/en/function.pack.php PHP pack/unpack functionality}]
*/ *
public static function bytes2unsignedInt($values, $endianness = 0) { * @param int $value in IEC REAL data type to be converted
$data = array(); * @return float float value
$int = 0; */
// Set the array to correct form private static function real2float($value)
$data = self::checkData($values); {
// Combine bytes // get unsigned long
$int = self::combineBytes($data, $endianness); $ulong = pack("L", $value);
// Convert the value // set float
return self::dword2unsignedInt($int); $float = unpack("f", $ulong);
}
/** return $float[1];
* bytes2string }
*
* The function converts an values array to the string. The function detects
* the end of the string by 0x00 character as defined by string standards.
*
* @param array $values
* @param bool $endianness
* @return string
*/
public static function bytes2string($values, $endianness = 0) {
// Prepare string variable
$str = "";
// Parse the received data word array
for($i=0;$i<count($values);$i+=2) {
if ($endianness) {
if($values[$i] != 0)
$str .= chr($values[$i]);
else
break;
if($values[$i+1] != 0)
$str .= chr($values[$i+1]);
else
break;
}
else {
if($values[$i+1] != 0)
$str .= chr($values[$i+1]);
else
break;
if($values[$i] != 0)
$str .= chr($values[$i]);
else
break;
}
}
// return string
return $str;
}
/** /**
* real2float * dword2signedInt
* *
* This function converts a value in IEC-1131 REAL single precision form to float. * Switch double word to signed integer
* *
* For more see [{@link http://en.wikipedia.org/wiki/Single_precision Single precision on Wiki}] or * @param int $value
* [{@link http://de.php.net/manual/en/function.base-convert.php PHP base_convert function commentary}, Todd Stokes @ Georgia Tech 21-Nov-2007] or * @return int
* [{@link http://www.php.net/manual/en/function.pack.php PHP pack/unpack functionality}] */
* private static function dword2signedInt($value)
* @param value value in IEC REAL data type to be converted {
* @return float float value if ((0x80000000 & $value) != 0) {
*/ return -(0x7FFFFFFF & ~$value) - 1;
private static function real2float($value) { } else {
// get unsigned long return (0x7FFFFFFF & $value);
$ulong = pack("L", $value); }
// set float }
$float = unpack("f", $ulong);
return $float[1];
}
/** /**
* dword2signedInt * dword2signedInt
* *
* Switch double word to signed integer * Switch double word to unsigned integer
* *
* @param int $value * @param int $value
* @return int * @return int|float
*/ */
private static function dword2signedInt($value) { private static function dword2unsignedInt($value)
if ((0x80000000 & $value) != 0) { {
return -(0x7FFFFFFF & ~$value)-1; if ((0x80000000 & $value) != 0) {
} else { return ((float)(0x7FFFFFFF & $value)) + 2147483648;
return (0x7FFFFFFF & $value); } else {
} return (int)(0x7FFFFFFF & $value);
} }
}
/** /**
* dword2signedInt * checkData
* *
* Switch double word to unsigned integer * Check if the data variable is array, and check if the values are numeric
* *
* @param int $value * @param int[] $data
* @return int|float * @return int
*/ * @throws Exception
private static function dword2unsignedInt($value) { */
if ((0x80000000 & $value) != 0) { private static function checkData($data)
return ((float) (0x7FFFFFFF & $value)) + 2147483648; {
} else { // Check the data
return (int) (0x7FFFFFFF & $value); if (!is_array($data) ||
} count($data) < 2 ||
} count($data) > 4 ||
count($data) == 3
) {
throw new Exception('The input data should be an array of 2 or 4 bytes.');
}
// Fill the rest of array by zeroes
if (count($data) == 2) {
$data[2] = 0;
$data[3] = 0;
}
// Check the values to be number
if (!is_numeric($data[0]) ||
!is_numeric($data[1]) ||
!is_numeric($data[2]) ||
!is_numeric($data[3])
) {
throw new Exception('Data are not numeric or the array keys are not indexed by 0,1,2 and 3');
}
/** return $data;
* checkData }
*
* Check if the data variable is array, and check if the values are numeric
*
* @param int $data
* @return int
*/
private static function checkData($data) {
// Check the data
if (!is_array($data) ||
count($data)<2 ||
count($data)>4 ||
count($data)==3) {
throw new Exception('The input data should be an array of 2 or 4 bytes.');
}
// Fill the rest of array by zeroes
if (count($data) == 2) {
$data[2] = 0;
$data[3] = 0;
}
// Check the values to be number
if (!is_numeric($data[0]) ||
!is_numeric($data[1]) ||
!is_numeric($data[2]) ||
!is_numeric($data[3])) {
throw new Exception('Data are not numeric or the array keys are not indexed by 0,1,2 and 3');
}
return $data; /**
} * combineBytes
*
* Combine bytes together
*
* @param int $data
* @param bool $bigEndian
* @return int
*/
private static function combineBytes($data, $bigEndian)
{
$value = 0;
// Combine bytes
if ($bigEndian == 0) {
$value = (($data[3] & 0xFF) << 16) |
(($data[2] & 0xFF) << 24) |
(($data[1] & 0xFF)) |
(($data[0] & 0xFF) << 8);
} else {
$value = (($data[3] & 0xFF) << 24) |
(($data[2] & 0xFF) << 16) |
(($data[1] & 0xFF) << 8) |
(($data[0] & 0xFF));
}
/** return $value;
* combineBytes }
*
* Combine bytes together
*
* @param int $data
* @param bool $endianness
* @return int
*/
private static function combineBytes($data, $endianness) {
$value = 0;
// Combine bytes
if ($endianness == 0)
$value = (($data[3] & 0xFF)<<16) |
(($data[2] & 0xFF)<<24) |
(($data[1] & 0xFF)) |
(($data[0] & 0xFF)<<8);
else
$value = (($data[3] & 0xFF)<<24) |
(($data[2] & 0xFF)<<16) |
(($data[1] & 0xFF)<<8) |
(($data[0] & 0xFF));
return $value;
}
} }
?>