From aca6f077bfeaf8c5fe60315859df3514f309e0d1 Mon Sep 17 00:00:00 2001 From: "krakora.jan@googlemail.com" Date: Tue, 29 May 2012 16:54:11 +0000 Subject: [PATCH 01/24] sandbox From 13d1fb794bc7fc94daa7b7bcbeb02d55a91910b4 Mon Sep 17 00:00:00 2001 From: "krakora.jan@googlemail.com" Date: Tue, 29 May 2012 17:22:21 +0000 Subject: [PATCH 02/24] FC6 --- Phpmodbus/ModbusMaster.php | 105 ++++++++++++++++++++++++++++++++++++- 1 file changed, 103 insertions(+), 2 deletions(-) diff --git a/Phpmodbus/ModbusMaster.php b/Phpmodbus/ModbusMaster.php index 738892a..8ca71a7 100644 --- a/Phpmodbus/ModbusMaster.php +++ b/Phpmodbus/ModbusMaster.php @@ -508,6 +508,107 @@ private function readMultipleRegistersParser($packet){ return $data; } + /** + * 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 * @@ -525,7 +626,7 @@ function writeMultipleCoils($unitId, $reference, $data){ $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); @@ -740,7 +841,7 @@ private function writeMultipleRegisterParser($packet){ $this->responseCode($packet); return true; } - + /** * readWriteRegisters * From 9293309c713ebf6ff849278251691bcc8fefa081 Mon Sep 17 00:00:00 2001 From: "krakora.jan@googlemail.com" Date: Wed, 8 Aug 2012 21:25:45 +0000 Subject: [PATCH 03/24] IecType static function declaration fix --- Phpmodbus/IecType.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Phpmodbus/IecType.php b/Phpmodbus/IecType.php index 9beb696..dd23ccc 100644 --- a/Phpmodbus/IecType.php +++ b/Phpmodbus/IecType.php @@ -34,7 +34,7 @@ class IecType { * @return value IEC BYTE data type * */ - function iecBYTE($value) { + public static function iecBYTE($value) { return chr($value & 0xFF); } @@ -47,7 +47,7 @@ function iecBYTE($value) { * @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 +62,7 @@ function iecINT($value) { * @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 +76,7 @@ function iecDINT($value, $endianness = 0) { * @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 +95,7 @@ function iecREAL($value, $endianness = 0) { * @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 +113,7 @@ private function float2iecReal($value) { * @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) . From 2e4e5f284dc611f589d54694bb8bd019f52c1ea5 Mon Sep 17 00:00:00 2001 From: "krakora.jan@googlemail.com" Date: Wed, 8 Aug 2012 21:26:15 +0000 Subject: [PATCH 04/24] test config scripts updates --- tests/config.bat | 2 +- tests/config.php | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/config.bat b/tests/config.bat index 5560180..ef49dfc 100644 --- a/tests/config.bat +++ b/tests/config.bat @@ -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 diff --git a/tests/config.php b/tests/config.php index e9133a3..f458917 100644 --- a/tests/config.php +++ b/tests/config.php @@ -1,4 +1,3 @@ \ No newline at end of file + $test_host_ip = "192.168.1.105"; + $test_bind_client_ip = "192.168.1.106"; \ No newline at end of file From 8d53a92232f6688272aef7d23ad1a9b9747f4034 Mon Sep 17 00:00:00 2001 From: "krakora.jan@googlemail.com" Date: Wed, 8 Aug 2012 21:29:28 +0000 Subject: [PATCH 05/24] Codesys test project --- tests/Codesys/TEST.EXP | 256 ++++++++++++++++++++++++++++++++++++ tests/Codesys/_make_exp.cmd | 15 +++ tests/Codesys/test.pro | Bin 0 -> 34020 bytes 3 files changed, 271 insertions(+) create mode 100644 tests/Codesys/TEST.EXP create mode 100644 tests/Codesys/_make_exp.cmd create mode 100644 tests/Codesys/test.pro diff --git a/tests/Codesys/TEST.EXP b/tests/Codesys/TEST.EXP new file mode 100644 index 0000000..3e6f226 --- /dev/null +++ b/tests/Codesys/TEST.EXP @@ -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 diff --git a/tests/Codesys/_make_exp.cmd b/tests/Codesys/_make_exp.cmd new file mode 100644 index 0000000..415af58 --- /dev/null +++ b/tests/Codesys/_make_exp.cmd @@ -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 \ No newline at end of file diff --git a/tests/Codesys/test.pro b/tests/Codesys/test.pro new file mode 100644 index 0000000000000000000000000000000000000000..6904c0c412cd9814cce6b332086a34bc044fff9d GIT binary patch literal 34020 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 Date: Wed, 8 Aug 2012 21:33:17 +0000 Subject: [PATCH 06/24] test.fc15fc1.php.html reference update, wrong 0.3333 interpretation --- tests/ModbusMasterUdp/ref/test.fc16fc3.php.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ModbusMasterUdp/ref/test.fc16fc3.php.html b/tests/ModbusMasterUdp/ref/test.fc16fc3.php.html index c3e4836..00dd046 100644 --- a/tests/ModbusMasterUdp/ref/test.fc16fc3.php.html +++ b/tests/ModbusMasterUdp/ref/test.fc16fc3.php.html @@ -62,7 +62,7 @@ [10] => 192 [11] => 0 [12] => 170 - [13] => 170 + [13] => 171 [14] => 62 [15] => 170 [16] => 0 From 2f43e23a8edbd9c1b56e613c407f2309296dbed5 Mon Sep 17 00:00:00 2001 From: "krakora.jan@googlemail.com" Date: Wed, 8 Aug 2012 21:33:55 +0000 Subject: [PATCH 07/24] test fc15 fc1 update, reference added --- .../ModbusMasterUdp/ref/test.fc15fc1.php.html | 66 +++++++++++++++++++ tests/ModbusMasterUdp/test.fc15fc1.php | 10 +-- 2 files changed, 71 insertions(+), 5 deletions(-) create mode 100644 tests/ModbusMasterUdp/ref/test.fc15fc1.php.html diff --git a/tests/ModbusMasterUdp/ref/test.fc15fc1.php.html b/tests/ModbusMasterUdp/ref/test.fc15fc1.php.html new file mode 100644 index 0000000..55a3de0 --- /dev/null +++ b/tests/ModbusMasterUdp/ref/test.fc15fc1.php.html @@ -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) +} diff --git a/tests/ModbusMasterUdp/test.fc15fc1.php b/tests/ModbusMasterUdp/test.fc15fc1.php index 090bdcb..5a7d8c4 100644 --- a/tests/ModbusMasterUdp/test.fc15fc1.php +++ b/tests/ModbusMasterUdp/test.fc15fc1.php @@ -12,11 +12,11 @@ 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); \ No newline at end of file From f75c386b77b3831fac634091fc6150f8bbb36e8c Mon Sep 17 00:00:00 2001 From: "krakora.jan@googlemail.com" Date: Wed, 8 Aug 2012 21:36:22 +0000 Subject: [PATCH 08/24] test IecReal fix for value=1/3, test did not fit to the current PHP data type interpretation. --- tests/IecType/ref/test.iecReal.php.html | 24 ++++++++++++------------ tests/IecType/test.iecReal.php | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/tests/IecType/ref/test.iecReal.php.html b/tests/IecType/ref/test.iecReal.php.html index 661237e..a195b00 100644 --- a/tests/IecType/ref/test.iecReal.php.html +++ b/tests/IecType/ref/test.iecReal.php.html @@ -1,12 +1,12 @@ -Endianing off
-0 --> Packet: 0000_0000_
-1 --> Packet: 0000_3f80_
--2 --> Packet: 0000_c000_
-0.333333333333 --> Packet: aaaa_3eaa_
-25 --> Packet: 0000_41c8_
-Endianing on
-0 --> Packet: 0000_0000_
-1 --> Packet: 3f80_0000_
--2 --> Packet: c000_0000_
-0.333333333333 --> Packet: 3eaa_aaaa_
-25 --> Packet: 41c8_0000_
\ No newline at end of file +Endianing off
+0 --> Packet: 0000_0000_
+1 --> Packet: 0000_3f80_
+-2 --> Packet: 0000_c000_
+0.333333333333 --> Packet: aaab_3eaa_
+25 --> Packet: 0000_41c8_
+Endianing on
+0 --> Packet: 0000_0000_
+1 --> Packet: 3f80_0000_
+-2 --> Packet: c000_0000_
+0.333333333333 --> Packet: 3eaa_aaab_
+25 --> Packet: 41c8_0000_
diff --git a/tests/IecType/test.iecReal.php b/tests/IecType/test.iecReal.php index f9ed82d..30495fd 100644 --- a/tests/IecType/test.iecReal.php +++ b/tests/IecType/test.iecReal.php @@ -7,7 +7,7 @@ "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 ); From bc8f48ef47e8a9882a08fd64435ca00674bfe5d6 Mon Sep 17 00:00:00 2001 From: "krakora.jan@googlemail.com" Date: Thu, 9 Aug 2012 11:03:34 +0000 Subject: [PATCH 09/24] test.tcp.socket_protocol_mismatch try-catch update --- .../ref/test.tcp.socket_protocol_mismatch.php.html | 8 +------- .../ModbusMaster/test.tcp.socket_protocol_mismatch.php | 10 +++++++--- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/tests/ModbusMaster/ref/test.tcp.socket_protocol_mismatch.php.html b/tests/ModbusMaster/ref/test.tcp.socket_protocol_mismatch.php.html index 294f1f5..b25cfe4 100644 --- a/tests/ModbusMaster/ref/test.tcp.socket_protocol_mismatch.php.html +++ b/tests/ModbusMaster/ref/test.tcp.socket_protocol_mismatch.php.html @@ -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' diff --git a/tests/ModbusMaster/test.tcp.socket_protocol_mismatch.php b/tests/ModbusMaster/test.tcp.socket_protocol_mismatch.php index ed016b4..aa5f691 100644 --- a/tests/ModbusMaster/test.tcp.socket_protocol_mismatch.php +++ b/tests/ModbusMaster/test.tcp.socket_protocol_mismatch.php @@ -10,9 +10,13 @@ $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!"; \ No newline at end of file +echo "Should never reach this line!"; \ No newline at end of file From bc9f4681da792bde814ccb4287ebe020d806f0ea Mon Sep 17 00:00:00 2001 From: "krakora.jan@googlemail.com" Date: Thu, 9 Aug 2012 11:10:37 +0000 Subject: [PATCH 10/24] test FC6 added --- tests/ModbusMasterUdp/ref/test.fc6fc3.php.html | 5 +++++ tests/ModbusMasterUdp/test.fc6fc3.php | 15 +++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 tests/ModbusMasterUdp/ref/test.fc6fc3.php.html create mode 100644 tests/ModbusMasterUdp/test.fc6fc3.php diff --git a/tests/ModbusMasterUdp/ref/test.fc6fc3.php.html b/tests/ModbusMasterUdp/ref/test.fc6fc3.php.html new file mode 100644 index 0000000..6102dcd --- /dev/null +++ b/tests/ModbusMasterUdp/ref/test.fc6fc3.php.html @@ -0,0 +1,5 @@ +Array +( + [0] => 207 + [1] => 199 +) diff --git a/tests/ModbusMasterUdp/test.fc6fc3.php b/tests/ModbusMasterUdp/test.fc6fc3.php new file mode 100644 index 0000000..03c39f5 --- /dev/null +++ b/tests/ModbusMasterUdp/test.fc6fc3.php @@ -0,0 +1,15 @@ +writeSingleRegister(0, 12288, $data, $dataTypes); +// Read data - FC3 +$recData = $modbus->readMultipleRegisters(0, 12288, 1); +print_r($recData); From 119eb06fd53a63b494dd059f53161027752d3c00 Mon Sep 17 00:00:00 2001 From: "krakora.jan@googlemail.com" Date: Thu, 9 Aug 2012 11:20:20 +0000 Subject: [PATCH 11/24] test FC2 added --- tests/ModbusMasterUdp/ref/test.fc2.php.html | 7 +++++++ tests/ModbusMasterUdp/test.fc2.php | 14 ++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 tests/ModbusMasterUdp/ref/test.fc2.php.html create mode 100644 tests/ModbusMasterUdp/test.fc2.php diff --git a/tests/ModbusMasterUdp/ref/test.fc2.php.html b/tests/ModbusMasterUdp/ref/test.fc2.php.html new file mode 100644 index 0000000..5baae72 --- /dev/null +++ b/tests/ModbusMasterUdp/ref/test.fc2.php.html @@ -0,0 +1,7 @@ +Test should pass when %IX0.0==FALSE and %IX0.1==TRUE +array(2) { + [0]=> + bool(false) + [1]=> + bool(true) +} diff --git a/tests/ModbusMasterUdp/test.fc2.php b/tests/ModbusMasterUdp/test.fc2.php new file mode 100644 index 0000000..3c73077 --- /dev/null +++ b/tests/ModbusMasterUdp/test.fc2.php @@ -0,0 +1,14 @@ +readInputDiscretes(0, 0, 2); + +var_dump($recData); \ No newline at end of file From 5298c1ba023353b3d5bccf5cc2094936fad6d369 Mon Sep 17 00:00:00 2001 From: "krakora.jan@googlemail.com" Date: Thu, 9 Aug 2012 11:42:48 +0000 Subject: [PATCH 12/24] commentaries update --- Phpmodbus/ModbusMaster.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Phpmodbus/ModbusMaster.php b/Phpmodbus/ModbusMaster.php index 8ca71a7..e5a0ba6 100644 --- a/Phpmodbus/ModbusMaster.php +++ b/Phpmodbus/ModbusMaster.php @@ -25,8 +25,10 @@ * * Implemented MODBUS master functions: * - FC 1: read coils + * - FC 2: read input discretes * - FC 3: read multiple registers - * - FC 15: write multiple coils + * - FC 6: write single register + * - FC 15: write multiple coils * - FC 16: write multiple registers * - FC 23: read write registers * From dcab5a883f9049fa6fbc7c4326acdf3f4a4ccb21 Mon Sep 17 00:00:00 2001 From: "krakora.jan@googlemail.com" Date: Thu, 9 Aug 2012 12:00:17 +0000 Subject: [PATCH 13/24] FC2 example update --- examples/example_fc2.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/example_fc2.php b/examples/example_fc2.php index 6e61988..62c0157 100644 --- a/examples/example_fc2.php +++ b/examples/example_fc2.php @@ -7,7 +7,8 @@ try { // FC 2 - $recData = $modbus->readInputDiscretes(0, 12288, 12); + // read 2 input bits from address 0x0 (Wago input image) + $recData = $modbus->readInputDiscretes(0, 0, 2); } catch (Exception $e) { // Print error information if any From 90a5baa102d323b223601c915df9f47577c320dd Mon Sep 17 00:00:00 2001 From: "krakora.jan@googlemail.com" Date: Thu, 9 Aug 2012 12:00:41 +0000 Subject: [PATCH 14/24] FC6 example --- examples/example_fc6.php | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 examples/example_fc6.php diff --git a/examples/example_fc6.php b/examples/example_fc6.php new file mode 100644 index 0000000..4db6b04 --- /dev/null +++ b/examples/example_fc6.php @@ -0,0 +1,26 @@ +writeSingleRegister(0, 12288, $data, $dataTypes); +} +catch (Exception $e) { + // Print error information if any + echo $modbus; + echo $e; + exit; +} + +// Print status information +echo $modbus; + +?> \ No newline at end of file From 89c0ec1f8d5a4ad71b71876b0fee93c2bc9d5174 Mon Sep 17 00:00:00 2001 From: "krakora.jan@googlemail.com" Date: Thu, 9 Aug 2012 12:25:35 +0000 Subject: [PATCH 15/24] Commentaries update --- Phpmodbus/PhpType.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Phpmodbus/PhpType.php b/Phpmodbus/PhpType.php index 97670a9..5552e61 100644 --- a/Phpmodbus/PhpType.php +++ b/Phpmodbus/PhpType.php @@ -1,12 +1,12 @@ Date: Thu, 9 Aug 2012 12:27:32 +0000 Subject: [PATCH 16/24] Documentation update --- tutorials/Phpmodbus/Phpmodbus.pkg | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/tutorials/Phpmodbus/Phpmodbus.pkg b/tutorials/Phpmodbus/Phpmodbus.pkg index 2ef74ff..1bb1318 100644 --- a/tutorials/Phpmodbus/Phpmodbus.pkg +++ b/tutorials/Phpmodbus/Phpmodbus.pkg @@ -22,7 +22,9 @@ The library implements: FC 1: read multiple coils + FC 2: read input discretes FC 3: read multiple registers + FC 6: write single register FC 15: write multiple coils FC 16: write multiple registers FC 23: read write registers @@ -32,9 +34,6 @@ For more about Modbus protocol see [{@link http://www.modbus.org}] or [{@link http://en.wikipedia.org/wiki/Modbus Wiki}] - - Developed with support of {@link http://www.wago.com}. - Install @@ -104,6 +103,15 @@ catch (Exception $e) { {@example example_fc1.php} + + FC2 - read input discretes + + FC2 functionality example + + + {@example example_fc2.php} + + FC3 - read mutliple registers @@ -113,6 +121,15 @@ catch (Exception $e) { {@example example_fc3.php} + + FC6 - write single register + + FC6 functionality example + + + {@example example_fc6.php} + + FC15 - write mutliple coils From 6823623260bed4a534f1503ac63955e1ff79dcf6 Mon Sep 17 00:00:00 2001 From: "krakora.jan@googlemail.com" Date: Tue, 5 Feb 2013 11:36:07 +0000 Subject: [PATCH 17/24] Issue 16 fix --- Phpmodbus/ModbusMaster.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Phpmodbus/ModbusMaster.php b/Phpmodbus/ModbusMaster.php index e5a0ba6..18451ca 100644 --- a/Phpmodbus/ModbusMaster.php +++ b/Phpmodbus/ModbusMaster.php @@ -98,6 +98,8 @@ private function connect(){ $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) { From ee5a4f8a67b344e16b0330372bb0f89fe410040f Mon Sep 17 00:00:00 2001 From: "krakora.jan@googlemail.com" Date: Tue, 5 Feb 2013 11:59:40 +0000 Subject: [PATCH 18/24] Commentaries update --- Phpmodbus/IecType.php | 6 +++--- license.txt | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Phpmodbus/IecType.php b/Phpmodbus/IecType.php index dd23ccc..74c1314 100644 --- a/Phpmodbus/IecType.php +++ b/Phpmodbus/IecType.php @@ -1,12 +1,12 @@ Date: Tue, 9 Jul 2013 20:54:55 +0000 Subject: [PATCH 19/24] readMultipleInputRegisters, FC 4(0x04) --- Phpmodbus/ModbusMaster.php | 99 +++++++++++++++++++++ tests/ModbusMasterUdp/ref/test.fc4.php.html | 11 +++ tests/ModbusMasterUdp/test.fc4.php | 14 +++ tests/config.php | 4 +- 4 files changed, 126 insertions(+), 2 deletions(-) create mode 100644 tests/ModbusMasterUdp/ref/test.fc4.php.html create mode 100644 tests/ModbusMasterUdp/test.fc4.php diff --git a/Phpmodbus/ModbusMaster.php b/Phpmodbus/ModbusMaster.php index 18451ca..724613c 100644 --- a/Phpmodbus/ModbusMaster.php +++ b/Phpmodbus/ModbusMaster.php @@ -512,6 +512,105 @@ private function readMultipleRegistersParser($packet){ 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 + int(0) + [1]=> + int(2) + [2]=> + int(0) + [3]=> + int(0) +} diff --git a/tests/ModbusMasterUdp/test.fc4.php b/tests/ModbusMasterUdp/test.fc4.php new file mode 100644 index 0000000..dee4929 --- /dev/null +++ b/tests/ModbusMasterUdp/test.fc4.php @@ -0,0 +1,14 @@ +readMultipleInputRegisters(0, 0, 2); + +var_dump($recData); \ No newline at end of file diff --git a/tests/config.php b/tests/config.php index f458917..9c71b4a 100644 --- a/tests/config.php +++ b/tests/config.php @@ -1,3 +1,3 @@ Date: Tue, 9 Jul 2013 21:23:44 +0000 Subject: [PATCH 20/24] writeSingleCoil, FC5 --- Phpmodbus/ModbusMaster.php | 102 ++++++++++++++++++++ tests/ModbusMasterUdp/ref/test.fc5.php.html | 5 + tests/ModbusMasterUdp/test.fc5.php | 23 +++++ 3 files changed, 130 insertions(+) create mode 100644 tests/ModbusMasterUdp/ref/test.fc5.php.html create mode 100644 tests/ModbusMasterUdp/test.fc5.php diff --git a/Phpmodbus/ModbusMaster.php b/Phpmodbus/ModbusMaster.php index 724613c..9f6bd3d 100644 --- a/Phpmodbus/ModbusMaster.php +++ b/Phpmodbus/ModbusMaster.php @@ -611,6 +611,108 @@ private function readMultipleInputRegistersParser($packet){ 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 * diff --git a/tests/ModbusMasterUdp/ref/test.fc5.php.html b/tests/ModbusMasterUdp/ref/test.fc5.php.html new file mode 100644 index 0000000..a6a24be --- /dev/null +++ b/tests/ModbusMasterUdp/ref/test.fc5.php.html @@ -0,0 +1,5 @@ +Array +( + [0] => 0 + [1] => 5 +) diff --git a/tests/ModbusMasterUdp/test.fc5.php b/tests/ModbusMasterUdp/test.fc5.php new file mode 100644 index 0000000..95e6f92 --- /dev/null +++ b/tests/ModbusMasterUdp/test.fc5.php @@ -0,0 +1,23 @@ +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); From a49b112449f072b88c2d04c133d797856ccec504 Mon Sep 17 00:00:00 2001 From: "krakora.jan@googlemail.com" Date: Tue, 9 Jul 2013 21:31:27 +0000 Subject: [PATCH 21/24] Commentary update --- Phpmodbus/ModbusMaster.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Phpmodbus/ModbusMaster.php b/Phpmodbus/ModbusMaster.php index 9f6bd3d..e115d11 100644 --- a/Phpmodbus/ModbusMaster.php +++ b/Phpmodbus/ModbusMaster.php @@ -1,12 +1,12 @@ Date: Tue, 9 Jul 2013 21:44:42 +0000 Subject: [PATCH 22/24] Documentation update --- examples/example_fc4.php | 19 +++++++++++++++++++ examples/example_fc5.php | 24 ++++++++++++++++++++++++ tutorials/Phpmodbus/Phpmodbus.pkg | 20 ++++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 examples/example_fc4.php create mode 100644 examples/example_fc5.php diff --git a/examples/example_fc4.php b/examples/example_fc4.php new file mode 100644 index 0000000..cb75cf9 --- /dev/null +++ b/examples/example_fc4.php @@ -0,0 +1,19 @@ +readMultipleInputRegisters(0, 0, 2); +} +catch (Exception $e) { + // Print error information if any + echo $modbus; + echo $e; + exit; +} + +var_dump($recData); \ No newline at end of file diff --git a/examples/example_fc5.php b/examples/example_fc5.php new file mode 100644 index 0000000..764a805 --- /dev/null +++ b/examples/example_fc5.php @@ -0,0 +1,24 @@ +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; +} diff --git a/tutorials/Phpmodbus/Phpmodbus.pkg b/tutorials/Phpmodbus/Phpmodbus.pkg index 1bb1318..d3e57ea 100644 --- a/tutorials/Phpmodbus/Phpmodbus.pkg +++ b/tutorials/Phpmodbus/Phpmodbus.pkg @@ -24,6 +24,8 @@ FC 1: read multiple 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 @@ -121,6 +123,24 @@ catch (Exception $e) { {@example example_fc3.php} + + FC4 - read multiple input registers + + FC4 functionality example + + + {@example example_fc4.php} + + + + FC5 - write single coil + + FC5 functionality example + + + {@example example_fc5.php} + + FC6 - write single register From 93b429001a9d118be52fe27fc7dde656d36d908d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=A4umler?= <39997594+SebastianBaeumler@users.noreply.github.com> Date: Thu, 25 Jul 2019 09:35:46 +0200 Subject: [PATCH 23/24] Add explicit Connect and Disconnect --- Phpmodbus/ModbusMaster.php | 351 ++++++++++++++++++++++++++++++++++++- 1 file changed, 342 insertions(+), 9 deletions(-) diff --git a/Phpmodbus/ModbusMaster.php b/Phpmodbus/ModbusMaster.php index 738892a..afb82b4 100644 --- a/Phpmodbus/ModbusMaster.php +++ b/Phpmodbus/ModbusMaster.php @@ -1,12 +1,13 @@ socket_protocol = $protocol; $this->host = $host; + $this->explicit = false; } /** @@ -76,6 +83,12 @@ function __toString() { * @return bool */ private function connect(){ + if($this->explicit == false){ + $this->connectInternal(); + } + } + + private function connectInternal(){ // Create a protocol specific socket if ($this->socket_protocol == "TCP"){ // TCP socket @@ -96,6 +109,8 @@ private function connect(){ $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) { @@ -112,7 +127,14 @@ private function connect(){ * * Disconnect the socket */ - private function disconnect(){ + + private function disconnect(){ + if($this->explicit == false){ + $this->disconnectInternal(); + } + } + + private function disconnectInternal(){ socket_close($this->sock); $this->status .= "Disconnected\n"; } @@ -203,6 +225,15 @@ private function responseCode($packet){ } } + function connectExplicit(){ + $this->explicit = true; + $this->connectInternal(); + } + + function disconnectExplicit(){ + $this->explicit = false; + $this->disconnectInternal(); + } /** * readCoils * @@ -508,6 +539,308 @@ private function readMultipleRegistersParser($packet){ 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;$istatus .= "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 * @@ -525,7 +858,7 @@ function writeMultipleCoils($unitId, $reference, $data){ $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); @@ -740,7 +1073,7 @@ private function writeMultipleRegisterParser($packet){ $this->responseCode($packet); return true; } - + /** * readWriteRegisters * From 4b5b2e96e766f750d48d28b7a1058948eee17580 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=A4umler?= <39997594+SebastianBaeumler@users.noreply.github.com> Date: Thu, 25 Jul 2019 10:05:41 +0200 Subject: [PATCH 24/24] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index cfe6ac6..0d5eeaf 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +forked from krakorj/phpmodbus + [![PayPayl donate button](https://img.shields.io/badge/paypal-donate-yellow.svg)](http://paypal.me/krakorj) # Phpmodbus