AVMOD IO44D, IO44DU

From VIT company
Jump to: navigation, search

Application

The modules are designed for discrete control with different load and inquiries for status of discrete inputs through the interface RS485 or USB. Device name has type marking which indicates that digital input/output device has 4 inputs and 4 outputs, and if it contans the "U" letter - device has USB interface with appropriate functionality.

Functional capabilities

  • 4 groups of contacts (relay) and 4 discreet inputs;
  • Maximum switching current up to 5 A and voltage up to 240 V;
  • Galvanically decoupled RS485 and USB 2.0 interfaces;
  • Can be used as USB to RS485 converter;
  • Ability to connect a number of devices to one bus;
  • Control via industry standard ModBus protocol;
  • Asynchronous registration of input events;
  • Relays can be flipped for a defined time interval by one command;
  • Access trough the virtual COM-port when connected to the PC by USB;
  • Galvanically decoupled inputs with internal pull-up resistors or independent voltage inputs;
  • Reliable and practical enclosure that can be installed on DIN-rail;
  • Test and configuration utility for PC is supplied;
  • The ability to broadcast the status of inputs to outputs.

Technical characteristics

Parameters of contact pairs

Number of contact pairs 4
Maximum switching voltage 240V
Maximum switching current 5A
Galvanic decoupling from other nodes in a circuit >1000V
Mechanical reliability of contacts 10 000 000 responses
Electrical strength of contacts 10 000 responses
Versions of contact pairs closed/open

Parameters of discrete inputs

Number of inputs 4
Input variants
Commutation to the common ground:
Internal pull-up resistors 2.2kOm
Internal source voltage +4V
Independent isolated voltage-driven inputs
Voltage +5/+12/+24V
Overvoltage protection <2Unom
Galvanic decoupling from other nodes in a circuit >1000V

Parameters of RS485 Interface

Supported baud rate, Bd 4800, 9600, 14400, 57600, 19200, 38400, 115200
Parity modes EVEN, ODD, NO
Galvanic decoupling from other nodes in a circuit 1000V
ESD protection 20kV

Parameters of USB* interface

Specification 2.0
Electrostatic discharge protection 20kV
Galvanic decoupling from other nodes in a circuit >1000V

Power parameters

Supply voltage 10…30V
Maximum consumption current 150mA
Power polarity changing protection Implemented

*Only for IO44DU module

Connection of external circuits

The following is the schema of external connectors of IO44D/IO44DU module:

AVMOD IO44D, IO44DU.The schema of external connectors of IO44D/IO44DU module
AVMOD IO44D, IO44DU.The schema of external connectors of IO44D/IO44DU module (X6)
Connector Description Contacts
1 2 3 4 5
X1 Relays 1,2 Relay 1 Relay 1 Relay 2 Relay 2 -
X2 Relays 3,4 Relay 3 Relay 3 Relay 4 Relay 4 -
X3 Inputs 1,2 Input 2 Input 2 common Input 1 common Input 1 -
X4 Inputs 3,4 Input 4 Input 4 common Input 3 common Input 3 -
X5 RS485, power supply RS485 A RS485 B RS485 C (common) +Usup -Usup
X6* Type B USB slot -


SA1 – termination resistor and safe bias resistor switch
*Only for IO44DU module

RS485 interface

IO44DU


Internal logical structure of IO44DU module is as follows:

AVMOD IO44D, IO44DU.Internal logical structure of IO44DU module


Module has internal RS485 bus, to which relay and discrete input controller is connected. Access to RS485 bus can be achieved in two ways: by connecting directly to its lines through device’s outer connectors, or through the built in RS485-USB interface converter (see the “USB interface” section). When connecting through RS485-RS232 converter port number is being defined by physical number of the COM port, to which converter is connected.

IO44D


Internal logical structure of IO44D module is as follows:

AVMOD IO44D, IO44DU.Internal logical structure of IO44D module


Module control can be performed only with additional interface converter or IO44DU module connected to common RS485 bus.


Attention!


If several IO44D(U) modules are connected to RS485 bus, it is necessary to turn SA1 switch to position “1” on two of them that are topologically placed at the ends of the bus. It is needed for connection of termination resistor and safe bias resistor.


A number of IO44D modules can be connected to RS485 bus, only if each module has a unique address.

Relay contacts


AVMOD modules IO44DU and IO44D contain four galvanically independent relay contact groups brought out to the external terminal blocks. Typical scheme of management of external loads is as follows:

AVMOD IO44D, IO44DU.Typical scheme of management of external loads

Discrete inputs


IO44DU/IO44D modules can have two different types of digital inputs. The first type is independent isolated voltage-driven inputs. To feed a logical one to the input, it must be connected to an external power source. Ratings of the internal limiting resistors depend on the input voltage, with which the module works (+5, +12 or +24). In this version, all the inputs are not galvanically connected to each other and to other nodes in the scheme.

AVMOD IO44D, IO44DU. Independent isolated voltage-driven inputs

The second version of inputs - the inputs switched to a common ground. To feed a logical one it is necessary to close corresponding input terminals. In this embodiment, the inputs are galvanically decoupled from the rest of circuit nodes, but have a common ground. This embodiment of the inputs is used for conjunction of external keys by "dry contact" scheme.

AVMOD IO44D, IO44DU. The inputs switched to a common ground

USB interface (IO44DU)


The USB unit is actually a built-in RS485-USB interface converter, enabling access to the internal RS485 bus of the device. When plugged in USB port, the device is determined by the system as a virtual COM port. Number assigned to the port can be defined as follows: go to Start -> Control Panel -> System -> Hardware -> Device Manager -> Ports COM and LPT. In the list of ports, find the port with the name Silicon Labs CP2103 USB to UART Bridge. Number of this port is the desired one.

Power supply


The module can operate at supply voltages ranging from +10 to +30 V. Recommended operating range is 12 - 24V. Maximum current consumption of the module is 150mA with four relays and supply voltage 10V. Protection against reverse polarity is implemented.

Avmod configuration utility


The tool is designed to configure and test the functionality of various devices of AVMOD series. It makes possible searching for devices connected to the PC serial port (including virtual).

Port selection


To start working with the utility, select the serial port to which the device is connected (see the “USB interface” and “RS485 interface” sections). Port is selected from the “Port” drop-down list, which includes available serial ports.

Search by address


This type of search should be used when one or more modules are connected to the bus, each having equal and known rate of exchange and the type of parity, but different addresses. For search, “by baud rate” and “by address” switches should be turned OFF and ON, respectively. You must also specify the initial (current) and end address, baud rate and parity, in which to search. When searching by the address, baud rate and parity remain unchanged. The search can be carried out until the first device is found, or by the range of addresses.

Search by baud rate


This type of search should be used when the address of the device is known, but exchange rate and the type of parity are unknown. For search, “by baud rate” and “by address” switches should be turned ON and OFF, respectively. The current address should be provided as well. When searching by baud rate, the current address remains unchanged. The search can be carried out until the first device is found, or in all possible combinations of baud rate and parity.


Attention!


When devices with the same address, baud rate, parity, or the same baud rate, and the address, but different parity are connected to a single bus, conflict may arise, leading to incorrect device detection.

Search by baud rate and address


This type of search should be used in case if the address, baud rate and parity of the devices connected to the bus, are unknown. This type of search is the slowest since it implies consistent review of all possible combinations of baud rate and parity for all addresses. For search, “by baud rate” and “by address”, both switches should be turned ON. Initial (current) and end address range should be specified as well. The search can be carried out until the first device is found, or by all addresses for each possible combinations of baud rate and parity.

Device configuration


