15 Commits
Author SHA1 Message Date
MightyPork 0ac0018444 foo 2016-03-11 22:30:00 +01:00
MightyPork 5300b2a867 added a namespace 2016-03-11 22:27:10 +01:00
John S Long c676c06e2e Merge pull request #1 from FabrizioC/master
Added FC 22 Mask Write Register support
2014-12-11 14:38:09 -06:00
FabrizioC 697daedba3 Update ModbusMaster.php 2014-11-21 10:38:17 +01:00
FabrizioC cd52263b8e Added FC22 Mask Write Register example 2014-11-21 10:31:45 +01:00
FabrizioC a2bde03574 Added FC 22 Mask Write Register function 2014-11-21 10:08:44 +01:00
FabrizioC 24d16bc1aa Added FC 22 Mask Write Register function 2014-11-21 10:07:38 +01:00
John Long bb0cdd467a 0.8 release 2013-11-29 22:27:16 -06:00
John Long 9ef8e72f3e Add syntax declaration to code block in README.md 2013-06-14 09:03:03 -04:00
John Long ad507ed46c Create README.md 2013-06-14 08:01:51 -05:00
John Long 5bb5dfe654 Added tag 0.7 for changeset 5885b1a0d0dc 2013-06-14 07:43:52 -05:00
John Long 83d9baa9f6 0.7 release 2013-06-14 07:43:45 -05:00
John Long 753bff38ec Added tag 0.6 for changeset 079f8ac1f49f 2013-06-14 07:43:03 -05:00
John Long 5f069276eb 0.6 release 2013-06-14 07:43:00 -05:00
John Long 7f4c4f2af1 Added tag 0.5 for changeset e1262f028e18 2013-06-14 07:42:20 -05:00
40 changed files with 2555 additions and 1565 deletions
+4
View File
@@ -0,0 +1,4 @@
/vendor
composer.lock
*~
-2
View File
@@ -1,2 +0,0 @@
vendor
.svn
-4
View File
@@ -1,4 +0,0 @@
a88b5a87fb4cd49f16ce72062cce19d55f1fbf98 0.2
a7f90c18859d31922bdd8c61299e2790f5e2eb1a 0.3
bdf8b3f414c4d08fc0edf9fd1953f55db26e4bac 0.4
1e09b0da7d8c62a9a292ee51540feac9de4c1222 0.4.1
+29 -2
View File
@@ -1,10 +1,33 @@
+---------------------------------------------------------+
| ACKNOWLEDGEMENTS |
+---------------------------------------------------------+
This project is based on work by Jan Krákora, (c) 2004-2013.
The original license is reproduced below.
https://code.google.com/archive/p/phpmodbus/
Further improvements - John S. Long and other contributors
https://github.com/adduc/phpmodbus
Cleanup and namespaces - Ondřej Hruška, 2016
https://github.com/MightyPork/phpmodbus
+---------------------------------------------------------+
| ORIGINAL LICENSE |
+---------------------------------------------------------+
The Phpmodbus License, Version 1
============================
Copyright (c) 2004, 2011 Jan Krakora, Wago (http://www.wago.com)
Copyright (c) 2004, 2013 Jan Krakora
All rights reserved.
This license is a legal agreement between you and Jan Krakora, Wago (the "Author")
This license is a legal agreement between you and Jan Krakora (the "Author")
for the use of Phpmodbus (the "Software"). By obtaining, using and/or
copying the Software, you agree that you have read, understood, and will
comply with the terms and conditions of this license.
@@ -60,3 +83,7 @@ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
End of file.
+49
View File
@@ -0,0 +1,49 @@
# phpmodbus
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/
> **What's new**
>
> 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:
* Modbus master
* FC1 - Read coils
* FC2 - Read input discretes
* FC3 - Read holding registers
* FC4 - Read holding input registers
* FC5 - Write single coil
* FC6 - Write single register
* FC15 - Write multiple coils
* FC16 - Write multiple registers
* FC23 - Read/Write multiple registers
Example:
```php
require_once dirname(__FILE__) . '/Phpmodbus/ModbusMaster.php';
// Modbus master UDP
$modbus = new ModbusMaster("192.168.1.1", "UDP");
// Read multiple registers
try {
$recData = $modbus->readMultipleRegisters(0, 12288, 5);
}
catch (Exception $e) {
// Print error information if any
echo $modbus;
echo $e;
exit;
}
// Print data in string format
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].
Note:
* The PHP extension php_sockets.dll should be enabled (server php.ini file)
+10 -6
View File
@@ -1,7 +1,12 @@
{
"name": "adduc/phpmodbus",
"description": "Composer version of PhpModBus",
"name": "MightyPork/phpmodbus",
"keywords": ["phpmodbus","modbus"],
"description": "PhpModbus with namespaces and updated to PHP 7",
"license": "LGPL",
"require": {
"php": "^5.3.2 || ^7.0",
"ext-sockets": "*"
},
"authors": [
{
"name": "Honza Krakora",
@@ -9,9 +14,8 @@
}
],
"autoload": {
"classmap": [ "Phpmodbus" ]
},
"require": {
"ext-sockets": "*"
"psr-4": {
"PHPModbus\\": "src/"
}
}
}
+3
View File
@@ -0,0 +1,3 @@
Those examples have not been updated to use namespaces.
They may not work. Just for reference.
+26
View File
@@ -0,0 +1,26 @@
<?php
require_once dirname(__FILE__) . '/../Phpmodbus/ModbusMaster.php';
// Create Modbus object
$modbus = new ModbusMaster("192.192.15.51", "UDP");
try {
// FC 2
// read 2 input bits from address 0x0 (Wago input image)
$recData = $modbus->readInputDiscretes(0, 0, 2);
}
catch (Exception $e) {
// Print error information if any
echo $modbus;
echo $e;
exit;
}
// Print status information
echo "</br>Status:</br>" . $modbus;
// Print read data
echo "</br>Data:</br>";
var_dump($recData);
echo "</br>";
+28
View File
@@ -0,0 +1,28 @@
<?php
require_once dirname(__FILE__) . '/../Phpmodbus/ModbusMaster.php';
// Create Modbus object
$modbus = new ModbusMaster("192.192.15.51", "UDP");
// Data to be writen
$bitValue = true;
$bitNumber = 2;
$andMask = 0xFFFF ^ pow(2, $bitNumber) ;
$orMask = 0x0000 ^ (pow(2, $bitNumber) * $bitValue ) ;
try {
// FC22
$modbus->maskWriteRegister(0, 12288, $andMask, $orMask);
}
catch (Exception $e) {
// Print error information if any
echo $modbus;
echo $e;
exit;
}
// Print status information
echo $modbus;
?>
+19
View File
@@ -0,0 +1,19 @@
<?php
require_once dirname(__FILE__) . '/../../Phpmodbus/ModbusMasterUdp.php';
// Create Modbus object
$modbus = new ModbusMasterUdp("192.192.15.51");
try {
// Read input discretes - FC 4
$recData = $modbus->readMultipleInputRegisters(0, 0, 2);
}
catch (Exception $e) {
// Print error information if any
echo $modbus;
echo $e;
exit;
}
var_dump($recData);
+24
View File
@@ -0,0 +1,24 @@
<?php
require_once dirname(__FILE__) . '/../../Phpmodbus/ModbusMasterUdp.php';
// Create Modbus object
$modbus = new ModbusMasterUdp("192.192.15.51");
// Data to be writen - TRUE, FALSE
$data_true = array(TRUE);
$data_false = array(FALSE);
try {
// Write single coil - FC5
$modbus->writeSingleCoil(0, 12288, $data_true);
$modbus->writeSingleCoil(0, 12289, $data_false);
$modbus->writeSingleCoil(0, 12290, $data_true);
$modbus->writeSingleCoil(0, 12291, $data_false);
}
catch (Exception $e) {
// Print error information if any
echo $modbus;
echo $e;
exit;
}
+26
View File
@@ -0,0 +1,26 @@
<?php
require_once dirname(__FILE__) . '/../Phpmodbus/ModbusMaster.php';
// Create Modbus object
$modbus = new ModbusMaster("192.192.15.51", "UDP");
// Data to be writen
$data = array(-1000);
$dataTypes = array("INT");
try {
// FC6
$modbus->writeSingleRegister(0, 12288, $data, $dataTypes);
}
catch (Exception $e) {
// Print error information if any
echo $modbus;
echo $e;
exit;
}
// Print status information
echo $modbus;
?>
+12 -9
View File
@@ -1,12 +1,15 @@
<?php
namespace PHPModbus;
/**
* Phpmodbus Copyright (c) 2004, 2010 Jan Krakora, WAGO Kontakttechnik GmbH & Co. KG (http://www.wago.com)
* Phpmodbus Copyright (c) 2004, 2013 Jan Krakora
*
* This source file is subject to the "PhpModbus license" that is bundled
* with this package in the file license.txt.
*
* @author Jan Krakora
* @copyright Copyright (c) 2004, 2010 Jan Krakora, WAGO Kontakttechnik GmbH & Co. KG (http://www.wago.com)
* @copyright Copyright (c) 2004, 2013 Jan Krakora
* @license PhpModbus license
* @category Phpmodbus
* @package Phpmodbus
@@ -20,7 +23,7 @@
* data types to a IEC data type.
*
* @author Jan Krakora
* @copyright Copyright (c) 2004, 2010 Jan Krakora, WAGO Kontakttechnik GmbH & Co. KG (http://www.wago.com)
* @copyright Copyright (c) 2004, 2010 Jan Krakora
* @package Phpmodbus
*/
class IecType {
@@ -34,7 +37,7 @@ class IecType {
* @return value IEC BYTE data type
*
*/
function iecBYTE($value) {
public static function iecBYTE($value) {
return chr($value & 0xFF);
}
@@ -47,7 +50,7 @@ class IecType {
* @return value IEC-1131 INT data type
*
*/
function iecINT($value) {
public static function iecINT($value) {
return self::iecBYTE(($value >> 8) & 0x00FF) .
self::iecBYTE(($value & 0x00FF));
}
@@ -62,7 +65,7 @@ class IecType {
* @return value IEC-1131 INT data type
*
*/
function iecDINT($value, $endianness = 0) {
public static function iecDINT($value, $endianness = 0) {
// result with right endianness
return self::endianness($value, $endianness);
}
@@ -76,7 +79,7 @@ class IecType {
* @param value endianness defines endian codding (little endian == 0, big endian == 1)
* @return value IEC-1131 REAL data type
*/
function iecREAL($value, $endianness = 0) {
public static function iecREAL($value, $endianness = 0) {
// iecREAL representation
$real = self::float2iecReal($value);
// result with right endianness
@@ -95,7 +98,7 @@ class IecType {
* @param float value to be converted
* @return value IEC REAL data type
*/
private function float2iecReal($value) {
private static function float2iecReal($value) {
// get float binary string
$float = pack("f", $value);
// set 32-bit unsigned integer of the float
@@ -113,7 +116,7 @@ class IecType {
* @param bool $endianness
* @return int
*/
private function endianness($value, $endianness = 0) {
private static function endianness($value, $endianness = 0) {
if ($endianness == 0)
return
self::iecBYTE(($value >> 8) & 0x000000FF) .
@@ -1,12 +1,15 @@
<?php
namespace PHPModbus;
/**
* Phpmodbus Copyright (c) 2004, 2012 Jan Krakora
* Phpmodbus Copyright (c) 2004, 2013 Jan Krakora
*
* This source file is subject to the "PhpModbus license" that is bundled
* with this package in the file license.txt.
*
*
* @copyright Copyright (c) 2004, 2012 Jan Krakora
* @copyright Copyright (c) 2004, 2013 Jan Krakora
* @license PhpModbus license
* @category Phpmodbus
* @tutorial Phpmodbus.pkg
@@ -15,9 +18,6 @@
*
*/
require_once dirname(__FILE__) . '/IecType.php';
require_once dirname(__FILE__) . '/PhpType.php';
/**
* ModbusMaster
*
@@ -25,13 +25,18 @@ require_once dirname(__FILE__) . '/PhpType.php';
*
* Implemented MODBUS master functions:
* - FC 1: read coils
* - FC 2: read input discretes
* - FC 3: read multiple registers
* - FC 4: read multiple input registers
* - FC 5: write single coil
* - FC 6: write single register
* - FC 15: write multiple coils
* - FC 16: write multiple registers
* - FC 22: mask write register
* - FC 23: read write registers
*
* @author Jan Krakora
* @copyright Copyright (c) 2004, 2012 Jan Krakora
* @copyright Copyright (c) 2004, 2013 Jan Krakora
* @package Phpmodbus
*
*/
@@ -43,7 +48,7 @@ class ModbusMaster {
public $client_port = "502";
public $status;
public $timeout_sec = 5; // Timeout 5 sec
public $endianess = 0; // Endianess codding (little endian == 0, big endian == 1)
public $endianness = 0; // Endianness codding (little endian == 0, big endian == 1)
public $socket_protocol = "UDP"; // Socket protocol (TCP, UDP)
/**
@@ -96,6 +101,8 @@ class ModbusMaster {
$this->status .= "Bound\n";
}
}
// Socket settings
socket_set_option($this->sock, SOL_SOCKET, SO_SNDTIMEO, array('sec' => 1, 'usec' => 0));
// Connect the socket
$result = @socket_connect($this->sock, $this->host, $this->port);
if ($result === false) {
@@ -175,8 +182,28 @@ class ModbusMaster {
* @return bool
*/
private function responseCode($packet){
if(($packet[7] & 0x80) > 0) {
throw new Exception("Modbus response error code:" . ord($packet[8]));
if((ord($packet[7]) & 0x80) > 0) {
// failure code
$failure_code = ord($packet[8]);
// failure code strings
$failures = array(
0x01 => "ILLEGAL FUNCTION",
0x02 => "ILLEGAL DATA ADDRESS",
0x03 => "ILLEGAL DATA VALUE",
0x04 => "SLAVE DEVICE FAILURE",
0x05 => "ACKNOWLEDGE",
0x06 => "SLAVE DEVICE BUSY",
0x08 => "MEMORY PARITY ERROR",
0x0A => "GATEWAY PATH UNAVAILABLE",
0x0B => "GATEWAY TARGET DEVICE FAILED TO RESPOND");
// get failure string
if(key_exists($failure_code, $failures)) {
$failure_str = $failures[$failure_code];
} else {
$failure_str = "UNDEFINED FAILURE CODE";
}
// exception response
throw new Exception("Modbus response error code: $failure_code ($failure_str)");
} else {
$this->status .= "Modbus response error code: NOERROR\n";
return true;
@@ -189,7 +216,7 @@ class ModbusMaster {
* Modbus function FC 1(0x01) - Read Coils
*
* Reads {@link $quantity} of Coils (boolean) from reference
* {@link $referenceRead} of a memory of a Modbus device given by
* {@link $reference} of a memory of a Modbus device given by
* {@link $unitId}.
*
* @param type $unitId
@@ -200,7 +227,7 @@ class ModbusMaster {
$this->status .= "readCoils: START\n";
// connect
$this->connect();
// send FC 3
// send FC 1
$packet = $this->readCoilsPacketBuilder($unitId, $reference, $quantity);
$this->status .= $this->printPacket($packet);
$this->send($packet);
@@ -219,7 +246,7 @@ class ModbusMaster {
/**
* fc1
*
* Alias to {@link readMultipleCoils} method
* Alias to {@link readCoils} method
*
* @param type $unitId
* @param type $reference
@@ -283,7 +310,7 @@ class ModbusMaster {
$di = 0;
foreach($data as $value){
for($i=0;$i<8;$i++){
if($di > $quantity) continue;
if($di == $quantity) continue;
// get boolean value
$v = ($value >> $i) & 0x01;
// build boolean array
@@ -298,6 +325,97 @@ class ModbusMaster {
return $data_bolean_array;
}
/**
* readInputDiscretes
*
* Modbus function FC 2(0x02) - Read Input Discretes
*
* Reads {@link $quantity} of Inputs (boolean) from reference
* {@link $reference} of a memory of a Modbus device given by
* {@link $unitId}.
*
* @param type $unitId
* @param type $reference
* @param type $quantity
*/
function readInputDiscretes($unitId, $reference, $quantity){
$this->status .= "readInputDiscretes: START\n";
// connect
$this->connect();
// send FC 2
$packet = $this->readInputDiscretesPacketBuilder($unitId, $reference, $quantity);
$this->status .= $this->printPacket($packet);
$this->send($packet);
// receive response
$rpacket = $this->rec();
$this->status .= $this->printPacket($rpacket);
// parse packet
$receivedData = $this->readInputDiscretesParser($rpacket, $quantity);
// disconnect
$this->disconnect();
$this->status .= "readInputDiscretes: DONE\n";
// return
return $receivedData;
}
/**
* fc2
*
* Alias to {@link readInputDiscretes} method
*
* @param type $unitId
* @param type $reference
* @param type $quantity
* @return type
*/
function fc2($unitId, $reference, $quantity){
return $this->readInputDiscretes($unitId, $reference, $quantity);
}
/**
* readInputDiscretesPacketBuilder
*
* FC2 packet builder - read coils
*
* @param type $unitId
* @param type $reference
* @param type $quantity
* @return type
*/
private function readInputDiscretesPacketBuilder($unitId, $reference, $quantity){
$dataLen = 0;
// build data section
$buffer1 = "";
// build body
$buffer2 = "";
$buffer2 .= iecType::iecBYTE(2); // FC 2 = 2(0x02)
// build body - read section
$buffer2 .= iecType::iecINT($reference); // refnumber = 12288
$buffer2 .= iecType::iecINT($quantity); // quantity
$dataLen += 5;
// build header
$buffer3 = '';
$buffer3 .= iecType::iecINT(rand(0,65000)); // transaction ID
$buffer3 .= iecType::iecINT(0); // protocol ID
$buffer3 .= iecType::iecINT($dataLen + 1); // lenght
$buffer3 .= iecType::iecBYTE($unitId); //unit ID
// return packet string
return $buffer3. $buffer2. $buffer1;
}
/**
* readInputDiscretesParser
*
* FC 2 response parser, alias to FC 1 parser i.e. readCoilsParser.
*
* @param type $packet
* @param type $quantity
* @return type
*/
private function readInputDiscretesParser($packet, $quantity){
return $this->readCoilsParser($packet, $quantity);
}
/**
* readMultipleRegisters
*
@@ -397,6 +515,308 @@ class ModbusMaster {
return $data;
}
/**
* readMultipleInputRegisters
*
* Modbus function FC 4(0x04) - Read Multiple Input Registers.
*
* This function reads {@link $quantity} of Words (2 bytes) from reference
* {@link $referenceRead} of a memory of a Modbus device given by
* {@link $unitId}.
*
*
* @param int $unitId usually ID of Modbus device
* @param int $reference Reference in the device memory to read data.
* @param int $quantity Amounth of the data to be read from device.
* @return false|Array Success flag or array of received data.
*/
function readMultipleInputRegisters($unitId, $reference, $quantity){
$this->status .= "readMultipleInputRegisters: START\n";
// connect
$this->connect();
// send FC 4
$packet = $this->readMultipleInputRegistersPacketBuilder($unitId, $reference, $quantity);
$this->status .= $this->printPacket($packet);
$this->send($packet);
// receive response
$rpacket = $this->rec();
$this->status .= $this->printPacket($rpacket);
// parse packet
$receivedData = $this->readMultipleInputRegistersParser($rpacket);
// disconnect
$this->disconnect();
$this->status .= "readMultipleInputRegisters: DONE\n";
// return
return $receivedData;
}
/**
* fc4
*
* Alias to {@link readMultipleInputRegisters} method.
*
* @param int $unitId
* @param int $reference
* @param int $quantity
* @return false|Array
*/
function fc4($unitId, $reference, $quantity){
return $this->readMultipleInputRegisters($unitId, $reference, $quantity);
}
/**
* readMultipleInputRegistersPacketBuilder
*
* Packet FC 4 builder - read multiple input registers
*
* @param int $unitId
* @param int $reference
* @param int $quantity
* @return string
*/
private function readMultipleInputRegistersPacketBuilder($unitId, $reference, $quantity){
$dataLen = 0;
// build data section
$buffer1 = "";
// build body
$buffer2 = "";
$buffer2 .= iecType::iecBYTE(4); // FC 4 = 4(0x04)
// build body - read section
$buffer2 .= iecType::iecINT($reference); // refnumber = 12288
$buffer2 .= iecType::iecINT($quantity); // quantity
$dataLen += 5;
// build header
$buffer3 = '';
$buffer3 .= iecType::iecINT(rand(0,65000)); // transaction ID
$buffer3 .= iecType::iecINT(0); // protocol ID
$buffer3 .= iecType::iecINT($dataLen + 1); // lenght
$buffer3 .= iecType::iecBYTE($unitId); // unit ID
// return packet string
return $buffer3. $buffer2. $buffer1;
}
/**
* readMultipleInputRegistersParser
*
* FC 4 response parser
*
* @param string $packet
* @return array
*/
private function readMultipleInputRegistersParser($packet){
$data = array();
// check Response code
$this->responseCode($packet);
// get data
for($i=0;$i<ord($packet[8]);$i++){
$data[$i] = ord($packet[9+$i]);
}
return $data;
}
/**
* writeSingleCoil
*
* Modbus function FC5(0x05) - Write Single Register.
*
* This function writes {@link $data} single coil at {@link $reference} position of
* memory of a Modbus device given by {@link $unitId}.
*
*
* @param int $unitId usually ID of Modbus device
* @param int $reference Reference in the device memory (e.g. in device WAGO 750-841, memory MW0 starts at address 12288)
* @param array $data value to be written (TRUE|FALSE).
* @return bool Success flag
*/
function writeSingleCoil($unitId, $reference, $data){
$this->status .= "writeSingleCoil: START\n";
// connect
$this->connect();
// send FC5
$packet = $this->writeSingleCoilPacketBuilder($unitId, $reference, $data);
$this->status .= $this->printPacket($packet);
$this->send($packet);
// receive response
$rpacket = $this->rec();
$this->status .= $this->printPacket($rpacket);
// parse packet
$this->writeSingleCoilParser($rpacket);
// disconnect
$this->disconnect();
$this->status .= "writeSingleCoil: DONE\n";
return true;
}
/**
* fc5
*
* Alias to {@link writeSingleCoil} method
*
* @param int $unitId
* @param int $reference
* @param array $data
* @param array $dataTypes
* @return bool
*/
function fc5($unitId, $reference, $data, $dataTypes){
return $this->writeSingleCoil($unitId, $reference, $data, $dataTypes);
}
/**
* writeSingleCoilPacketBuilder
*
* Packet builder FC5 - WRITE single register
*
* @param int $unitId
* @param int $reference
* @param array $data
* @param array $dataTypes
* @return string
*/
private function writeSingleCoilPacketBuilder($unitId, $reference, $data){
$dataLen = 0;
// build data section
$buffer1 = "";
foreach($data as $key=>$dataitem) {
if($dataitem == TRUE){
$buffer1 = iecType::iecINT(0xFF00);
} else {
$buffer1 = iecType::iecINT(0x0000);
};
};
$dataLen += 2;
// build body
$buffer2 = "";
$buffer2 .= iecType::iecBYTE(5); // FC5 = 5(0x05)
$buffer2 .= iecType::iecINT($reference); // refnumber = 12288
$dataLen += 3;
// build header
$buffer3 = '';
$buffer3 .= iecType::iecINT(rand(0,65000)); // transaction ID
$buffer3 .= iecType::iecINT(0); // protocol ID
$buffer3 .= iecType::iecINT($dataLen + 1); // lenght
$buffer3 .= iecType::iecBYTE($unitId); //unit ID
// return packet string
return $buffer3. $buffer2. $buffer1;
}
/**
* writeSingleCoilParser
*
* FC5 response parser
*
* @param string $packet
* @return bool
*/
private function writeSingleCoilParser($packet){
$this->responseCode($packet);
return true;
}
/**
* writeSingleRegister
*
* Modbus function FC6(0x06) - Write Single Register.
*
* This function writes {@link $data} single word value at {@link $reference} position of
* memory of a Modbus device given by {@link $unitId}.
*
*
* @param int $unitId usually ID of Modbus device
* @param int $reference Reference in the device memory (e.g. in device WAGO 750-841, memory MW0 starts at address 12288)
* @param array $data Array of values to be written.
* @param array $dataTypes Array of types of values to be written. The array should consists of string "INT", "DINT" and "REAL".
* @return bool Success flag
*/
function writeSingleRegister($unitId, $reference, $data, $dataTypes){
$this->status .= "writeSingleRegister: START\n";
// connect
$this->connect();
// send FC6
$packet = $this->writeSingleRegisterPacketBuilder($unitId, $reference, $data, $dataTypes);
$this->status .= $this->printPacket($packet);
$this->send($packet);
// receive response
$rpacket = $this->rec();
$this->status .= $this->printPacket($rpacket);
// parse packet
$this->writeSingleRegisterParser($rpacket);
// disconnect
$this->disconnect();
$this->status .= "writeSingleRegister: DONE\n";
return true;
}
/**
* fc6
*
* Alias to {@link writeSingleRegister} method
*
* @param int $unitId
* @param int $reference
* @param array $data
* @param array $dataTypes
* @return bool
*/
function fc6($unitId, $reference, $data, $dataTypes){
return $this->writeSingleRegister($unitId, $reference, $data, $dataTypes);
}
/**
* writeSingleRegisterPacketBuilder
*
* Packet builder FC6 - WRITE single register
*
* @param int $unitId
* @param int $reference
* @param array $data
* @param array $dataTypes
* @return string
*/
private function writeSingleRegisterPacketBuilder($unitId, $reference, $data, $dataTypes){
$dataLen = 0;
// build data section
$buffer1 = "";
foreach($data as $key=>$dataitem) {
$buffer1 .= iecType::iecINT($dataitem); // register values x
$dataLen += 2;
break;
}
// build body
$buffer2 = "";
$buffer2 .= iecType::iecBYTE(6); // FC6 = 6(0x06)
$buffer2 .= iecType::iecINT($reference); // refnumber = 12288
$dataLen += 3;
// build header
$buffer3 = '';
$buffer3 .= iecType::iecINT(rand(0,65000)); // transaction ID
$buffer3 .= iecType::iecINT(0); // protocol ID
$buffer3 .= iecType::iecINT($dataLen + 1); // lenght
$buffer3 .= iecType::iecBYTE($unitId); //unit ID
// return packet string
return $buffer3. $buffer2. $buffer1;
}
/**
* writeSingleRegisterParser
*
* FC6 response parser
*
* @param string $packet
* @return bool
*/
private function writeSingleRegisterParser($packet){
$this->responseCode($packet);
return true;
}
/**
* writeMultipleCoils
*
@@ -414,7 +834,7 @@ class ModbusMaster {
$this->status .= "writeMultipleCoils: START\n";
// connect
$this->connect();
// send FC16
// send FC15
$packet = $this->writeMultipleCoilsPacketBuilder($unitId, $reference, $data);
$this->status .= $this->printPacket($packet);
$this->send($packet);
@@ -630,6 +1050,106 @@ class ModbusMaster {
return true;
}
/**
* maskWriteRegister
*
* Modbus function FC22(0x16) - Mask Write Register.
*
* This function alter single bit(s) at {@link $reference} position of
* memory of a Modbus device given by {@link $unitId}.
*
* Result = (Current Contents AND And_Mask) OR (Or_Mask AND (NOT And_Mask))
*
* @param int $unitId usually ID of Modbus device
* @param int $reference Reference in the device memory (e.g. in device WAGO 750-841, memory MW0 starts at address 12288)
* @param int $andMask
* @param int $orMask
* @return bool Success flag
*/
function maskWriteRegister($unitId, $reference, $andMask, $orMask){
$this->status .= "maskWriteRegister: START\n";
// connect
$this->connect();
// send FC22
$packet = $this->maskWriteRegisterPacketBuilder($unitId, $reference, $andMask, $orMask);
$this->status .= $this->printPacket($packet);
$this->send($packet);
// receive response
$rpacket = $this->rec();
$this->status .= $this->printPacket($rpacket);
// parse packet
$this->maskWriteRegisterParser($rpacket);
// disconnect
$this->disconnect();
$this->status .= "maskWriteRegister: DONE\n";
return true;
}
/**
* fc22
*
* Alias to {@link maskWriteRegister} method
*
* @param int $unitId
* @param int $reference
* @param int $andMask
* @param int $orMask
* @return bool
*/
function fc22($unitId, $reference, $andMask, $orMask){
return $this->maskWriteRegister($unitId, $reference, $andMask, $orMask);
}
/**
* maskWriteRegisterPacketBuilder
*
* Packet builder FC22 - MASK WRITE register
*
* @param int $unitId
* @param int $reference
* @param int $andMask
* @param int $orMask
* @return string
*/
private function maskWriteRegisterPacketBuilder($unitId, $reference, $andMask, $orMask){
$dataLen = 0;
// build data section
$buffer1 = "";
// build body
$buffer2 = "";
$buffer2 .= iecType::iecBYTE(22); // FC 22 = 22(0x16)
$buffer2 .= iecType::iecINT($reference); // refnumber = 12288
$buffer2 .= iecType::iecINT($andMask); // AND mask
$buffer2 .= iecType::iecINT($orMask); // OR mask
$dataLen += 7;
// build header
$buffer3 = '';
$buffer3 .= iecType::iecINT(rand(0,65000)); // transaction ID
$buffer3 .= iecType::iecINT(0); // protocol ID
$buffer3 .= iecType::iecINT($dataLen + 1); // lenght
$buffer3 .= iecType::iecBYTE($unitId); //unit ID
// return packet string
return $buffer3. $buffer2. $buffer1;
}
/**
* maskWriteRegisterParser
*
* FC22 response parser
*
* @param string $packet
* @return bool
*/
private function maskWriteRegisterParser($packet){
$this->responseCode($packet);
return true;
}
/**
* readWriteRegisters
*
@@ -1,4 +1,7 @@
<?php
namespace PHPModbus;
/**
* Phpmodbus Copyright (c) 2004, 2012 Jan Krakora
*
@@ -15,8 +18,6 @@
*
*/
require_once dirname(__FILE__) . '/ModbusMaster.php';
/**
* ModbusMasterTcp
*
@@ -1,4 +1,7 @@
<?php
namespace PHPModbus;
/**
* Phpmodbus Copyright (c) 2004, 2012 Jan Krakora
*
@@ -15,8 +18,6 @@
*
*/
require_once dirname(__FILE__) . '/ModbusMaster.php';
/**
* ModbusMasterUdp
*
+6 -3
View File
@@ -1,12 +1,15 @@
<?php
namespace PHPModbus;
/**
* Phpmodbus Copyright (c) 2004, 2010 Jan Krakora, WAGO Kontakttechnik GmbH & Co. KG (http://www.wago.com)
* Phpmodbus Copyright (c) 2004, 2012 Jan Krakora
*
* This source file is subject to the "PhpModbus license" that is bundled
* with this package in the file license.txt.
*
* @author Jan Krakora
* @copyright Copyright (c) 2004, 2010 Jan Krakora, WAGO Kontakttechnik GmbH & Co. KG (http://www.wago.com)
* @copyright Copyright (c) 2004, 2012 Jan Krakora
* @license PhpModbus license
* @category Phpmodbus
* @package Phpmodbus
@@ -21,7 +24,7 @@
* (array of bytes) to the PHP data type, i.e. signed int, unsigned int and float.
*
* @author Jan Krakora
* @copyright Copyright (c) 2004, 2010 Jan Krakora, WAGO Kontakttechnik GmbH & Co. KG (http://www.wago.com)
* @copyright Copyright (c) 2004, 2012 Jan Krakora
* @package Phpmodbus
*
*/
+256
View File
@@ -0,0 +1,256 @@
(* @NESTEDCOMMENTS := 'Yes' *)
(* @PATH := '' *)
(* @OBJECTFLAGS := '0, 8' *)
(* @SYMFILEFLAGS := '2048' *)
PROGRAM PLC_PRG
VAR
(* BOOL, COIL *)
COIL1 AT %MX0.0 : BOOL := 0;
COIL2 AT %MX0.1 : BOOL := 0;
COIL3 AT %MX0.2 : BOOL := 0;
COIL4 AT %MX0.3 : BOOL := 0;
COIL5 AT %MX0.4 : BOOL := 0;
COIL6 AT %MX0.5 : BOOL := 0;
COIL7 AT %MX0.6 : BOOL := 0;
COIL8 AT %MX0.7 : BOOL := 0;
(* BYTE *)
BYTE1 AT %MB0 : BYTE := 0;
BYTE2 AT %MB1 : BYTE := 0;
BYTE3 AT %MB2 : BYTE := 0;
BYTE4 AT %MB3 : BYTE := 0;
BYTE5 AT %MB4 : BYTE := 0;
(* INT *)
INT1 AT %MW0 : INT := 0;
INT2 AT %MW1 : INT := 0;
INT3 AT %MW2 : INT := 0;
INT4 AT %MW3 : INT := 0;
INT5 AT %MW4 : INT := 0;
(* WORD *)
WORD1 AT %MW0 : WORD := 0;
WORD2 AT %MW1 : WORD := 0;
WORD3 AT %MW2 : WORD := 0;
WORD4 AT %MW3 : WORD := 0;
WORD5 AT %MW4 : WORD := 0;
(* DINT *)
DINT1 AT %MD0 : DINT := 0;
DINT2 AT %MD1 : DINT := 0;
DINT3 AT %MD2 : DINT := 0;
DINT4 AT %MD3 : DINT := 0;
DINT5 AT %MD4 : DINT := 0;
(* DWORD *)
DWORD1 AT %MD0 : DWORD := 0;
DWORD2 AT %MD1 : DWORD := 0;
DWORD3 AT %MD2 : DWORD := 0;
DWORD4 AT %MD3 : DWORD := 0;
DWORD5 AT %MD4 : DWORD := 0;
(* REAL *)
REAL1 AT %MD0 : REAL := 0;
REAL2 AT %MD1 : REAL := 0;
REAL3 AT %MD2 : REAL := 0;
REAL4 AT %MD3 : REAL := 0;
REAL5 AT %MD4 : REAL := 0;
(* String *)
STRING1 AT %MW0 : STRING := 'Hello word!!!';
END_VAR
(* @END_DECLARATION := '0' *)
(* Something to do *)
;
END_PROGRAM
(* @NESTEDCOMMENTS := 'Yes' *)
(* @GLOBAL_VARIABLE_LIST := 'Global_Variables' *)
(* @PATH := '' *)
(* @OBJECTFLAGS := '0, 8' *)
(* @SYMFILEFLAGS := '2048' *)
VAR_GLOBAL
END_VAR
(* @OBJECT_END := 'Global_Variables' *)
(* @CONNECTIONS := Global_Variables
FILENAME : ''
FILETIME : 0
EXPORT : 0
NUMOFCONNECTIONS : 0
*)
(* @NESTEDCOMMENTS := 'Yes' *)
(* @GLOBAL_VARIABLE_LIST := 'Variable_Configuration' *)
(* @PATH := '' *)
(* @OBJECTFLAGS := '0, 8' *)
(* @SYMFILEFLAGS := '2048' *)
VAR_CONFIG
END_VAR
(* @OBJECT_END := 'Variable_Configuration' *)
(* @CONNECTIONS := Variable_Configuration
FILENAME : ''
FILETIME : 0
EXPORT : 0
NUMOFCONNECTIONS : 0
*)
_ALARMCONFIG
_ALARMCONFIGNEXTTEXTID : 10002
_ALARMCONFIGFORMATS : 'HH$':$'mm$':$'ss','dd$'-$'MM$'-$'yyyy'
_ALARMCLASSLIST : 1
_ALARMCLASSID : 0
_ALARMCLASSACKTYPE : 0
_ALARMCLASSNAME : 'DEFAULT'
_ALARMCLASSDESCRIPTION : ''
_ALARMCLASSBGCOLORS : 16777215,16777215,16777215
_ALARMCLASSTEXTCOLORS : 3394560,255,16711680
_ALARMCLASSBITMAPS : '','',''
_ALARMACTIONLIST : 0
(* @ALARMCLASSRESETCOLORS := '_ALARMCLASSRESETCOLORS: 33023,16777215' *)
(* @ALARMCLASSRESETBITMAP := '_ALARMCLASSRESETBITMAP: $'$'' *)
_ALARMGROUPLISTNAME : 'System'
_ALARMGROUPPATH : 'System'
_ALARMGROUPLIST : 0
_VISUALSETTINGSFLAGS : 0,0,0,0
_VISUALSETTINGSFLAGS : '','',''
_VISUALSETTINGSDYNTEXTFILECOUNT : 0
(* @ALARMCONFIGFLAGS := '_ALARMCONFIGFLAGS: 0' *)
(* @ALARMCONFIGGLOBALDB_STR := '_ALARMCONFIGGLOBALDB_STRINGS: $'$',$'$',$'$',$'$'' *)
(* @ALARMCONFIGGLOBALDB_NUM := '_ALARMCONFIGGLOBALDB_NUMBERS: 0,0' *)
_END_ALARMCONFIG
LIBRARY
Standard.lib 2.12.10 14:48:34
(* @LIBRARYSYMFILEINFO := '0' *)
NumOfPOUs: 26
ASCIIBYTE_TO_STRING: 2048
CONCAT: 0
CTD: 0
CTU: 0
CTUD: 0
DELETE: 0
F_TRIG: 0
FIND: 0
INSERT: 0
LEFT: 0
LEN: 0
MID: 0
R_TRIG: 0
REAL_STATE: 2048
REPLACE: 0
RIGHT: 0
RS: 0
RTC: 0
SEMA: 0
SR: 0
STANDARD_VERSION: 2048
STRING_COMPARE: 2048
STRING_TO_ASCIIBYTE: 2048
TOF: 0
TON: 0
TP: 0
NumOfGVLs: 1
'Global Variables 0': 0
END_LIBRARY
LIBRARY
SYSLIBCALLBACK.LIB 2.12.10 14:48:32
(* @LIBRARYSYMFILEINFO := '0' *)
NumOfPOUs: 2
SysCallbackRegister: 0
SysCallbackUnregister: 0
NumOfGVLs: 2
Globale_Variablen: 0
Version: 0
END_LIBRARY
PLC_CONFIGURATION
_GLOBAL
_VERSION: 3
_AUTOADR: 0
_CHECKADR: 0
_SAVECONFIGFILESINPROJECT: 0
_END_GLOBAL
_MODULE: '3S'
_SECTION_NAME: 'Root'
_INDEX_IN_PARENT: '-1'
_MODULE_NAME: 'Hardware configuration'
_NODE_ID: -1
_IECIN: %IB0
_IECOUT: %QB0
_IECDIAG: %MB0
_DOWNLOAD: 1
_EXCLUDEFROMAUTOADR: 0
_COMMENT: ''
_MODULE: '3S'
_SECTION_NAME: 'K_Bus'
_INDEX_IN_PARENT: '1'
_MODULE_NAME: 'K-Bus'
_NODE_ID: 0
_IECIN: %IB0
_IECOUT: %QB0
_IECDIAG: %MB0
_DOWNLOAD: 1
_EXCLUDEFROMAUTOADR: 0
_COMMENT: ''
_END_MODULE
_MODULE: '3S'
_SECTION_NAME: 'FB_VARS'
_INDEX_IN_PARENT: '2'
_MODULE_NAME: 'Fieldbus variables'
_NODE_ID: 1
_IECIN: %IB0
_IECOUT: %QB0
_IECDIAG: %MB0
_DOWNLOAD: 1
_EXCLUDEFROMAUTOADR: 0
_COMMENT: ''
_END_MODULE
_END_MODULE
PLC_END
RESOURCE
{event_task : 'start','Called when program starts','','FUNCTION systemevent: DWORD VAR_INPUT dwEvent: DWORD; dwFilter: DWORD; dwOwner: DWORD; END_VAR '}{event_task_info : 0,1,11986}
{event_task : 'stop','Called when program stops','','FUNCTION systemevent: DWORD VAR_INPUT dwEvent: DWORD; dwFilter: DWORD; dwOwner: DWORD; END_VAR '}{event_task_info : 0,2,11986}
{event_task : 'before_reset','Called before reset takes place','','FUNCTION systemevent: DWORD VAR_INPUT dwEvent: DWORD; dwFilter: DWORD; dwOwner: DWORD; END_VAR '}{event_task_info : 0,3,11986}
{event_task : 'after_reset','Called after reset took place','','FUNCTION systemevent: DWORD VAR_INPUT dwEvent: DWORD; dwFilter: DWORD; dwOwner: DWORD; END_VAR '}{event_task_info : 0,4,11986}
{event_task : 'shutdown','Called before shutdown is performed (Firmware update over ethernet)','','FUNCTION systemevent: DWORD VAR_INPUT dwEvent: DWORD; dwFilter: DWORD; dwOwner: DWORD; END_VAR '}{event_task_info : 0,5,11986}
{event_task : 'excpt_watchdog','Software watchdog of IEC-task expired','','FUNCTION systemevent: DWORD VAR_INPUT dwEvent: DWORD; dwFilter: DWORD; dwOwner: DWORD; END_VAR '}{event_task_info : 0,7,11986}
{event_task : 'excpt_fieldbus','Fieldbus error','','FUNCTION systemevent: DWORD VAR_INPUT dwEvent: DWORD; dwFilter: DWORD; dwOwner: DWORD; END_VAR '}{event_task_info : 0,9,11986}
{event_task : 'excpt_ioupdate','KBus error','','FUNCTION systemevent: DWORD VAR_INPUT dwEvent: DWORD; dwFilter: DWORD; dwOwner: DWORD; END_VAR '}{event_task_info : 0,10,11986}
{event_task : 'excpt_dividebyzero','Division by zero. Only integer operations!','','FUNCTION systemevent: DWORD VAR_INPUT dwEvent: DWORD; dwFilter: DWORD; dwOwner: DWORD; END_VAR '}{event_task_info : 0,18,11986}
{event_task : 'excpt_noncontinuable','Exception handler','','FUNCTION systemevent: DWORD VAR_INPUT dwEvent: DWORD; dwFilter: DWORD; dwOwner: DWORD; END_VAR '}{event_task_info : 0,20,11986}
{event_task : 'after_reading_inputs','Called after reading of inputs','','FUNCTION systemevent: DWORD VAR_INPUT dwEvent: DWORD; dwFilter: DWORD; dwOwner: DWORD; END_VAR '}{event_task_info : 0,28,11986}
{event_task : 'before_writing_outputs','Called before writing of outputs','','FUNCTION systemevent: DWORD VAR_INPUT dwEvent: DWORD; dwFilter: DWORD; dwOwner: DWORD; END_VAR '}{event_task_info : 0,29,11986}
{event_task : 'debug_loop','Debug loop at breakpoint','','FUNCTION systemevent: DWORD VAR_INPUT dwEvent: DWORD; dwFilter: DWORD; dwOwner: DWORD; END_VAR '}{event_task_info : 0,31,11986}
{event_task : 'online_change','Is called after CodeInit() at Online-Change','','FUNCTION systemevent: DWORD VAR_INPUT dwEvent: DWORD; dwFilter: DWORD; dwOwner: DWORD; END_VAR '}{event_task_info : 0,33,11986}
{event_task : 'before_download','Is called before the Download starts','','FUNCTION systemevent: DWORD VAR_INPUT dwEvent: DWORD; dwFilter: DWORD; dwOwner: DWORD; END_VAR '}{event_task_info : 0,34,11986}
{event_task : 'event_login','Is called before the login service is performed','','FUNCTION systemevent: DWORD VAR_INPUT dwEvent: DWORD; dwFilter: DWORD; dwOwner: DWORD; END_VAR '}{event_task_info : 0,501,11986}
{event_task : 'eth_overload','Ethernet Overload','','FUNCTION systemevent: DWORD VAR_INPUT dwEvent: DWORD; dwFilter: DWORD; dwOwner: DWORD; END_VAR '}{event_task_info : 0,750,11986}
{event_task : 'eth_network_ready','Is called directly after the Network and the PLC are initialised','','FUNCTION systemevent: DWORD VAR_INPUT dwEvent: DWORD; dwFilter: DWORD; dwOwner: DWORD; END_VAR '}{event_task_info : 0,751,11986}
{event_task : 'blink_code','New blink code / Blink code cleared ( Call STATUS_GET_LAST_ERROR for details )','','FUNCTION systemevent: DWORD VAR_INPUT dwEvent: DWORD; dwFilter: DWORD; dwOwner: DWORD; END_VAR '}{event_task_info : 0,752,11986}
{event_task : 'interrupt_0','Interrupt Real Time Clock (every second)','','FUNCTION systemevent: DWORD VAR_INPUT dwEvent: DWORD; dwFilter: DWORD; dwOwner: DWORD; END_VAR '}{event_task_info : 0,1000,11986}
END_RESOURCE
_WORKSPACE
_GLOBALVISUALSETTINGS
_VISUALSETTINGSFLAGS : 0,0,0,0
_VISUALSETTINGSFLAGS : '','',''
_VISUALSETTINGSDYNTEXTFILECOUNT : 0
_VISUALBITMAPLISTCOUNT : 0
_END_GLOBALVISUALSETTINGS
_END_WORKSPACE
+15
View File
@@ -0,0 +1,15 @@
rem Create Codesys EXP file
rem Build cmd file
set CODESYS="c:\Program Files (x86)\WAGO Software\CoDeSys V2.3\codesys.exe"
set PROJECT=test
del %PROJECT%.EXP
echo file open %PROJECT%.pro >> codesys_cmd_file.cmd
echo project export %PROJECT%.EXP >> codesys_cmd_file.cmd
rem echo file saveas %PROJECT%.lib internallib >> codesys_cmd_file.cmd
echo file close >> codesys_cmd_file.cmd
echo file quit >> codesys_cmd_file.cmd
%CODESYS% /noinfo /cmd codesys_cmd_file.cmd
rem Clean all when finished
del codesys_cmd_file.cmd
Binary file not shown.
+2 -2
View File
@@ -2,11 +2,11 @@ Endianing off <hr>
0 --> Packet: 0000_0000_<br>
1 --> Packet: 0000_3f80_<br>
-2 --> Packet: 0000_c000_<br>
0.333333333333 --> Packet: aaaa_3eaa_<br>
0.333333333333 --> Packet: aaab_3eaa_<br>
25 --> Packet: 0000_41c8_<br>
Endianing on <hr>
0 --> Packet: 0000_0000_<br>
1 --> Packet: 3f80_0000_<br>
-2 --> Packet: c000_0000_<br>
0.333333333333 --> Packet: 3eaa_aaaa_<br>
0.333333333333 --> Packet: 3eaa_aaab_<br>
25 --> Packet: 41c8_0000_<br>
+1 -1
View File
@@ -7,7 +7,7 @@ $data = Array (
"0" => 0, // -> 0000 0000
"1" => 1, // -> 3f80 0000
"2" => -2, // -> c000 0000
"3" => 1/3, // -> 3eaa aaab
"3" => 0.333333333333, //1/3 -> 3eaa aaab
"4" => 25 // -> 41c8 0000
);
@@ -1,7 +1 @@
Fatal error: Uncaught exception 'Exception' with message 'Unknown socket protocol, should be 'TCP' or 'UDP'' in D:\Projects\20081010_phpmodbus\src\trunk\Phpmodbus\ModbusMaster.php:87
Stack trace:
#0 D:\Projects\20081010_phpmodbus\src\trunk\Phpmodbus\ModbusMaster.php(654): ModbusMaster->connect()
#1 D:\Projects\20081010_phpmodbus\src\trunk\tests\ModbusMaster\test.tcp.socket_protocol_mismatch.php(13): ModbusMaster->readWriteRegisters(0, 12288, 6, 12288, Array, Array)
#2 {main}
thrown in D:\Projects\20081010_phpmodbus\src\trunk\Phpmodbus\ModbusMaster.php on line 87
Caught exception: Unknown socket protocol, should be 'TCP' or 'UDP'
@@ -10,9 +10,13 @@ $data = array(1000, 2000, 1.250, 1.250);
$dataTypes = array("REAL", "REAL", "REAL", "REAL");
// FC23
$recData = $modbus->readWriteRegisters(0, 12288, 6, 12288, $data, $dataTypes);
try {
$recData = $modbus->readWriteRegisters(0, 12288, 6, 12288, $data, $dataTypes);
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
exit();
}
// Should through an Exception
// Print status information
echo "Something wrong!";
echo "Should never reach this line!";
@@ -0,0 +1,66 @@
array(32) {
[0]=>
bool(true)
[1]=>
bool(false)
[2]=>
bool(true)
[3]=>
bool(true)
[4]=>
bool(false)
[5]=>
bool(true)
[6]=>
bool(true)
[7]=>
bool(true)
[8]=>
bool(true)
[9]=>
bool(true)
[10]=>
bool(true)
[11]=>
bool(true)
[12]=>
bool(false)
[13]=>
bool(false)
[14]=>
bool(false)
[15]=>
bool(false)
[16]=>
bool(false)
[17]=>
bool(false)
[18]=>
bool(false)
[19]=>
bool(false)
[20]=>
bool(true)
[21]=>
bool(true)
[22]=>
bool(true)
[23]=>
bool(true)
[24]=>
bool(true)
[25]=>
bool(true)
[26]=>
bool(true)
[27]=>
bool(true)
[28]=>
bool(true)
[29]=>
bool(true)
[30]=>
bool(true)
[31]=>
bool(true)
}
@@ -62,7 +62,7 @@ Array
[10] => 192
[11] => 0
[12] => 170
[13] => 170
[13] => 171
[14] => 62
[15] => 170
[16] => 0
@@ -0,0 +1,7 @@
Test should pass when %IX0.0==FALSE and %IX0.1==TRUE
array(2) {
[0]=>
bool(false)
[1]=>
bool(true)
}
@@ -0,0 +1,11 @@
Test should pass when %IX0.0==FALSE and %IX0.1==TRUE
array(4) {
[0]=>
int(0)
[1]=>
int(2)
[2]=>
int(0)
[3]=>
int(0)
}
@@ -0,0 +1,5 @@
Array
(
[0] => 0
[1] => 5
)
@@ -0,0 +1,5 @@
Array
(
[0] => 207
[1] => 199
)
+5 -5
View File
@@ -12,11 +12,11 @@ $data = array(1, 0, TRUE, TRUE, 0, 1, TRUE, TRUE,
1, 1, TRUE, TRUE, 1, 1, TRUE, TRUE);
// Write data - FC 15
$modbus->writeMultipleCoils(0, 12288, $data);
echo $modbus->status;
$modbus->status = "";
echo "\n\n";
//echo $modbus->status;
//$modbus->status = "";
//echo "\n\n";
// Read data - FC 1
$recData = $modbus->readCoils(0, 12288, 32);
echo $modbus->status;
echo "\n\n";
//echo $modbus->status;
//echo "\n\n";
var_dump($recData);
+14
View File
@@ -0,0 +1,14 @@
<?php
require_once dirname(__FILE__) . '/../../Phpmodbus/ModbusMasterUdp.php';
require_once dirname(__FILE__) . '/../config.php';
// Create Modbus object
$modbus = new ModbusMasterUdp($test_host_ip);
// Test requirements
echo "Test should pass when %IX0.0==FALSE and %IX0.1==TRUE\n";
// Read input discretes - FC 2
$recData = $modbus->readInputDiscretes(0, 0, 2);
var_dump($recData);
+14
View File
@@ -0,0 +1,14 @@
<?php
require_once dirname(__FILE__) . '/../../Phpmodbus/ModbusMasterUdp.php';
require_once dirname(__FILE__) . '/../config.php';
// Create Modbus object
$modbus = new ModbusMasterUdp($test_host_ip);
// Test requirements
echo "Test should pass when %IX0.0==FALSE and %IX0.1==TRUE\n";
// Read input discretes - FC 4
$recData = $modbus->readMultipleInputRegisters(0, 0, 2);
var_dump($recData);
+23
View File
@@ -0,0 +1,23 @@
<?php
require_once dirname(__FILE__) . '/../../Phpmodbus/ModbusMasterUdp.php';
require_once dirname(__FILE__) . '/../config.php';
// Create Modbus object
$modbus = new ModbusMasterUdp($test_host_ip);
// Data to be writen - TRUE, FALSE
$data_true = array(TRUE);
$data_false = array(FALSE);
// Reset target WORD
$modbus->writeSingleRegister(0, 12288, array(0), array('WORD'));
// Write single coil - FC5
$modbus->writeSingleCoil(0, 12288, $data_true);
$modbus->writeSingleCoil(0, 12289, $data_false);
$modbus->writeSingleCoil(0, 12290, $data_true);
$modbus->writeSingleCoil(0, 12291, $data_false);
// Read data - FC3
$recData = $modbus->readMultipleRegisters(0, 12288, 1);
print_r($recData);
+15
View File
@@ -0,0 +1,15 @@
<?php
require_once dirname(__FILE__) . '/../../Phpmodbus/ModbusMasterUdp.php';
require_once dirname(__FILE__) . '/../config.php';
// Create Modbus object
$modbus = new ModbusMasterUdp($test_host_ip);
// Data to be writen - INT
$data = array(-12345);
$dataTypes = array("INT");
// Write data - FC6
$modbus->writeSingleRegister(0, 12288, $data, $dataTypes);
// Read data - FC3
$recData = $modbus->readMultipleRegisters(0, 12288, 1);
print_r($recData);
+3
View File
@@ -0,0 +1,3 @@
Probably broken and dubious.
Left from the original repo.
+1 -1
View File
@@ -1,4 +1,4 @@
set php=c:\Program_Files\xampplite\php\php.exe
set php=c:\Program_Files\xampp\php\php.exe
rem set php=C:\PHP\versions\php-5.2.6-Win32\php.exe -d auto_prepend_file=C:\PHP\locale.php
set diff="diff.exe"
rem set testUri=http://localHost/nette/_trunk/tests
+2 -3
View File
@@ -1,4 +1,3 @@
<?php
$test_host_ip = "192.192.15.51";
$test_bind_client_ip = "192.192.15.113";
?>
$test_host_ip = "192.192.1.10";
$test_bind_client_ip = "192.192.1.100";
-173
View File
@@ -1,173 +0,0 @@
<refentry id="{@id}">
<refnamediv>
<refname>Phpmodbus user's guide</refname>
<refpurpose>Phpmodbus How-to</refpurpose>
</refnamediv>
<refsynopsisdiv>
<author>
Jan Krakora
<authorblurb>
{@link mailto:krakora.jan@googlemail.com email}
</authorblurb>
</author>
</refsynopsisdiv>
{@toc}
<refsect1 id="{@id intro}">
<title>Introduction</title>
<para>
Phpmodbus is a PHP library for the Modbus protocol. The library implements
Modbus TCP/UDP master class with subset of the most used Modbus commands.
</para>
<para>
The library implements:
<itemizedlist>
<listitem><para>FC 1: read multiple coils</para></listitem>
<listitem><para>FC 3: read multiple registers</para></listitem>
<listitem><para>FC 15: write multiple coils</para></listitem>
<listitem><para>FC 16: write multiple registers</para></listitem>
<listitem><para>FC 23: read write registers</para></listitem>
</itemizedlist>
</para>
<para>
For more about Modbus protocol see [{@link http://www.modbus.org}] or
[{@link http://en.wikipedia.org/wiki/Modbus Wiki}]
</para>
<note>
Developed with support of <graphic fileref="wago_logo.png"/> {@link http://www.wago.com}.
</note>
</refsect1>
<refsect1 id="{@id install}">
<title>Install</title>
<para>
At the first, it is supposed an PHP solution has been already installed on
your server (LAMP, WAMP, MSS+CGI etc.).
</para>
<para>
Copy the Phpmodbus library to your PHP project folder.
</para>
<para>
Create a PHP script and assign the library using require_once() command
<programlisting role="c">
<![CDATA[require_once dirname(__FILE__) . '/Phpmodbus/ModbusMaster.php'; ]]>
</programlisting>
</para>
<para>
To create UDP Modbus master object communicating to an modbus slave
e.g. at IP address 192.168.1.1 write
<programlisting role="c" linenumbering="numbered" startinglinenumber="2">
<![CDATA[ $modbus = new ModbusMaster("192.168.1.1", "UDP"); ]]>
</programlisting>
</para>
<para>
To create TCP Modbus master use
<programlisting role="c" linenumbering="numbered" startinglinenumber="2">
<![CDATA[ $modbus = new ModbusMaster("192.168.1.1", "TCP"); ]]>
</programlisting>
</para>
<para>
To read 5 words (10 bytes) from the device ID=0 and its memory address 12288
use try-catch method call
<programlisting role="c" linenumbering="numbered" startinglinenumber="3">
<![CDATA[try {
// Function processing
$recData = $modbus->readMultipleRegisters(0, 12288, 5);
}
catch (Exception $e) {
// Exception processing, e.g. print error information
echo $modbus;
echo $e;
exit;
}]]>
</programlisting>
</para>
<para>
To process the function byte stream, use conversion to PHP types in
</para>
<programlisting role="c" linenumbering="numbered" startinglinenumber="15">
<![CDATA[echo PhpType::bytes2string($recData); ]]>
</programlisting>
<para>
For other examples see sections bellow.
</para>
</refsect1>
<refsect1 id="{@id examples}">
<title>Examples</title>
<para>
This section presents library features and examples
</para>
<refsect2 id="{@id example_fc1}">
<title>FC1 - read mutliple coils</title>
<para>
FC1 functionality example
</para>
<para>
{@example example_fc1.php}
</para>
</refsect2>
<refsect2 id="{@id example_fc3}">
<title>FC3 - read mutliple registers</title>
<para>
FC3 functionality example
</para>
<para>
{@example example_fc3.php}
</para>
</refsect2>
<refsect2 id="{@id example_fc15}">
<title>FC15 - write mutliple coils</title>
<para>
FC15 functionality example
</para>
<para>
{@example example_fc15.php}
</para>
</refsect2>
<refsect2 id="{@id example_fc16}">
<title>FC16 - write mutliple registers</title>
<para>
FC16 functionality example
</para>
<para>
{@example example_fc16.php}
</para>
</refsect2>
<refsect2 id="{@id example_fc23}">
<title>FC23 - read write registers</title>
<para>
FC23 functionality example
</para>
<para>
{@example example_fc23.php}
</para>
</refsect2>
<refsect2 id="{@id wago_example}">
<title>Dump of M-memory from WAGO 750-84x series coupler.</title>
<para>
Dump of M-memory from WAGO 750-84x series coupler.
</para>
<para>
{@example example_750841_Mmemory.php}
</para>
</refsect2>
<refsect2 id="{@id datatype}">
<title>Data conversion to PHP types.</title>
<para>
Conversion of the data bytes, received from Modbus, to a PHP type.
</para>
<para>
{@example example_datatype.php}
</para>
</refsect2>
</refsect1>
<refsect1 id="{@id back_comp}">
<title>Back compatibility</title>
<para>
This version is back compatible to the last versions. Just use
<programlisting role="c">
<![CDATA[require_once dirname(__FILE__) . '/Phpmodbus/ModbusMasterUdp.php';
$modbus = new ModbusMasterUdp("192.168.1.1");
// ... ]]>
</programlisting>
</para>
</refsect1>
</refentry>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB