COMGENIUS TLM
  SoftPLC    Font size:      

Examples

All examples below assume the following string table:

1    "Rack no: %3o has %2d modules.\r\n"   example 1
2    "\x02\x03%.2C%.2C%#R"                 example 2, Modbus slave 2, function 3
3    "AK HM %.14s %.3d"                    example 3
4    "\x02\x03\xfa%.250C%#R"               example 4, Modbus response
5    "\x02\x83%c%#R"                       example 5, Modbus exception


Example 1. COMPRINT of Text with Integers

Format: 1

Two parameters: integer, integer

Sample output:

 "Rack no:   5 has  2 modules."
Note
Look at our example string table's format string number 1. The trailing carriage return and line feed are not shown in the Sample output because they are not visible characters. There are two conversion specifications and therefore two Params are required, in this case both integers. The first conversion specification is %3o and means print out a field 3 characters wide, pad on the front end with spaces if needed and do it in octal. The second conversion specification is %2d and means print out a field 2 characters wide at least, pad on the front end with spaces if needed and do it in decimal.


Example 2. COMPRINT of Modbus RTU Query

In this example binary is printed rather than ASCII, so our format string has hex escapes. The desired Modbus RTU query is Read Holding Registers, Modbus function number 3 and intended for slave 2:

+-------+-------+-------+-------+-------+-------+-------+-------+
|  02   |  03   | Ref Hi| Ref Lo| Num Hi| Num Lo| CRC Lo| CRC Hi|
+-------+-------+-------+-------+-------+-------+-------+-------+
  slave   func  |<----2 bytes-->|<----2 bytes-->|<----2 bytes-->|

The 2 Ref bytes are the datatable address starting at 0 (which corresponds to register 40001), in most significant byte first format (big endian). The 2 Num bytes are the count of registers to read, in big endian format, with a maximum of 125. The 2 CRC bytes are the CRC-16 calculated by preloading with 0xFFFF, not 0, and are output in little endian format.


Format: 2

Two parameters: integer, integer

Sample output: see above where the 8 byte query is shown.

Note
Look at our example string table's format string number 2. The first byte is 0x02 and is the slave id we arbitrarily chose for this example. It could be any slave id and it could also have been created as a result of a %c (single byte) conversion specification. The next byte is hard coded as 0x03, the Modbus function. The next two bytes are a big endian 16 bit binary integer containing the memory address, so %.2C is the conversion specification. The next two bytes are a big endian 16 bit binary number containing the desired register count, so %.2C is the conversion specification. The datatable value for this, Param 2, cannot exceed 125 according to the Modbus specification. The last two bytes are the little endian CRC-16 using 0xFFFF as the CRC preload. To get the 0xFFFF preload, the alternate form specifier # is used in the conversion specification %#R.

There is yet a simpler format string possible for this example, and that would be to hard code the Ref and Num words using 4 hex escapes, something that makes more sense if they do not need to be modifiable at runtime. In such a case no Params would be required, since the %#R conversion specification uses no Params itself.


Example 3. COMSCAN of Text with Integers

In this example a string is expected on the Port in ASCII. The expected string looks like:

AK HM <variableWidthNonWhitespace> NNNCRLF

The AK HM are fixed. The <variableWidthNonWhitespace> is a field that will not have whitespace in it. This field's width will vary from 1 to 14 characters. The NNN is a decimal number like "123" and it is at most 3 characters wide. The CRLF are two characters: \r and \n respectively. They are whitespace according to our earlier definition.

Format: 3

Two parameters: STRING element, integer

Note
Look at our example string table's format string number 3. The AK HM are fixed and must be matched explicitly. The first conversion specification is %.14s, meaning match and copy a non-whitespace string segment of up to 14 characters into the corresponding Param 1, which must be a STRING element. The copying will end at the space character preceding the NNN. The next conversion specification is %.3d, which means expect a decimal integer field (possibly with a leading '-' character) up to 3 digits wide. The end of the NNN field will be marked by whitespace (in this case the CRLF), or by any character after the 3rd decimal digit character because of the precision of 3.

You almost always want to use precision in your COMSCAN conversion specifications, otherwise matching can erroneously succeed before all the bytes are received on the serial port.


Example 4. COMSCAN of Modbus RTU Response

In example 2, COMPRINT was used to send a Modbus query. In this current example, the desired Modbus RTU response is for the Read Holding Registers query, Modbus function number 3 and coming back from slave 2:

+-------+-------+-------+-------+-------+-------+-------+   +-------+-------+
|  02   |  03   |# bytes|data0Hi|data0Lo|data1Hi|data1Lo|...| CRC Lo| CRC Hi|
+-------+-------+-------+-------+-------+-------+-------+   +-------+-------+
                        |<---- 125 words or 250 bytes ----->|

For discussion, we'll assume the query asked for 125 registers. Then the # bytes field will be 250 which is 0xFA in hex. COMSCAN is both a matcher and converter. If slave id, function, # bytes, or CRC do not match, then the ER bit is set along with the DN bit. However, the Params can still be modified even on COMSCAN mismatch and failure. Therefore it is critical to buffer the Params and copy them to a safe useable place when the DN bit is on without the ER bit.


Format: 4

One parameter: integer

Note
Look at our example string table's format string number 4. The first byte is 0x02 and is the slave id we arbitrarily chose for this example. It could be any slave id. The next byte is hard coded as 0x03, the Modbus function. The next byte is 0xFD which is 2 x 125, the byte count. Then comes the conversion specification %.250C, which means convert 250 bytes in big endian fashion and store the results starting at Param1, with 2 bytes per integer. The last conversion specification is the %#R which is for the CRC-16, preloaded with 0xFFFF and compared little endian to the received bytes at this position. This conversion specification is for matching only, no conversion is stored in any Param, so no Param is required for it.


Example 5. Simple Modbus RTU Master

This example is a complete working Modbus RTU master implemented with a COMPRINT and two COMSCANs. The COMPRINT is basically described by example 2. On the serial cable, in response to the COMPRINT one of three results are expected:

  1. A valid Modbus response packet
  2. A valid Modbus exception packet
  3. Garbage or no response at all

Matching a Modbus response was discussed in example 4, and it requires its own COMSCAN instruction with a taylor made format string. Matching a Modbus exception packet requires another COMSCAN instruction with a different taylor made format string. Because COMSCAN puts back all characters when any part of the matching process fails, this leaves them all available for the next COMSCAN to try and match against. If the second one also fails, any garbage characters can be cleared out of the receive buffer with the COMRCVCLEAR TLI.

The example is available both as a PDF printout and as a binary SOFTPLC.APP file. You can download either from our website. To use the SOFTPLC.APP file, put it into a new directory like \SoftPLC\app\MODBMAST\ or similar so that TOPDOC NexGen can find it. Acrobat Reader is needed to view the PDF file, and can also be used to print it out to a printer.

This example uses format strings 2, 4, and 5. Format strings 2 and 4 were discussed in examples 2 and 4 respectively. Format string 5 is designed to match an exception response, per the Modbus specification and capture the single byte exception code into the least significant byte of an integer Param.

Please read the PDF file and the rung comments for the full understanding of the program logic.