Configuration of the device is done directly in the device list window. To change the baud rate or the type of device parity, click the appropriate box and select the desired values in the drop-down list. To change the address of the device, enter the desired value into the address cell.

Control mode of IO44D and IO44DU modules


To switch to the control mode, select the device from the device list in the “Search” tab. The “Control” tab will appear. It will contain control elements specific for the selected device type. For these modules the following controls are available:

  • Switch of the relay’s state;
  • Specified time interval switches of the relay;
  • Flags of the input state and their reset button (« <- »);
  • Flags that register transitions from 1 to 0 and their update and reset buttons (« <- » and «0» );
  • Flags that register transitions from 0 to 1 and their update and reset buttons (« <- » and «0» );
  • Flags that register any transitions and their update and reset buttons (« <- » and «0» ).

Terminal display mode


Terminal allows controlling the exchange of packages between the software and modules. To enable the display of the terminal, select Show Terminal in the View menu. To hide the terminal, select Hide the terminal.

Program model of IO44D and IO44DU

Description of the communication protocol


Data exchange happens by means of the packages. Each package consists of one address byte, function code byte, a sequence of data bytes, and two-byte checksum. Functional code and data bytes form the elementary protocol package (PDU).

Address on bus Functional code Data CRC16


Address of the device determines for which device on the bus is the current package or on what device it was obtained (in case of sending a response). The address can be in the range 1...255 (recommended in the protocol specification ModBus addresses are 1...247). Address 0 - broadcast: when referring to it all the devices connected to the bus follow the corresponding instructions, without sending a response package. Packages with address that does not match the address of the device or is not zero, are being ignored by the device. Functional codes define the purpose of the data that follows. The checksum is calculated on the basis of the standard ModBus polynomial. If the checksum does not match, the device ignores the package.


According to the ModBus protocol, access to resources of AVMOD IO44D (U) module is carried out by bit or registers method, i.e. communication with a variety of resources, such as relays or inputs, in most cases, can occur through the read-write binary (bit) variables, and through the ranks of the relevant registers.

Functional codes


The AVMOD IO44DU device supports the following functional codes:

Functional code Description
0х01 reading of bit variables
0х02 reading of discrete inputs
0х03 reading of registers
0х05 writing of one bit variable
0х06 writing of one register
0х0F writing of bit variables
0х10 writing of registers


0х01 (1) – Allows reading values of several bit variables. The address of the first variable with which to begin reading and the number of variables that should be read are specified in the request. In the response, values of the variables are represented by bits, i.e. first variable corresponds to the first (lower) bit of the low byte, the second - the second bit, etc. The n number of data bytes in the response equals to the number of variables divided by 8 and rounded up to the nearest whole number.


Request:

Description Byte Values range
Functional code 1 0х01
Start address 2 0x0000 - 0x000F
Number of variables 2 0х0001 - 0х000F

Response:

Description Byte Values range
Functional code 1 0х01
Number of bytes 1 0x01 - 0x02
Variable values n -


Example: read state of four discrete variables, beginning with address 0х0000 (variables with addresses 0 and 2 - logical 1, 1 and 3 – logical 0)
Request: 01 01 00 00 00 04 3D CD
Response: 01 01 01 05 91 8B

0х02 (2) – Allows reading values of several discrete inputs. The address of the input from which to begin reading and the number of inputs that should be read are specified in the request. In the response, values of the inputs are represented by bits, i.e. first input corresponds to the first (lower) bit of the low byte, the second - the second bit, etc. The n number of data bytes in the response equals to the number of inputs divided by 8 and rounded up to the nearest whole number.

Request:

Description Byte Values range
Functional code 1 0х02
Start address 2 0x0000 - 0x000F
Number of variables 2 0х0001 - 0х0010

Response:

Description Byte Values range
Functional code 1 0х01
Number of bytes 1 0x01 - 0x02
Variable values n -


