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 @@ 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 +62,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 +76,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 +95,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 +113,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) . diff --git a/Phpmodbus/ModbusMaster.php b/Phpmodbus/ModbusMaster.php index 0a1997d..e5a0ba6 100644 --- a/Phpmodbus/ModbusMaster.php +++ b/Phpmodbus/ModbusMaster.php @@ -1,798 +1,1012 @@ -socket_protocol = $protocol; - $this->host = $host; - } - - /** - * __toString - * - * Magic method - */ - function __toString() { - return "
" . $this->status . "
"; - } - - /** - * connect - * - * Connect the socket - * - * @return bool - */ - private function connect(){ - // Create a protocol specific socket - if ($this->socket_protocol == "TCP"){ - // TCP socket - $this->sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); - } elseif ($this->socket_protocol == "UDP"){ - // UDP socket - $this->sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); - } else { - throw new Exception("Unknown socket protocol, should be 'TCP' or 'UDP'"); - } - // Bind the client socket to a specific local port - if (strlen($this->client)>0){ - $result = socket_bind($this->sock, $this->client, $this->client_port); - if ($result === false) { - throw new Exception("socket_bind() failed.
Reason: ($result)". - socket_strerror(socket_last_error($this->sock))); - } else { - $this->status .= "Bound\n"; - } - } - // Connect the socket - $result = @socket_connect($this->sock, $this->host, $this->port); - if ($result === false) { - throw new Exception("socket_connect() failed.
Reason: ($result)". - socket_strerror(socket_last_error($this->sock))); - } else { - $this->status .= "Connected\n"; - return true; - } - } - - /** - * disconnect - * - * Disconnect the socket - */ - private function disconnect(){ - socket_close($this->sock); - $this->status .= "Disconnected\n"; - } - - /** - * send - * - * Send the packet via Modbus - * - * @param string $packet - */ - private function send($packet){ - socket_write($this->sock, $packet, strlen($packet)); - $this->status .= "Send\n"; - } - - /** - * rec - * - * Receive data from the socket - * - * @return bool - */ - private function rec(){ - socket_set_nonblock($this->sock); - $readsocks[] = $this->sock; - $writesocks = NULL; - $exceptsocks = NULL; - $rec = ""; - $lastAccess = time(); - while (socket_select($readsocks, - $writesocks, - $exceptsocks, - 0, - 300000) !== FALSE) { - $this->status .= "Wait data ... \n"; - if (in_array($this->sock, $readsocks)) { - while (@socket_recv($this->sock, $rec, 2000, 0)) { - $this->status .= "Data received\n"; - return $rec; - } - $lastAccess = time(); - } else { - if (time()-$lastAccess >= $this->timeout_sec) { - throw new Exception( "Watchdog time expired [ " . - $this->timeout_sec . " sec]!!! Connection to " . - $this->host . " is not established."); - } - } - $readsocks[] = $this->sock; - } - } - - /** - * responseCode - * - * Check the Modbus response code - * - * @param string $packet - * @return bool - */ - private function responseCode($packet){ - if(($packet[7] & 0x80) > 0) { - throw new Exception("Modbus response error code:" . ord($packet[8])); - } else { - $this->status .= "Modbus response error code: NOERROR\n"; - return true; - } - } - - /** - * readCoils - * - * 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 $unitId}. - * - * @param type $unitId - * @param type $reference - * @param type $quantity - */ - function readCoils($unitId, $reference, $quantity){ - $this->status .= "readCoils: START\n"; - // connect - $this->connect(); - // send FC 3 - $packet = $this->readCoilsPacketBuilder($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->readCoilsParser($rpacket, $quantity); - // disconnect - $this->disconnect(); - $this->status .= "readCoils: DONE\n"; - // return - return $receivedData; - } - - /** - * fc1 - * - * Alias to {@link readMultipleCoils} method - * - * @param type $unitId - * @param type $reference - * @param type $quantity - * @return type - */ - function fc1($unitId, $reference, $quantity){ - return $this->readCoils($unitId, $reference, $quantity); - } - - /** - * readCoilsPacketBuilder - * - * FC1 packet builder - read coils - * - * @param type $unitId - * @param type $reference - * @param type $quantity - * @return type - */ - private function readCoilsPacketBuilder($unitId, $reference, $quantity){ - $dataLen = 0; - // build data section - $buffer1 = ""; - // build body - $buffer2 = ""; - $buffer2 .= iecType::iecBYTE(1); // FC 1 = 1(0x01) - // 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; - } - - /** - * readCoilsParser - * - * FC 1 response parser - * - * @param type $packet - * @param type $quantity - * @return type - */ - private function readCoilsParser($packet, $quantity){ - $data = array(); - // check Response code - $this->responseCode($packet); - // get data from stream - for($i=0;$i $quantity) continue; - // get boolean value - $v = ($value >> $i) & 0x01; - // build boolean array - if($v == 0){ - $data_bolean_array[] = FALSE; - } else { - $data_bolean_array[] = TRUE; - } - $di++; - } - } - return $data_bolean_array; - } - - /** - * readMultipleRegisters - * - * Modbus function FC 3(0x03) - Read Multiple 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 (e.g. in device WAGO 750-841, memory MW0 starts at address 12288). - * @param int $quantity Amounth of the data to be read from device. - * @return false|Array Success flag or array of received data. - */ - function readMultipleRegisters($unitId, $reference, $quantity){ - $this->status .= "readMultipleRegisters: START\n"; - // connect - $this->connect(); - // send FC 3 - $packet = $this->readMultipleRegistersPacketBuilder($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->readMultipleRegistersParser($rpacket); - // disconnect - $this->disconnect(); - $this->status .= "readMultipleRegisters: DONE\n"; - // return - return $receivedData; - } - - /** - * fc3 - * - * Alias to {@link readMultipleRegisters} method. - * - * @param int $unitId - * @param int $reference - * @param int $quantity - * @return false|Array - */ - function fc3($unitId, $reference, $quantity){ - return $this->readMultipleRegisters($unitId, $reference, $quantity); - } - - /** - * readMultipleRegistersPacketBuilder - * - * Packet FC 3 builder - read multiple registers - * - * @param int $unitId - * @param int $reference - * @param int $quantity - * @return string - */ - private function readMultipleRegistersPacketBuilder($unitId, $reference, $quantity){ - $dataLen = 0; - // build data section - $buffer1 = ""; - // build body - $buffer2 = ""; - $buffer2 .= iecType::iecBYTE(3); // FC 3 = 3(0x03) - // 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; - } - - /** - * readMultipleRegistersParser - * - * FC 3 response parser - * - * @param string $packet - * @return array - */ - private function readMultipleRegistersParser($packet){ - $data = array(); - // check Response code - $this->responseCode($packet); - // get data - for($i=0;$istatus .= "writeMultipleCoils: START\n"; - // connect - $this->connect(); - // send FC16 - $packet = $this->writeMultipleCoilsPacketBuilder($unitId, $reference, $data); - $this->status .= $this->printPacket($packet); - $this->send($packet); - // receive response - $rpacket = $this->rec(); - $this->status .= $this->printPacket($rpacket); - // parse packet - $this->writeMultipleCoilsParser($rpacket); - // disconnect - $this->disconnect(); - $this->status .= "writeMultipleCoils: DONE\n"; - return true; - } - - /** - * fc15 - * - * Alias to {@link writeMultipleCoils} method - * - * @param int $unitId - * @param int $reference - * @param array $data - * @return bool - */ - function fc15($unitId, $reference, $data){ - return $this->writeMultipleCoils($unitId, $reference, $data); - } - - /** - * writeMultipleCoilsPacketBuilder - * - * Packet builder FC15 - Write multiple coils - * - * @param int $unitId - * @param int $reference - * @param array $data - * @return string - */ - private function writeMultipleCoilsPacketBuilder($unitId, $reference, $data){ - $dataLen = 0; - // build bool stream to the WORD array - $data_word_stream = array(); - $data_word = 0; - $shift = 0; - for($i=0;$i 0)) { - $data_word_stream[] = $data_word; - $shift = 0; - $data_word = 0; - $data_word |= (0x01 && $data[$i]) << $shift; - $shift++; - } - else { - $data_word |= (0x01 && $data[$i]) << $shift; - $shift++; - } - } - $data_word_stream[] = $data_word; - // show binary stream to status string - foreach($data_word_stream as $d){ - $this->status .= sprintf("byte=b%08b\n", $d); - } - // build data section - $buffer1 = ""; - foreach($data_word_stream as $key=>$dataitem) { - $buffer1 .= iecType::iecBYTE($dataitem); // register values x - $dataLen += 1; - } - // build body - $buffer2 = ""; - $buffer2 .= iecType::iecBYTE(15); // FC 15 = 15(0x0f) - $buffer2 .= iecType::iecINT($reference); // refnumber = 12288 - $buffer2 .= iecType::iecINT(count($data)); // bit count - $buffer2 .= iecType::iecBYTE((count($data)+7)/8); // byte count - $dataLen += 6; - // 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; - } - - /** - * writeMultipleCoilsParser - * - * FC15 response parser - * - * @param string $packet - * @return bool - */ - private function writeMultipleCoilsParser($packet){ - $this->responseCode($packet); - return true; - } - - /** - * writeMultipleRegister - * - * Modbus function FC16(0x10) - Write Multiple Register. - * - * This function writes {@link $data} array 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 writeMultipleRegister($unitId, $reference, $data, $dataTypes){ - $this->status .= "writeMultipleRegister: START\n"; - // connect - $this->connect(); - // send FC16 - $packet = $this->writeMultipleRegisterPacketBuilder($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->writeMultipleRegisterParser($rpacket); - // disconnect - $this->disconnect(); - $this->status .= "writeMultipleRegister: DONE\n"; - return true; - } - - - /** - * fc16 - * - * Alias to {@link writeMultipleRegister} method - * - * @param int $unitId - * @param int $reference - * @param array $data - * @param array $dataTypes - * @return bool - */ - function fc16($unitId, $reference, $data, $dataTypes){ - return $this->writeMultipleRegister($unitId, $reference, $data, $dataTypes); - } - - - /** - * writeMultipleRegisterPacketBuilder - * - * Packet builder FC16 - WRITE multiple register - * e.g.: 4dd90000000d0010300000030603e807d00bb8 - * - * @param int $unitId - * @param int $reference - * @param array $data - * @param array $dataTypes - * @return string - */ - private function writeMultipleRegisterPacketBuilder($unitId, $reference, $data, $dataTypes){ - $dataLen = 0; - // build data section - $buffer1 = ""; - foreach($data as $key=>$dataitem) { - if($dataTypes[$key]=="INT"){ - $buffer1 .= iecType::iecINT($dataitem); // register values x - $dataLen += 2; - } - elseif($dataTypes[$key]=="DINT"){ - $buffer1 .= iecType::iecDINT($dataitem, $this->endianness); // register values x - $dataLen += 4; - } - elseif($dataTypes[$key]=="REAL") { - $buffer1 .= iecType::iecREAL($dataitem, $this->endianness); // register values x - $dataLen += 4; - } - else{ - $buffer1 .= iecType::iecINT($dataitem); // register values x - $dataLen += 2; - } - } - // build body - $buffer2 = ""; - $buffer2 .= iecType::iecBYTE(16); // FC 16 = 16(0x10) - $buffer2 .= iecType::iecINT($reference); // refnumber = 12288 - $buffer2 .= iecType::iecINT($dataLen/2); // word count - $buffer2 .= iecType::iecBYTE($dataLen); // byte count - $dataLen += 6; - // 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; - } - - /** - * writeMultipleRegisterParser - * - * FC16 response parser - * - * @param string $packet - * @return bool - */ - private function writeMultipleRegisterParser($packet){ - $this->responseCode($packet); - return true; - } - - /** - * readWriteRegisters - * - * Modbus function FC23(0x17) - Read Write Registers. - * - * This function writes {@link $data} array at reference {@link $referenceWrite} - * position of memory of a Modbus device given by {@link $unitId}. Simultanously, - * it returns {@link $quantity} of Words (2 bytes) from reference {@link $referenceRead}. - * - * - * @param int $unitId usually ID of Modbus device - * @param int $referenceRead Reference in the device memory to read data (e.g. in device WAGO 750-841, memory MW0 starts at address 12288). - * @param int $quantity Amounth of the data to be read from device. - * @param int $referenceWrite Reference in the device memory to write data. - * @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 false|Array Success flag or array of data. - */ - function readWriteRegisters($unitId, $referenceRead, $quantity, $referenceWrite, $data, $dataTypes){ - $this->status .= "readWriteRegisters: START\n"; - // connect - $this->connect(); - // send FC23 - $packet = $this->readWriteRegistersPacketBuilder($unitId, $referenceRead, $quantity, $referenceWrite, $data, $dataTypes); - $this->status .= $this->printPacket($packet); - $this->send($packet); - // receive response - $rpacket = $this->rec(); - $this->status .= $this->printPacket($rpacket); - // parse packet - $receivedData = $this->readWriteRegistersParser($rpacket); - // disconnect - $this->disconnect(); - $this->status .= "writeMultipleRegister: DONE\n"; - // return - return $receivedData; - } - - /** - * fc23 - * - * Alias to {@link readWriteRegisters} method. - * - * @param int $unitId - * @param int $referenceRead - * @param int $quantity - * @param int $referenceWrite - * @param array $data - * @param array $dataTypes - * @return false|Array - */ - function fc23($unitId, $referenceRead, $quantity, $referenceWrite, $data, $dataTypes){ - return $this->readWriteRegisters($unitId, $referenceRead, $quantity, $referenceWrite, $data, $dataTypes); - } - - /** - * readWriteRegistersPacketBuilder - * - * Packet FC23 builder - READ WRITE registers - * - * - * @param int $unitId - * @param int $referenceRead - * @param int $quantity - * @param int $referenceWrite - * @param array $data - * @param array $dataTypes - * @return string - */ - private function readWriteRegistersPacketBuilder($unitId, $referenceRead, $quantity, $referenceWrite, $data, $dataTypes){ - $dataLen = 0; - // build data section - $buffer1 = ""; - foreach($data as $key => $dataitem) { - if($dataTypes[$key]=="INT"){ - $buffer1 .= iecType::iecINT($dataitem); // register values x - $dataLen += 2; - } - elseif($dataTypes[$key]=="DINT"){ - $buffer1 .= iecType::iecDINT($dataitem, $this->endianness); // register values x - $dataLen += 4; - } - elseif($dataTypes[$key]=="REAL") { - $buffer1 .= iecType::iecREAL($dataitem, $this->endianness); // register values x - $dataLen += 4; - } - else{ - $buffer1 .= iecType::iecINT($dataitem); // register values x - $dataLen += 2; - } - } - // build body - $buffer2 = ""; - $buffer2 .= iecType::iecBYTE(23); // FC 23 = 23(0x17) - // build body - read section - $buffer2 .= iecType::iecINT($referenceRead); // refnumber = 12288 - $buffer2 .= iecType::iecINT($quantity); // quantity - // build body - write section - $buffer2 .= iecType::iecINT($referenceWrite); // refnumber = 12288 - $buffer2 .= iecType::iecINT($dataLen/2); // word count - $buffer2 .= iecType::iecBYTE($dataLen); // byte count - $dataLen += 10; - // 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; - } - - - /** - * readWriteRegistersParser - * - * FC23 response parser - * - * @param string $packet - * @return array - */ - private function readWriteRegistersParser($packet){ - $data = array(); - // if not exception - if(!$this->responseCode($packet)) - return false; - // get data - for($i=0;$i> 4) & 0x0F); - $l = dechex($value & 0x0F); - return "$h$l"; - } - - /** - * printPacket - * - * Print a packet in the hex form - * - * @param string $packet - * @return string - */ - private function printPacket($packet){ - $str = ""; - $str .= "Packet: "; - for($i=0;$ibyte2hex(ord($packet[$i])); - } - $str .= "\n"; - return $str; - } -} +socket_protocol = $protocol; + $this->host = $host; + } + + /** + * __toString + * + * Magic method + */ + function __toString() { + return "
" . $this->status . "
"; + } + + /** + * connect + * + * Connect the socket + * + * @return bool + */ + private function connect(){ + // Create a protocol specific socket + if ($this->socket_protocol == "TCP"){ + // TCP socket + $this->sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); + } elseif ($this->socket_protocol == "UDP"){ + // UDP socket + $this->sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); + } else { + throw new Exception("Unknown socket protocol, should be 'TCP' or 'UDP'"); + } + // Bind the client socket to a specific local port + if (strlen($this->client)>0){ + $result = socket_bind($this->sock, $this->client, $this->client_port); + if ($result === false) { + throw new Exception("socket_bind() failed.
Reason: ($result)". + socket_strerror(socket_last_error($this->sock))); + } else { + $this->status .= "Bound\n"; + } + } + // Connect the socket + $result = @socket_connect($this->sock, $this->host, $this->port); + if ($result === false) { + throw new Exception("socket_connect() failed.
Reason: ($result)". + socket_strerror(socket_last_error($this->sock))); + } else { + $this->status .= "Connected\n"; + return true; + } + } + + /** + * disconnect + * + * Disconnect the socket + */ + private function disconnect(){ + socket_close($this->sock); + $this->status .= "Disconnected\n"; + } + + /** + * send + * + * Send the packet via Modbus + * + * @param string $packet + */ + private function send($packet){ + socket_write($this->sock, $packet, strlen($packet)); + $this->status .= "Send\n"; + } + + /** + * rec + * + * Receive data from the socket + * + * @return bool + */ + private function rec(){ + socket_set_nonblock($this->sock); + $readsocks[] = $this->sock; + $writesocks = NULL; + $exceptsocks = NULL; + $rec = ""; + $lastAccess = time(); + while (socket_select($readsocks, + $writesocks, + $exceptsocks, + 0, + 300000) !== FALSE) { + $this->status .= "Wait data ... \n"; + if (in_array($this->sock, $readsocks)) { + while (@socket_recv($this->sock, $rec, 2000, 0)) { + $this->status .= "Data received\n"; + return $rec; + } + $lastAccess = time(); + } else { + if (time()-$lastAccess >= $this->timeout_sec) { + throw new Exception( "Watchdog time expired [ " . + $this->timeout_sec . " sec]!!! Connection to " . + $this->host . " is not established."); + } + } + $readsocks[] = $this->sock; + } + } + + /** + * responseCode + * + * Check the Modbus response code + * + * @param string $packet + * @return bool + */ + private function responseCode($packet){ + 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; + } + } + + /** + * readCoils + * + * Modbus function FC 1(0x01) - Read Coils + * + * Reads {@link $quantity} of Coils (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 readCoils($unitId, $reference, $quantity){ + $this->status .= "readCoils: START\n"; + // connect + $this->connect(); + // send FC 1 + $packet = $this->readCoilsPacketBuilder($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->readCoilsParser($rpacket, $quantity); + // disconnect + $this->disconnect(); + $this->status .= "readCoils: DONE\n"; + // return + return $receivedData; + } + + /** + * fc1 + * + * Alias to {@link readCoils} method + * + * @param type $unitId + * @param type $reference + * @param type $quantity + * @return type + */ + function fc1($unitId, $reference, $quantity){ + return $this->readCoils($unitId, $reference, $quantity); + } + + /** + * readCoilsPacketBuilder + * + * FC1 packet builder - read coils + * + * @param type $unitId + * @param type $reference + * @param type $quantity + * @return type + */ + private function readCoilsPacketBuilder($unitId, $reference, $quantity){ + $dataLen = 0; + // build data section + $buffer1 = ""; + // build body + $buffer2 = ""; + $buffer2 .= iecType::iecBYTE(1); // FC 1 = 1(0x01) + // 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; + } + + /** + * readCoilsParser + * + * FC 1 response parser + * + * @param type $packet + * @param type $quantity + * @return type + */ + private function readCoilsParser($packet, $quantity){ + $data = array(); + // check Response code + $this->responseCode($packet); + // get data from stream + for($i=0;$i> $i) & 0x01; + // build boolean array + if($v == 0){ + $data_bolean_array[] = FALSE; + } else { + $data_bolean_array[] = TRUE; + } + $di++; + } + } + 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 + * + * Modbus function FC 3(0x03) - Read Multiple 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 (e.g. in device WAGO 750-841, memory MW0 starts at address 12288). + * @param int $quantity Amounth of the data to be read from device. + * @return false|Array Success flag or array of received data. + */ + function readMultipleRegisters($unitId, $reference, $quantity){ + $this->status .= "readMultipleRegisters: START\n"; + // connect + $this->connect(); + // send FC 3 + $packet = $this->readMultipleRegistersPacketBuilder($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->readMultipleRegistersParser($rpacket); + // disconnect + $this->disconnect(); + $this->status .= "readMultipleRegisters: DONE\n"; + // return + return $receivedData; + } + + /** + * fc3 + * + * Alias to {@link readMultipleRegisters} method. + * + * @param int $unitId + * @param int $reference + * @param int $quantity + * @return false|Array + */ + function fc3($unitId, $reference, $quantity){ + return $this->readMultipleRegisters($unitId, $reference, $quantity); + } + + /** + * readMultipleRegistersPacketBuilder + * + * Packet FC 3 builder - read multiple registers + * + * @param int $unitId + * @param int $reference + * @param int $quantity + * @return string + */ + private function readMultipleRegistersPacketBuilder($unitId, $reference, $quantity){ + $dataLen = 0; + // build data section + $buffer1 = ""; + // build body + $buffer2 = ""; + $buffer2 .= iecType::iecBYTE(3); // FC 3 = 3(0x03) + // 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; + } + + /** + * readMultipleRegistersParser + * + * FC 3 response parser + * + * @param string $packet + * @return array + */ + private function readMultipleRegistersParser($packet){ + $data = array(); + // check Response code + $this->responseCode($packet); + // get data + for($i=0;$istatus .= "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 + * + * Modbus function FC15(0x0F) - Write Multiple Coils + * + * This function writes {@link $data} array at {@link $reference} position of + * memory of a Modbus device given by {@link $unitId}. + * + * @param type $unitId + * @param type $reference + * @param type $data + * @return type + */ + function writeMultipleCoils($unitId, $reference, $data){ + $this->status .= "writeMultipleCoils: START\n"; + // connect + $this->connect(); + // send FC15 + $packet = $this->writeMultipleCoilsPacketBuilder($unitId, $reference, $data); + $this->status .= $this->printPacket($packet); + $this->send($packet); + // receive response + $rpacket = $this->rec(); + $this->status .= $this->printPacket($rpacket); + // parse packet + $this->writeMultipleCoilsParser($rpacket); + // disconnect + $this->disconnect(); + $this->status .= "writeMultipleCoils: DONE\n"; + return true; + } + + /** + * fc15 + * + * Alias to {@link writeMultipleCoils} method + * + * @param int $unitId + * @param int $reference + * @param array $data + * @return bool + */ + function fc15($unitId, $reference, $data){ + return $this->writeMultipleCoils($unitId, $reference, $data); + } + + /** + * writeMultipleCoilsPacketBuilder + * + * Packet builder FC15 - Write multiple coils + * + * @param int $unitId + * @param int $reference + * @param array $data + * @return string + */ + private function writeMultipleCoilsPacketBuilder($unitId, $reference, $data){ + $dataLen = 0; + // build bool stream to the WORD array + $data_word_stream = array(); + $data_word = 0; + $shift = 0; + for($i=0;$i 0)) { + $data_word_stream[] = $data_word; + $shift = 0; + $data_word = 0; + $data_word |= (0x01 && $data[$i]) << $shift; + $shift++; + } + else { + $data_word |= (0x01 && $data[$i]) << $shift; + $shift++; + } + } + $data_word_stream[] = $data_word; + // show binary stream to status string + foreach($data_word_stream as $d){ + $this->status .= sprintf("byte=b%08b\n", $d); + } + // build data section + $buffer1 = ""; + foreach($data_word_stream as $key=>$dataitem) { + $buffer1 .= iecType::iecBYTE($dataitem); // register values x + $dataLen += 1; + } + // build body + $buffer2 = ""; + $buffer2 .= iecType::iecBYTE(15); // FC 15 = 15(0x0f) + $buffer2 .= iecType::iecINT($reference); // refnumber = 12288 + $buffer2 .= iecType::iecINT(count($data)); // bit count + $buffer2 .= iecType::iecBYTE((count($data)+7)/8); // byte count + $dataLen += 6; + // 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; + } + + /** + * writeMultipleCoilsParser + * + * FC15 response parser + * + * @param string $packet + * @return bool + */ + private function writeMultipleCoilsParser($packet){ + $this->responseCode($packet); + return true; + } + + /** + * writeMultipleRegister + * + * Modbus function FC16(0x10) - Write Multiple Register. + * + * This function writes {@link $data} array 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 writeMultipleRegister($unitId, $reference, $data, $dataTypes){ + $this->status .= "writeMultipleRegister: START\n"; + // connect + $this->connect(); + // send FC16 + $packet = $this->writeMultipleRegisterPacketBuilder($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->writeMultipleRegisterParser($rpacket); + // disconnect + $this->disconnect(); + $this->status .= "writeMultipleRegister: DONE\n"; + return true; + } + + + /** + * fc16 + * + * Alias to {@link writeMultipleRegister} method + * + * @param int $unitId + * @param int $reference + * @param array $data + * @param array $dataTypes + * @return bool + */ + function fc16($unitId, $reference, $data, $dataTypes){ + return $this->writeMultipleRegister($unitId, $reference, $data, $dataTypes); + } + + + /** + * writeMultipleRegisterPacketBuilder + * + * Packet builder FC16 - WRITE multiple register + * e.g.: 4dd90000000d0010300000030603e807d00bb8 + * + * @param int $unitId + * @param int $reference + * @param array $data + * @param array $dataTypes + * @return string + */ + private function writeMultipleRegisterPacketBuilder($unitId, $reference, $data, $dataTypes){ + $dataLen = 0; + // build data section + $buffer1 = ""; + foreach($data as $key=>$dataitem) { + if($dataTypes[$key]=="INT"){ + $buffer1 .= iecType::iecINT($dataitem); // register values x + $dataLen += 2; + } + elseif($dataTypes[$key]=="DINT"){ + $buffer1 .= iecType::iecDINT($dataitem, $this->endianness); // register values x + $dataLen += 4; + } + elseif($dataTypes[$key]=="REAL") { + $buffer1 .= iecType::iecREAL($dataitem, $this->endianness); // register values x + $dataLen += 4; + } + else{ + $buffer1 .= iecType::iecINT($dataitem); // register values x + $dataLen += 2; + } + } + // build body + $buffer2 = ""; + $buffer2 .= iecType::iecBYTE(16); // FC 16 = 16(0x10) + $buffer2 .= iecType::iecINT($reference); // refnumber = 12288 + $buffer2 .= iecType::iecINT($dataLen/2); // word count + $buffer2 .= iecType::iecBYTE($dataLen); // byte count + $dataLen += 6; + // 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; + } + + /** + * writeMultipleRegisterParser + * + * FC16 response parser + * + * @param string $packet + * @return bool + */ + private function writeMultipleRegisterParser($packet){ + $this->responseCode($packet); + return true; + } + + /** + * readWriteRegisters + * + * Modbus function FC23(0x17) - Read Write Registers. + * + * This function writes {@link $data} array at reference {@link $referenceWrite} + * position of memory of a Modbus device given by {@link $unitId}. Simultanously, + * it returns {@link $quantity} of Words (2 bytes) from reference {@link $referenceRead}. + * + * + * @param int $unitId usually ID of Modbus device + * @param int $referenceRead Reference in the device memory to read data (e.g. in device WAGO 750-841, memory MW0 starts at address 12288). + * @param int $quantity Amounth of the data to be read from device. + * @param int $referenceWrite Reference in the device memory to write data. + * @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 false|Array Success flag or array of data. + */ + function readWriteRegisters($unitId, $referenceRead, $quantity, $referenceWrite, $data, $dataTypes){ + $this->status .= "readWriteRegisters: START\n"; + // connect + $this->connect(); + // send FC23 + $packet = $this->readWriteRegistersPacketBuilder($unitId, $referenceRead, $quantity, $referenceWrite, $data, $dataTypes); + $this->status .= $this->printPacket($packet); + $this->send($packet); + // receive response + $rpacket = $this->rec(); + $this->status .= $this->printPacket($rpacket); + // parse packet + $receivedData = $this->readWriteRegistersParser($rpacket); + // disconnect + $this->disconnect(); + $this->status .= "writeMultipleRegister: DONE\n"; + // return + return $receivedData; + } + + /** + * fc23 + * + * Alias to {@link readWriteRegisters} method. + * + * @param int $unitId + * @param int $referenceRead + * @param int $quantity + * @param int $referenceWrite + * @param array $data + * @param array $dataTypes + * @return false|Array + */ + function fc23($unitId, $referenceRead, $quantity, $referenceWrite, $data, $dataTypes){ + return $this->readWriteRegisters($unitId, $referenceRead, $quantity, $referenceWrite, $data, $dataTypes); + } + + /** + * readWriteRegistersPacketBuilder + * + * Packet FC23 builder - READ WRITE registers + * + * + * @param int $unitId + * @param int $referenceRead + * @param int $quantity + * @param int $referenceWrite + * @param array $data + * @param array $dataTypes + * @return string + */ + private function readWriteRegistersPacketBuilder($unitId, $referenceRead, $quantity, $referenceWrite, $data, $dataTypes){ + $dataLen = 0; + // build data section + $buffer1 = ""; + foreach($data as $key => $dataitem) { + if($dataTypes[$key]=="INT"){ + $buffer1 .= iecType::iecINT($dataitem); // register values x + $dataLen += 2; + } + elseif($dataTypes[$key]=="DINT"){ + $buffer1 .= iecType::iecDINT($dataitem, $this->endianness); // register values x + $dataLen += 4; + } + elseif($dataTypes[$key]=="REAL") { + $buffer1 .= iecType::iecREAL($dataitem, $this->endianness); // register values x + $dataLen += 4; + } + else{ + $buffer1 .= iecType::iecINT($dataitem); // register values x + $dataLen += 2; + } + } + // build body + $buffer2 = ""; + $buffer2 .= iecType::iecBYTE(23); // FC 23 = 23(0x17) + // build body - read section + $buffer2 .= iecType::iecINT($referenceRead); // refnumber = 12288 + $buffer2 .= iecType::iecINT($quantity); // quantity + // build body - write section + $buffer2 .= iecType::iecINT($referenceWrite); // refnumber = 12288 + $buffer2 .= iecType::iecINT($dataLen/2); // word count + $buffer2 .= iecType::iecBYTE($dataLen); // byte count + $dataLen += 10; + // 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; + } + + + /** + * readWriteRegistersParser + * + * FC23 response parser + * + * @param string $packet + * @return array + */ + private function readWriteRegistersParser($packet){ + $data = array(); + // if not exception + if(!$this->responseCode($packet)) + return false; + // get data + for($i=0;$i> 4) & 0x0F); + $l = dechex($value & 0x0F); + return "$h$l"; + } + + /** + * printPacket + * + * Print a packet in the hex form + * + * @param string $packet + * @return string + */ + private function printPacket($packet){ + $str = ""; + $str .= "Packet: "; + for($i=0;$ibyte2hex(ord($packet[$i])); + } + $str .= "\n"; + return $str; + } +} 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 @@ readInputDiscretes(0, 0, 2); +} +catch (Exception $e) { + // Print error information if any + echo $modbus; + echo $e; + exit; +} + +// Print status information +echo "
Status:
" . $modbus; + +// Print read data +echo "
Data:
"; +var_dump($recData); +echo "
"; \ No newline at end of file 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 diff --git a/tests/Codesys/DEFAULT.DFR b/tests/Codesys/DEFAULT.DFR new file mode 100644 index 0000000..656e9fe Binary files /dev/null and b/tests/Codesys/DEFAULT.DFR differ 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.SDB b/tests/Codesys/test.SDB new file mode 100644 index 0000000..7a1a08b Binary files /dev/null and b/tests/Codesys/test.SDB differ diff --git a/tests/Codesys/test.SYM b/tests/Codesys/test.SYM new file mode 100644 index 0000000..7ed349a --- /dev/null +++ b/tests/Codesys/test.SYM @@ -0,0 +1,4 @@ +;Version=2 +;ProjectId=114942 +;Checksum=0 +;Filesize=0 diff --git a/tests/Codesys/test.pro b/tests/Codesys/test.pro new file mode 100644 index 0000000..6904c0c Binary files /dev/null and b/tests/Codesys/test.pro differ diff --git a/tests/Codesys/test00002ed2r.ci b/tests/Codesys/test00002ed2r.ci new file mode 100644 index 0000000..062ad60 Binary files /dev/null and b/tests/Codesys/test00002ed2r.ci differ diff --git a/tests/Codesys/test00002ed2r.ri b/tests/Codesys/test00002ed2r.ri new file mode 100644 index 0000000..453fbbc Binary files /dev/null and b/tests/Codesys/test00002ed2r.ri differ diff --git a/tests/IecType/output/test.iecByte.php.html b/tests/IecType/output/test.iecByte.php.html new file mode 100644 index 0000000..dc6e8a7 --- /dev/null +++ b/tests/IecType/output/test.iecByte.php.html @@ -0,0 +1 @@ +125
98
0
0
0
0
0
0
0
0
0
0
255
255
255
255
158
88
97
168
\ No newline at end of file diff --git a/tests/IecType/output/test.iecDInt.php.html b/tests/IecType/output/test.iecDInt.php.html new file mode 100644 index 0000000..1abf31b --- /dev/null +++ b/tests/IecType/output/test.iecDInt.php.html @@ -0,0 +1 @@ +Endianing off
0 --> Packet: 0000_0000_
1 --> Packet: 0001_0000_
-1 --> Packet: ffff_ffff_
2147483647 --> Packet: ffff_7fff_
-2147483648 --> Packet: 0000_8000_
Endianing on
0 --> Packet: 0000_0000_
1 --> Packet: 0000_0001_
-1 --> Packet: ffff_ffff_
2147483647 --> Packet: 7fff_ffff_
-2147483648 --> Packet: 8000_0000_
\ No newline at end of file diff --git a/tests/IecType/output/test.iecInt.php.html b/tests/IecType/output/test.iecInt.php.html new file mode 100644 index 0000000..583ad9b --- /dev/null +++ b/tests/IecType/output/test.iecInt.php.html @@ -0,0 +1 @@ +Endianing off
0 --> Packet: 0000_
1 --> Packet: 0001_
-1 --> Packet: ffff_
32767 --> Packet: 7fff_
-32768 --> Packet: 8000_
Endianing on
0 --> Packet: 0000_
1 --> Packet: 0001_
-1 --> Packet: ffff_
32767 --> Packet: 7fff_
-32768 --> Packet: 8000_
\ No newline at end of file diff --git a/tests/IecType/output/test.iecReal.php.html b/tests/IecType/output/test.iecReal.php.html new file mode 100644 index 0000000..a195b00 --- /dev/null +++ b/tests/IecType/output/test.iecReal.php.html @@ -0,0 +1,12 @@ +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/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 @@ $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 ); diff --git a/tests/ModbusMaster/output/test.tcp.fc16fc3.php.html b/tests/ModbusMaster/output/test.tcp.fc16fc3.php.html new file mode 100644 index 0000000..00dd046 --- /dev/null +++ b/tests/ModbusMaster/output/test.tcp.fc16fc3.php.html @@ -0,0 +1,72 @@ +Array +( + [0] => 0 + [1] => 0 + [2] => 0 + [3] => 1 + [4] => 0 + [5] => 1 + [6] => 0 + [7] => 255 + [8] => 0 + [9] => 255 +) +Array +( + [0] => 0 + [1] => 0 + [2] => 0 + [3] => 1 + [4] => 255 + [5] => 255 + [6] => 127 + [7] => 255 + [8] => 128 + [9] => 0 +) +Array +( + [0] => 0 + [1] => 0 + [2] => 0 + [3] => 0 + [4] => 0 + [5] => 1 + [6] => 0 + [7] => 0 + [8] => 255 + [9] => 255 + [10] => 255 + [11] => 255 + [12] => 255 + [13] => 255 + [14] => 127 + [15] => 255 + [16] => 0 + [17] => 0 + [18] => 128 + [19] => 0 +) +Array +( + [0] => 0 + [1] => 0 + [2] => 0 + [3] => 0 + [4] => 0 + [5] => 0 + [6] => 63 + [7] => 128 + [8] => 0 + [9] => 0 + [10] => 192 + [11] => 0 + [12] => 170 + [13] => 171 + [14] => 62 + [15] => 170 + [16] => 0 + [17] => 0 + [18] => 65 + [19] => 200 +) diff --git a/tests/ModbusMaster/output/test.tcp.fc26.php.html b/tests/ModbusMaster/output/test.tcp.fc26.php.html new file mode 100644 index 0000000..7991aa8 --- /dev/null +++ b/tests/ModbusMaster/output/test.tcp.fc26.php.html @@ -0,0 +1 @@ +writeMultipleRegister (FC26): DONE \ No newline at end of file diff --git a/tests/ModbusMaster/output/test.tcp.socket_protocol_mismatch.php.html b/tests/ModbusMaster/output/test.tcp.socket_protocol_mismatch.php.html new file mode 100644 index 0000000..b25cfe4 --- /dev/null +++ b/tests/ModbusMaster/output/test.tcp.socket_protocol_mismatch.php.html @@ -0,0 +1 @@ +Caught exception: Unknown socket protocol, should be 'TCP' or 'UDP' diff --git a/tests/ModbusMaster/output/test.udp.fc16fc3.php.html b/tests/ModbusMaster/output/test.udp.fc16fc3.php.html new file mode 100644 index 0000000..00dd046 --- /dev/null +++ b/tests/ModbusMaster/output/test.udp.fc16fc3.php.html @@ -0,0 +1,72 @@ +Array +( + [0] => 0 + [1] => 0 + [2] => 0 + [3] => 1 + [4] => 0 + [5] => 1 + [6] => 0 + [7] => 255 + [8] => 0 + [9] => 255 +) +Array +( + [0] => 0 + [1] => 0 + [2] => 0 + [3] => 1 + [4] => 255 + [5] => 255 + [6] => 127 + [7] => 255 + [8] => 128 + [9] => 0 +) +Array +( + [0] => 0 + [1] => 0 + [2] => 0 + [3] => 0 + [4] => 0 + [5] => 1 + [6] => 0 + [7] => 0 + [8] => 255 + [9] => 255 + [10] => 255 + [11] => 255 + [12] => 255 + [13] => 255 + [14] => 127 + [15] => 255 + [16] => 0 + [17] => 0 + [18] => 128 + [19] => 0 +) +Array +( + [0] => 0 + [1] => 0 + [2] => 0 + [3] => 0 + [4] => 0 + [5] => 0 + [6] => 63 + [7] => 128 + [8] => 0 + [9] => 0 + [10] => 192 + [11] => 0 + [12] => 170 + [13] => 171 + [14] => 62 + [15] => 170 + [16] => 0 + [17] => 0 + [18] => 65 + [19] => 200 +) diff --git a/tests/ModbusMaster/output/test.udp.fc26.php.html b/tests/ModbusMaster/output/test.udp.fc26.php.html new file mode 100644 index 0000000..7991aa8 --- /dev/null +++ b/tests/ModbusMaster/output/test.udp.fc26.php.html @@ -0,0 +1 @@ +writeMultipleRegister (FC26): DONE \ No newline at end of file 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 @@ $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!"; \ No newline at end of file +echo "Should never reach this line!"; \ No newline at end of file diff --git a/tests/ModbusMasterTcp/output/test.fc16fc3.php.html b/tests/ModbusMasterTcp/output/test.fc16fc3.php.html new file mode 100644 index 0000000..00dd046 --- /dev/null +++ b/tests/ModbusMasterTcp/output/test.fc16fc3.php.html @@ -0,0 +1,72 @@ +Array +( + [0] => 0 + [1] => 0 + [2] => 0 + [3] => 1 + [4] => 0 + [5] => 1 + [6] => 0 + [7] => 255 + [8] => 0 + [9] => 255 +) +Array +( + [0] => 0 + [1] => 0 + [2] => 0 + [3] => 1 + [4] => 255 + [5] => 255 + [6] => 127 + [7] => 255 + [8] => 128 + [9] => 0 +) +Array +( + [0] => 0 + [1] => 0 + [2] => 0 + [3] => 0 + [4] => 0 + [5] => 1 + [6] => 0 + [7] => 0 + [8] => 255 + [9] => 255 + [10] => 255 + [11] => 255 + [12] => 255 + [13] => 255 + [14] => 127 + [15] => 255 + [16] => 0 + [17] => 0 + [18] => 128 + [19] => 0 +) +Array +( + [0] => 0 + [1] => 0 + [2] => 0 + [3] => 0 + [4] => 0 + [5] => 0 + [6] => 63 + [7] => 128 + [8] => 0 + [9] => 0 + [10] => 192 + [11] => 0 + [12] => 170 + [13] => 171 + [14] => 62 + [15] => 170 + [16] => 0 + [17] => 0 + [18] => 65 + [19] => 200 +) diff --git a/tests/ModbusMasterTcp/output/test.fc26.php.html b/tests/ModbusMasterTcp/output/test.fc26.php.html new file mode 100644 index 0000000..7991aa8 --- /dev/null +++ b/tests/ModbusMasterTcp/output/test.fc26.php.html @@ -0,0 +1 @@ +writeMultipleRegister (FC26): DONE \ No newline at end of file diff --git a/tests/ModbusMasterUdp/output/test.fc15fc1.php.html b/tests/ModbusMasterUdp/output/test.fc15fc1.php.html new file mode 100644 index 0000000..55a3de0 --- /dev/null +++ b/tests/ModbusMasterUdp/output/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/output/test.fc16fc3.php.html b/tests/ModbusMasterUdp/output/test.fc16fc3.php.html new file mode 100644 index 0000000..00dd046 --- /dev/null +++ b/tests/ModbusMasterUdp/output/test.fc16fc3.php.html @@ -0,0 +1,72 @@ +Array +( + [0] => 0 + [1] => 0 + [2] => 0 + [3] => 1 + [4] => 0 + [5] => 1 + [6] => 0 + [7] => 255 + [8] => 0 + [9] => 255 +) +Array +( + [0] => 0 + [1] => 0 + [2] => 0 + [3] => 1 + [4] => 255 + [5] => 255 + [6] => 127 + [7] => 255 + [8] => 128 + [9] => 0 +) +Array +( + [0] => 0 + [1] => 0 + [2] => 0 + [3] => 0 + [4] => 0 + [5] => 1 + [6] => 0 + [7] => 0 + [8] => 255 + [9] => 255 + [10] => 255 + [11] => 255 + [12] => 255 + [13] => 255 + [14] => 127 + [15] => 255 + [16] => 0 + [17] => 0 + [18] => 128 + [19] => 0 +) +Array +( + [0] => 0 + [1] => 0 + [2] => 0 + [3] => 0 + [4] => 0 + [5] => 0 + [6] => 63 + [7] => 128 + [8] => 0 + [9] => 0 + [10] => 192 + [11] => 0 + [12] => 170 + [13] => 171 + [14] => 62 + [15] => 170 + [16] => 0 + [17] => 0 + [18] => 65 + [19] => 200 +) diff --git a/tests/ModbusMasterUdp/output/test.fc16fc3bind.php.html b/tests/ModbusMasterUdp/output/test.fc16fc3bind.php.html new file mode 100644 index 0000000..00dd046 --- /dev/null +++ b/tests/ModbusMasterUdp/output/test.fc16fc3bind.php.html @@ -0,0 +1,72 @@ +Array +( + [0] => 0 + [1] => 0 + [2] => 0 + [3] => 1 + [4] => 0 + [5] => 1 + [6] => 0 + [7] => 255 + [8] => 0 + [9] => 255 +) +Array +( + [0] => 0 + [1] => 0 + [2] => 0 + [3] => 1 + [4] => 255 + [5] => 255 + [6] => 127 + [7] => 255 + [8] => 128 + [9] => 0 +) +Array +( + [0] => 0 + [1] => 0 + [2] => 0 + [3] => 0 + [4] => 0 + [5] => 1 + [6] => 0 + [7] => 0 + [8] => 255 + [9] => 255 + [10] => 255 + [11] => 255 + [12] => 255 + [13] => 255 + [14] => 127 + [15] => 255 + [16] => 0 + [17] => 0 + [18] => 128 + [19] => 0 +) +Array +( + [0] => 0 + [1] => 0 + [2] => 0 + [3] => 0 + [4] => 0 + [5] => 0 + [6] => 63 + [7] => 128 + [8] => 0 + [9] => 0 + [10] => 192 + [11] => 0 + [12] => 170 + [13] => 171 + [14] => 62 + [15] => 170 + [16] => 0 + [17] => 0 + [18] => 65 + [19] => 200 +) diff --git a/tests/ModbusMasterUdp/output/test.fc2.php.html b/tests/ModbusMasterUdp/output/test.fc2.php.html new file mode 100644 index 0000000..5baae72 --- /dev/null +++ b/tests/ModbusMasterUdp/output/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/output/test.fc26.php.html b/tests/ModbusMasterUdp/output/test.fc26.php.html new file mode 100644 index 0000000..7991aa8 --- /dev/null +++ b/tests/ModbusMasterUdp/output/test.fc26.php.html @@ -0,0 +1 @@ +writeMultipleRegister (FC26): DONE \ No newline at end of file diff --git a/tests/ModbusMasterUdp/output/test.fc26bind.php.html b/tests/ModbusMasterUdp/output/test.fc26bind.php.html new file mode 100644 index 0000000..7991aa8 --- /dev/null +++ b/tests/ModbusMasterUdp/output/test.fc26bind.php.html @@ -0,0 +1 @@ +writeMultipleRegister (FC26): DONE \ No newline at end of file diff --git a/tests/ModbusMasterUdp/output/test.fc6fc3.php.html b/tests/ModbusMasterUdp/output/test.fc6fc3.php.html new file mode 100644 index 0000000..6102dcd --- /dev/null +++ b/tests/ModbusMasterUdp/output/test.fc6fc3.php.html @@ -0,0 +1,5 @@ +Array +( + [0] => 207 + [1] => 199 +) 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/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 @@ Array [10] => 192 [11] => 0 [12] => 170 - [13] => 170 + [13] => 171 [14] => 62 [15] => 170 [16] => 0 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/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.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 @@ $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); \ No newline at end of file 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 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); diff --git a/tests/PhpType/output/test.bytes2mixed.php.html b/tests/PhpType/output/test.bytes2mixed.php.html new file mode 100644 index 0000000..952bc9d --- /dev/null +++ b/tests/PhpType/output/test.bytes2mixed.php.html @@ -0,0 +1 @@ +32098
0
0
-1
-25000
25000
\ No newline at end of file diff --git a/tests/PhpType/output/test.bytes2real.php.html b/tests/PhpType/output/test.bytes2real.php.html new file mode 100644 index 0000000..7d44edb --- /dev/null +++ b/tests/PhpType/output/test.bytes2real.php.html @@ -0,0 +1 @@ +1000
2000
1.25
\ No newline at end of file diff --git a/tests/PhpType/output/test.bytes2signedint.php.html b/tests/PhpType/output/test.bytes2signedint.php.html new file mode 100644 index 0000000..a2b10ea --- /dev/null +++ b/tests/PhpType/output/test.bytes2signedint.php.html @@ -0,0 +1 @@ +-1
0
1
-2147483648
2147483647
diff --git a/tests/PhpType/output/test.bytes2string.php.html b/tests/PhpType/output/test.bytes2string.php.html new file mode 100644 index 0000000..31bbf09 --- /dev/null +++ b/tests/PhpType/output/test.bytes2string.php.html @@ -0,0 +1 @@ +eHll oowlr!da
Hello world!
\ No newline at end of file diff --git a/tests/PhpType/output/test.bytes2unsignedint.php.html b/tests/PhpType/output/test.bytes2unsignedint.php.html new file mode 100644 index 0000000..29be8ee --- /dev/null +++ b/tests/PhpType/output/test.bytes2unsignedint.php.html @@ -0,0 +1,6 @@ +float(4294967295) +
int(0) +
int(1) +
float(2147483648) +
int(2147483647) +
diff --git a/tests/PhpType/output/test.strangearray.size.php.html b/tests/PhpType/output/test.strangearray.size.php.html new file mode 100644 index 0000000..d0e619d --- /dev/null +++ b/tests/PhpType/output/test.strangearray.size.php.html @@ -0,0 +1 @@ +Exception 'Data are not in array 2 or 4 bytes'
25602
Exception 'Data are not in array 2 or 4 bytes'
25602
Exception 'Data are not in array 2 or 4 bytes'
\ No newline at end of file diff --git a/tests/PhpType/output/test.strangearray.textarray.php.html b/tests/PhpType/output/test.strangearray.textarray.php.html new file mode 100644 index 0000000..734d099 --- /dev/null +++ b/tests/PhpType/output/test.strangearray.textarray.php.html @@ -0,0 +1 @@ +Exception 'Data are not numeric' \ No newline at end of file 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 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