Example: read state of four discrete inputs, beginning with address 0х0004 (input 4 – logical 1)
Request: 01 02 00 04 00 04 38 08
Response: 01 02 01 08 A0 4E

0х03 (3) – Allows reading of several registers. The address of the first register from which to begin reading and the number of registers that should be read are specified in the request. In the response, two bytes of data correspond to each register.


Request:

Description Byte Values range
Functional code 1 0х03
Start address 2 0x0000 - 0x000C
Number of variables 2 0х0001 - 0х000D


Response:

Description Byte Values range
Functional code 1 0х03
Number of bytes 2 0x0001 - 0x000D
Number of variables n -


Example: Read the contents of two registers beginning with address 0х0000 (contents 0х0001 and 0х0222)
Request: 01 03 00 00 00 02 C4 0B
Response: 01 03 04 02 22 00 01 9А 41

0х05 (5) – Allows changing of one bit variable at specified address. The variable is being set to logical 1, if passed value equals to 0хFF00 and to logical 0, if 0х0000. All other values lead to generation of the error code.


Request:

Description Byte Values range
Functional code 1 0х05
Address 2 0x0000 - 0x000F
Value 2 0х0000 or 0хFF00


Response:

Description Byte Values range
Functional code 1 0х05
Address 2 0x0000 - 0x000F
Value 2 0х0000 or 0хFF00


Example: Write logical 1 into variable with address 0х0000.
Request: 01 05 00 00 FF 00 8C 3A
Response: 01 05 00 00 FF 00 8C 3A

0х06 (6) – Allows changing the value of one register at the specified address.


Request:

Description Byte Values range
Functional code 1 0х06
Address 2 0x0002 - 0x000C
Value 2 0х0000 - 0хFFFF


Response:

Description Byte Values range
Functional code 1 0х06
Address 2 0x0002 - 0x000
Value 2 0х0000 - 0хFFFF


Example: Write 0х0010 value into register with address 0х0009.
Request: 01 06 00 09 00 10 58 04
Response: 01 06 00 09 00 10 58 04

0x0F (15) – Allows changing states of several bit variables. The address of the first variable and the number of variable that should be written are specified in the request. Values of the variables are defined by corresponding bits of data bytes, i.e. first variable corresponds to the first (lower) bit of the low byte, the second - the second bit, etc. The n number of data bytes equals to the number of variables divided by 8 and rounded up to the nearest whole number.


Request:

Description Byte Values range
Functional code 1 0х0F
Start address 2 0x0000 - 0x000F
Number of variables 2 0х0001 - 0х0010
Number of bytes 1 n
Value n -

Response:

Description Byte Values range
Functional code 1 0х0F
Start address 2 0x0000 - 0x000F
Number of variables 2 0х0001 - 0х0010


Example: Write four bit variables beginning with the address 0х0000 (0 and 2 – logical 1)
Request: 01 0F 00 00 00 04 01 05 FE 95
Response: 01 0F 00 00 00 04 54 08


0x10 (16) – Allows changing values of several registers. The address of the first register and the number of registers that should be written are specified in the request. The n number of data bytes should equal to the number of registers multiplied by two.


Request:

Description Byte Values range
Functional code 1 0х10
Start address 2 0x0002 - 0x000C
Number of variables 2 0х0001 - 0х000A
Number of bytes 1 n
Value n -


Response:

Description Byte Values range
Functional code 1 0х10
Start address 2 0x0002 - 0x000C
Number of variables 2 0х0001 - 0х000A


Example: Write 0х0010 value into four registers beginning with the address 0х0009
Request: 01 10 00 09 00 04 08 00 10 00 10 00 10 00 10 7A 6D
Response: 01 10 00 09 00 04 11 C8

Error codes


If an error occurs while accessing resources on the device, the response package will contain a functional error code and exception code. The error code is formed by adding the function code of request with the 0x80 constant.


Error:

Description Byte Values range
Functional code 1 Functional request code + 0х80
Exception 1 0х01 or 0х02 or 0х03 or 0х04


Exception codes indicate the type of error:

0х01 – wrong functional code
0х02 – wrong data address
0х03 – wrong data value
'0х04 – error while trying to execute function

Description of registers


Access to the registers is carried out with functional codes 0x03, 0x06 and 0x10

Register address Description
0x00 Two upper bytes of serial number
0x01 Two lower bytes of serial number
0x02 Device’s address
0x03 Baud rate/parity
0x04 Relay (lower nibble)
0x05 Inputs (lower nibble)
0x06 Transitions from high to low (lower nibble)
0x07 Transitions from low to high (lower nibble)
0x08 Any transitions (lower nibble)
0x09 Switching relay 1 to the specified number of tenths of a second
0x0A Switching relay 2 to the specified number of tenths of a second
0x0B Switching relay 3 to the specified number of tenths of a second
0x0C Switching relay 4 to the specified number of tenths of a second
0x0D Link between inputs and outputs


0x00, 0x01 (read only) – registers, containing type of the device and serial number.
0x02 – device address register on the ModBus.
0x03 – baud rate and parity setting register on the RS485 line.


Lower byte of the register defines baud rate:  

Lower byte of 0x03 register Baud rate, Bd
0 4800
1 9600
2 14400
3 19200*
4 38400
5 57600
6 115200


High byte determines the type or presence of parity byte in the package:

High byte of 0x03 register Parity
0 EVEN*
1 ODD
2 NO

* Factory baud rate and parity (0x0003).


0x04 – relay control register. Lower nibble bits of this register determine the state of the relay. While writing logical one to the corresponding bit, the contacts are being closed if they were normally opened. In case if they were closed, the contacts will be opened while writing logical one.


0x05 – register of the discrete inputs. Lower nibble of this register correspond to the discrete inputs. In case when pull-up resistors are present, corresponding bit is set to logical one if input is connected to the ground. If pull-up resistors are not present the bit is set when voltage that exceeds threshold appears on the input.


0х06 – latch register, the corresponding bits of which (lower nibble) are set to 1 if on one or more inputs there was a transition from high to low level. Bits can be reset to initial state only with software writing 0.


0х07 – latch register, the corresponding bits of which (lower nibble) are set to 1 if on one or more inputs there was a transition from low to high level. Bits can be reset to initial state only with software writing 0.


0х08 – latch register, the corresponding bits of which (lower nibble) are set to 1 if on one or more inputs there was any transition of state. Bits can be reset to initial state only with software writing 0.


0х09, 0х0A, 0x0B, 0x0C – 2-byte registers that change state of the corresponding relay (0x09 corresponds to relay 1 etc.) for specified time interval. When writing to a register with number N different from 0, the state of the relay switches to opposite for the specified by the written number time period. The number has a dimension of tenth of a second, i.e. T (time delay) in seconds can be defined by the formula T = N * 10. After specified time delay, the relay switches to its original state.


0x0D – discrete inputs and relay linking register. When setting register’s bits of lower nibble to 1, connection between corresponding inputs and outputs is being established.

Bit variables and inputs


Access to bit variables is carried out with functional codes 0x01, 0x05, 0x0F; to discrete inputs – 0x02

Address Description
Bit variables Inputs
0x00 Relay 1 Input 1
0x01 Relay 2 Input 2
0x02 Relay 3 Input 3
0x03 Relay 4 Input 4
0x04 Transition H-L input 1 Transition H-L input 1
0x05 Transition H-L input 2 Transition H-L input 2
0x06 Transition H-L input 3 Transition H-L input 3
0x07 Transition H-L input 4 Transition H-L input 4
0x08 Transition L-H input 1 Transition L-H input 1
0x09 Transition L-H input 2 Transition L-H input 2
0x0A Transition L-H input 3 Transition L-H input 3
0x0B Transition L-H input 4 Transition L-H input 4
0x0C Any transition input 1 Any transition input 1
0x0D Any transition input 2 Any transition input 2
0x0E Any transition input 3 Any transition input 3
0x0F Any transition input 4 Any transition input 4
0x10 Linking of input 1 with relay 1 Linking of input 1 with relay 1
0x11 Linking of input 2 with relay 2 Linking of input 2 with relay 2
0x12 Linking of input 3 with relay 3 Linking of input 3 with relay 3
0x13 Linking of input 4 with relay 4 Linking of input 4 with relay 4


0x00, 0х01, 0x02, 0x03 – discrete variables of relays or inputs. Functional codes 0x01, 0x05, 0x0F correspond to bits of first nibble of register 0x04 (relay). Code 0x02 allows reading state of the corresponding inputs.


0x04, 0х05, 0x06, 0x07 – correspond to the first four bits of the latch resistor’s transition from high to low level (0x06). Available by functional codes 0x01, 0x02, 0x05, 0x0F.


0x08, 0х09, 0x0A, 0x0B – correspond to the first four bits of the latch resistor’s transition from low to high level (0х07). Available by functional codes 0x01, 0x02, 0x05, 0x0F.


0x0C, 0х0D, 0x0E, 0x0F – correspond to the first four bits of the latch resistor’s transition from high to low level (0х08). Available by functional codes 0x01, 0x02, 0x05, 0x0F.


0x10, 0х11, 0x12, 0x13 – correspond to the first four bits of input and relay linking register (0х0D). Available by functional codes 0x01, 0x02, 0x05, 0x0F.

Example of checksum calculation subprogram in C

unsigned char auchCRCHi[] = {
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81,
0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
0x40
} ;
 
unsigned char auchCRCLo[] = {
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4,
0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD,
0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7,
0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE,
0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2,
0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB,
0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91,
0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88,
0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80,
0x40
};
 
unsigned short CRC16 ( unsigned char *puchMsg, unsigned short usDataLen)
{
	unsigned char uchCRCHi = 0xFF ; 			
	unsigned char uchCRCLo = 0xFF ; 			
	unsigned uIndex ; 					
	while (usDataLen--) { 				
		uIndex = uchCRCLo ^ *puchMsg++ ; 	
		uchCRCLo = uchCRCHi ^ auchCRCHi[uIndex] ;
		uchCRCHi = auchCRCLo[uIndex] ;
	}
	return (uchCRCHi << 8 | uchCRCLo) ;
}

Example of checksum calculation subprogram in Pascal

const
 
CRChi : array[0..255] of byte =
  ( 
  $00,$C1,$81,$40,$01,$C0,$80,$41,$01,$C0,$80,$41,$00,$C1,$81,$40,
  $01,$C0,$80,$41,$00,$C1,$81,$40,$00,$C1,$81,$40,$01,$C0,$80,$41,
  $01,$C0,$80,$41,$00,$C1,$81,$40,$00,$C1,$81,$40,$01,$C0,$80,$41,
  $00,$C1,$81,$40,$01,$C0,$80,$41,$01,$C0,$80,$41,$00,$C1,$81,$40,
  $01,$C0,$80,$41,$00,$C1,$81,$40,$00,$C1,$81,$40,$01,$C0,$80,$41,
  $00,$C1,$81,$40,$01,$C0,$80,$41,$01,$C0,$80,$41,$00,$C1,$81,$40,
  $00,$C1,$81,$40,$01,$C0,$80,$41,$01,$C0,$80,$41,$00,$C1,$81,$40,
  $01,$C0,$80,$41,$00,$C1,$81,$40,$00,$C1,$81,$40,$01,$C0,$80,$41,
  $01,$C0,$80,$41,$00,$C1,$81,$40,$00,$C1,$81,$40,$01,$C0,$80,$41,
  $00,$C1,$81,$40,$01,$C0,$80,$41,$01,$C0,$80,$41,$00,$C1,$81,$40,
  $00,$C1,$81,$40,$01,$C0,$80,$41,$01,$C0,$80,$41,$00,$C1,$81,$40,
  $01,$C0,$80,$41,$00,$C1,$81,$40,$00,$C1,$81,$40,$01,$C0,$80,$41,
  $00,$C1,$81,$40,$01,$C0,$80,$41,$01,$C0,$80,$41,$00,$C1,$81,$40,
  $01,$C0,$80,$41,$00,$C1,$81,$40,$00,$C1,$81,$40,$01,$C0,$80,$41,
  $01,$C0,$80,$41,$00,$C1,$81,$40,$00,$C1,$81,$40,$01,$C0,$80,$41,
  $00,$C1,$81,$40,$01,$C0,$80,$41,$01,$C0,$80,$41,$00,$C1,$81,$40 );
 
CRClo : array[0..255] of byte =
  ( 
  $00,$C0,$C1,$01,$C3,$03,$02,$C2,$C6,$06,$07,$C7,$05,$C5,$C4,$04,
  $CC,$0C,$0D,$CD,$0F,$CF,$CE,$0E,$0A,$CA,$CB,$0B,$C9,$09,$08,$C8,
  $D8,$18,$19,$D9,$1B,$DB,$DA,$1A,$1E,$DE,$DF,$1F,$DD,$1D,$1C,$DC,
  $14,$D4,$D5,$15,$D7,$17,$16,$D6,$D2,$12,$13,$D3,$11,$D1,$D0,$10,
  $F0,$30,$31,$F1,$33,$F3,$F2,$32,$36,$F6,$F7,$37,$F5,$35,$34,$F4,
  $3C,$FC,$FD,$3D,$FF,$3F,$3E,$FE,$FA,$3A,$3B,$FB,$39,$F9,$F8,$38,
  $28,$E8,$E9,$29,$EB,$2B,$2A,$EA,$EE,$2E,$2F,$EF,$2D,$ED,$EC,$2C,
  $E4,$24,$25,$E5,$27,$E7,$E6,$26,$22,$E2,$E3,$23,$E1,$21,$20,$E0,
  $A0,$60,$61,$A1,$63,$A3,$A2,$62,$66,$A6,$A7,$67,$A5,$65,$64,$A4,
  $6C,$AC,$AD,$6D,$AF,$6F,$6E,$AE,$AA,$6A,$6B,$AB,$69,$A9,$A8,$68,
  $78,$B8,$B9,$79,$BB,$7B,$7A,$BA,$BE,$7E,$7F,$BF,$7D,$BD,$BC,$7C,
  $B4,$74,$75,$B5,$77,$B7,$B6,$76,$72,$B2,$B3,$73,$B1,$71,$70,$B0,
  $50,$90,$91,$51,$93,$53,$52,$92,$96,$56,$57,$97,$55,$95,$94,$54,
  $9C,$5C,$5D,$9D,$5F,$9F,$9E,$5E,$5A,$9A,$9B,$5B,$99,$59,$58,$98,
  $88,$48,$49,$89,$4B,$8B,$8A,$4A,$4E,$8E,$8F,$4F,$8D,$4D,$4C,$8C,
  $44,$84,$85,$45,$87,$47,$46,$86,$82,$42,$43,$83,$41,$81,$80,$40 );
 
 
procedure CRC16(Data: array of byte;  len : word; var Hi : byte; var Lo : byte);
var Index : word;
    i : word;
begin
   Hi:=$FF;
   Lo:=$FF;
   i:=0;
   While (i<Len) do
   begin
     Index:=Hi xor Data[i];
     Hi:=Lo xor CRCHi[Index];
       Lo:=CRCLo[Index];
       i:=i+1;
   end;
end;
AVMOD_IO44D,_IO44DU

AVMOD_IO44D,_IO44DU