here the seperate Documentation Part of the Module because with Documentation the Module is to long for a post!
Code: Select all
;- --------------------------------------------------------------------------------
;- Documentation
;- --------------------------------------------------------------------------------
;{ Documentation
; ModBus Functions
; 01: Read Coils
; 02: Read Discret Inputs
; 03: Read Holding Registers
; 04: Read Input Registers
; 05: Write Singel Coil
; 06: Write Single Register
; 15: Write Multiple Coil
; 16: Write Multiple Register
; --------------------------------------------------------------------------------
;- READ_COILS : 01
; --------------------------------------------------------------------------------
; Implement Modbus function code 01.
; "This function code is used to read from 1 to 2000 contiguous status of
; coils in a remote device. The Request PDU specifies the starting
; address, i.e. the address of the first coil specified, And the number
; of coils. In the PDU Coils are addressed starting at zero. Therefore
; coils numbered 1-16 are addressed As 0-15.
; The coils in the response message are packed As one coil per bit of the
; Data field. Status is indicated As 1= ON And 0= OFF. The LSB of the
; first Data byte contains the output addressed in the query. The other
; coils follow toward the high order End of this byte, And from low order
; To high order in subsequent bytes.
; If the returned output quantity is Not a multiple of eight, the
; remaining bits in the final Data byte will be padded With zeros (toward
; the high order End of the byte). The Byte Count field specifies the
; quantity of complete bytes of Data."
; -- MODBUS Application Protocol Specification V1.1b3, chapter 6.1
; The request PDU With function code 01 must be 5 bytes:
; ================ ===============
; Field Length (bytes)
; ================ ===============
; Function code 1
; Starting address 2
; Quantity 2
; ================ ===============
; The PDU can unpacked To this:
; ..
; Note: the backslash in the bytes below are escaped using an extra back
; slash. Without escaping the bytes aren't printed correctly in the HTML
; output of this docs.
; To work With the bytes in Python you need To remove the escape sequences.
; `b'\\x01\\x00d` -> `b\x01\x00d`
; .. code-block:: python
; >>> struct.unpack('>BHH', b'\\x01\\x00d\\x00\\x03')
; (1, 100, 3)
; The reponse PDU varies in length, depending on the request. Each 8 coils
; require 1 byte. The amount of bytes needed represent status of the coils To
; can be calculated With: bytes = ceil(quantity / 8). This response
; contains ceil(3 / 8) = 1 byte To describe the status of the coils. The
; Structure of a compleet response PDU looks like this:
; ================ ===============
; Field Length (bytes)
; ================ ===============
; Function code 1
; Byte count 1
; Coil status n
; ================ ===============
; Assume the status of 102 is 0, 101 is 1 And 100 is also 1. This is binary
; 011 which is decimal 3.
; The PDU can packed like this::
; >>> struct.pack('>BBB', function_code, byte_count, 3)
; b'\\x01\\x01\\x03'
; --------------------------------------------------------------------------------
;- READ_DISCRETE_INPUTS : 02
; --------------------------------------------------------------------------------
; Implement Modbus function code 02.
; "This function code is used to read from 1 to 2000 contiguous status of
; discrete inputs in a remote device. The Request PDU specifies the
; starting address, i.e. the address of the first input specified, And
; the number of inputs. In the PDU Discrete Inputs are addressed starting
; at zero. Therefore Discrete inputs numbered 1-16 are addressed As
; 0-15.
; The discrete inputs in the response message are packed As one input per
; bit of the Data field. Status is indicated As 1= ON; 0= OFF. The LSB
; of the first Data byte contains the input addressed in the query. The
; other inputs follow toward the high order End of this byte, And from
; low order To high order in subsequent bytes.
; If the returned input quantity is Not a multiple of eight, the
; remaining bits in the final d ata byte will be padded With zeros
; (toward the high order End of the byte). The Byte Count field specifies
; the quantity of complete bytes of Data."
; -- MODBUS Application Protocol Specification V1.1b3, chapter 6.2
; The request PDU With function code 02 must be 5 bytes:
; ================ ===============
; Field Length (bytes)
; ================ ===============
; Function code 1
; Starting address 2
; Quantity 2
; ================ ===============
; The PDU can unpacked To this:
; ..
; Note: the backslash in the bytes below are escaped using an extra back
; slash. Without escaping the bytes aren't printed correctly in the HTML
; output of this docs.
; To work With the bytes in Python you need To remove the escape sequences.
; `b'\\x01\\x00d` -> `b\x01\x00d`
; .. code-block:: python
; >>> struct.unpack('>BHH', b'\\x02\\x00d\\x00\\x03')
; (2, 100, 3)
; The reponse PDU varies in length, depending on the request. 8 inputs
; require 1 byte. The amount of bytes needed represent status of the inputs
; To can be calculated With: bytes = ceil(quantity / 8). This response
; contains ceil(3 / 8) = 1 byte To describe the status of the inputs. The
; Structure of a compleet response PDU looks like this:
; ================ ===============
; Field Length (bytes)
; ================ ===============
; Function code 1
; Byte count 1
; Coil status n
; ================ ===============
; Assume the status of 102 is 0, 101 is 1 And 100 is also 1. This is binary
; 011 which is decimal 3.
; The PDU can packed like this::
; >>> struct.pack('>BBB', function_code, byte_count, 3)
; b'\\x02\\x01\\x03'
; --------------------------------------------------------------------------------
;- READ_HOLDING_REGISTERS : 03
; --------------------------------------------------------------------------------
; Implement Modbus function code 03.
; "This function code is used to read the contents of a contiguous block
; of holding registers in a remote device. The Request PDU specifies the
; starting register address And the number of registers. In the PDU
; Registers are addressed starting at zero. Therefore registers numbered
; 1-16 are addressed As 0-15.
; The register Data in the response message are packed As two bytes per
; register, With the binary contents right justified within each byte.
; For each register, the first byte contains the high order bits And the
; second contains the low order bits."
; -- MODBUS Application Protocol Specification V1.1b3, chapter 6.3
; The request PDU With function code 03 must be 5 bytes:
; ================ ===============
; Field Length (bytes)
; ================ ===============
; Function code 1
; Starting address 2
; Quantity 2
; ================ ===============
; The PDU can unpacked To this:
; ..
; Note: the backslash in the bytes below are escaped using an extra back
; slash. Without escaping the bytes aren't printed correctly in the HTML
; output of this docs.
; To work With the bytes in Python you need To remove the escape sequences.
; `b'\\x01\\x00d` -> `b\x01\x00d`
; .. code-block:: python
; >>> struct.unpack('>BHH', b'\\x03\\x00d\\x00\\x03')
; (3, 100, 3)
; The reponse PDU varies in length, depending on the request. By Default,
; holding registers are 16 bit (2 bytes) values. So values of 3 holding
; registers is expressed in 2 * 3 = 6 bytes.
; ================ ===============
; Field Length (bytes)
; ================ ===============
; Function code 1
; Byte count 1
; Register values Quantity * 2
; ================ ===============
; Assume the value of 100 is 8, 101 is 0 And 102 is also 15.
; The PDU can packed like this::
; >>> Data = [8, 0, 15]
; >>> struct.pack('>BBHHH', function_code, Len(Data) * 2, *data)
; b'\\x03\\x06\\x00\\x08\\x00\\x00\\x00\\x0f'
; --------------------------------------------------------------------------------
;- READ_INPUT_REGISTERS : 04
; --------------------------------------------------------------------------------
; Implement Modbus function code 04.
; "This function code is used to read from 1 to 125 contiguous input
; registers in a remote device. The Request PDU specifies the starting
; register address And the number of registers. In the PDU Registers are
; addressed starting at zero. Therefore input registers numbered 1-16 are
; addressed As 0-15.
; The register Data in the response message are packed As two bytes per
; register, With the binary contents right justified within each byte.
; For each register, the first byte contains the high order bits And the
; second contains the low order bits."
; -- MODBUS Application Protocol Specification V1.1b3, chapter 6.4
; The request PDU With function code 04 must be 5 bytes:
; ================ ===============
; Field Length (bytes)
; ================ ===============
; Function code 1
; Starting address 2
; Quantity 2
; ================ ===============
; The PDU can unpacked To this:
; ..
; Note: the backslash in the bytes below are escaped using an extra back
; slash. Without escaping the bytes aren't printed correctly in the HTML
; output of this docs.
; To work With the bytes in Python you need To remove the escape sequences.
; `b'\\x01\\x00d` -> `b\x01\x00d`
; .. code-block:: python
; >>> struct.unpack('>BHH', b'\\x04\\x00d\\x00\\x03')
; (4, 100, 3)
; The reponse PDU varies in length, depending on the request. By Default,
; holding registers are 16 bit (2 bytes) values. So values of 3 holding
; registers is expressed in 2 * 3 = 6 bytes.
; ================ ===============
; Field Length (bytes)
; ================ ===============
; Function code 1
; Byte count 1
; Register values Quantity * 2
; ================ ===============
; Assume the value of 100 is 8, 101 is 0 And 102 is also 15.
; The PDU can packed like this::
; >>> Data = [8, 0, 15]
; >>> struct.pack('>BBHHH', function_code, Len(Data) * 2, *data)
; b'\\x04\\x06\\x00\\x08\\x00\\x00\\x00\\x0f'
; --------------------------------------------------------------------------------
;- WRITE_SINGLE_COIL : 5
; --------------------------------------------------------------------------------
; Implement Modbus function code 05.
; "This function code is used to write a single output to either ON or
; OFF in a remote device. The requested ON/OFF state is specified by a
; constant in the request Data field. A value of FF 00 hex requests the
; output To be ON. A value of 00 00 requests it To be OFF. All other
; values are illegal And will Not affect the output.
; The Request PDU specifies the address of the coil To be forced. Coils
; are addressed starting at zero. Therefore coil numbered 1 is addressed
; As 0. The requested ON/OFF state is specified by a constant in the
; Coil Value field. A value of 0XFF00 requests the coil To be ON. A value
; of 0X0000 requests the coil To be off. All other values are illegal And
; will Not affect the coil.
; The normal response is an echo of the request, returned after the coil
; state has been written."
; -- MODBUS Application Protocol Specification V1.1b3, chapter 6.5
; The request PDU With function code 05 must be 5 bytes:
; ================ ===============
; Field Length (bytes)
; ================ ===============
; Function code 1
; Address 2
; Value 2
; ================ ===============
; The PDU can unpacked To this:
; ..
; Note: the backslash in the bytes below are escaped using an extra back
; slash. Without escaping the bytes aren't printed correctly in the HTML
; output of this docs.
; To work With the bytes in Python you need To remove the escape sequences.
; `b'\\x01\\x00d` -> `b\x01\x00d`
; .. code-block:: python
; >>> struct.unpack('>BHH', b'\\x05\\x00d\\xFF\\x00')
; (5, 100, 65280)
; The reponse PDU is a copy of the request PDU.
; ================ ===============
; Field Length (bytes)
; ================ ===============
; Function code 1
; Address 2
; Value 2
; ================ ===============
; --------------------------------------------------------------------------------
;- WRITE_SINGLE_REGISTER : 06
; --------------------------------------------------------------------------------
; Implement Modbus function code 06.
; "This function code is used to write a single holding register in a
; remote device. The Request PDU specifies the address of the register To
; be written. Registers are addressed starting at zero. Therefore
; register numbered 1 is addressed As 0. The normal response is an echo
; of the request, returned after the register contents have been
; written."
; -- MODBUS Application Protocol Specification V1.1b3, chapter 6.6
; The request PDU With function code 06 must be 5 bytes:
; ================ ===============
; Field Length (bytes)
; ================ ===============
; Function code 1
; Address 2
; Value 2
; ================ ===============
; The PDU can unpacked To this:
; ..
; Note: the backslash in the bytes below are escaped using an extra back
; slash. Without escaping the bytes aren't printed correctly in the HTML
; output of this docs.
; To work With the bytes in Python you need To remove the escape sequences.
; `b'\\x01\\x00d` -> `b\x01\x00d`
; .. code-block:: python
; >>> struct.unpack('>BHH', b'\\x06\\x00d\\x00\\x03')
; (6, 100, 3)
; The reponse PDU is a copy of the request PDU.
; ================ ===============
; Field Length (bytes)
; ================ ===============
; Function code 1
; Address 2
; Value 2
; ================ ===============
; --------------------------------------------------------------------------------
;- WRITE_MULTIPLE_COILS : 15
; --------------------------------------------------------------------------------
; Implement Modbus function 15 (0x0F) Write Multiple Coils.
; "This function code is used to force each coil in a sequence of coils
; To either ON Or OFF in a remote device. The Request PDU specifies the
; coil references To be forced. Coils are addressed starting at zero.
; Therefore coil numbered 1 is addressed As 0.
; The requested ON/OFF states are specified by contents of the request
; Data field. A logical '1' in a bit position of the field requests the
; corresponding output To be ON. A logical '0' requests it To be OFF.
; The normal response returns the function code, starting address, And
; quantity of coils forced."
; -- MODBUS Application Protocol Specification V1.1b3, chapter 6.11
; The request PDU With function code 15 must be at least 7 bytes:
; ================ ===============
; Field Length (bytes)
; ================ ===============
; Function code 1
; Starting Address 2
; Quantity 2
; Byte count 1
; Value n
; ================ ===============
; The PDU can unpacked To this:
; ..
; Note: the backslash in the bytes below are escaped using an extra back
; slash. Without escaping the bytes aren't printed correctly in the HTML
; output of this docs.
; To work With the bytes in Python you need To remove the escape sequences.
; `b'\\x01\\x00d` -> `b\x01\x00d`
; .. code-block:: python
; >>> struct.unpack('>BHHBB', b'\\x0f\\x00d\\x00\\x03\\x01\\x05')
; (16, 100, 3, 1, 5)
; The reponse PDU is 5 bytes And contains following Structure:
; ================ ===============
; Field Length (bytes)
; ================ ===============
; Function code 1
; Starting address 2
; Quantity 2
; ================ ===============
; --------------------------------------------------------------------------------
;- WRITE_MULTIPLE_REGISTERS : 16
; --------------------------------------------------------------------------------
; Implement Modbus function 16 (0x10) Write Multiple Registers.
; "This function code is used to write a block of contiguous registers (1
; To 123 registers) in a remote device.
; The requested written values are specified in the request Data field.
; Data is packed As two bytes per register.
; The normal response returns the function code, starting address, And
; quantity of registers written."
; -- MODBUS Application Protocol Specification V1.1b3, chapter 6.12
; The request PDU With function code 16 must be at least 8 bytes:
; ================ ===============
; Field Length (bytes)
; ================ ===============
; Function code 1
; Starting Address 2
; Quantity 2
; Byte count 1
; Value Quantity * 2
; ================ ===============
; The PDU can unpacked To this:
; ..
; Note: the backslash in the bytes below are escaped using an extra back
; slash. Without escaping the bytes aren't printed correctly in the HTML
; output of this docs.
; To work With the bytes in Python you need To remove the escape sequences.
; `b'\\x01\\x00d` -> `b\x01\x00d`
; .. code-block:: python
; >>> struct.unpack('>BHHBH', b'\\x10\\x00d\\x00\\x01\\x02\\x00\\x05')
; (16, 100, 1, 2, 5)
; The reponse PDU is 5 bytes And contains following Structure:
; ================ ===============
; Field Length (bytes)
; ================ ===============
; Function code 1
; Starting address 2
; Quantity 2
; ================ ===============
; ----------------------------------------------------------------------
;- ADU: Aplication Data Unit
; ----------------------------------------------------------------------
; The ADU covers the PDU with Adress+PDU+Checksum
; ADU for RTU
; -----------------------------------
; | 1Byte | max 253 | 2Byte |
; |--------|-------------|----------|
; | Adress | FC | Data | Checksum |
; -----------------------------------
; | PDU |
; -----------------------------------
; ADU Frame for TCP : 7 Byte ADU Frame + PDU
; -----------------------------------------------------------------------------------
; | Modbus TCP ADU-HEADER | Modbus PDU |
; -----------------------------------------------------------------------------------
; | [0..1] | [2..3] | [4..5] | [6] | [7] | [8..9] | [10..259] |
; -----------------------------------------------------------------------------------
; | Transaction | Protocol ID | MessageLength | DeviceID | FC | ADR | DATA |
; -----------------------------------------------------------------------------------
; | | [7] | [8] | [9..259] |
; | for the response ----------------------------
; | | FC | NB | DATA |
; -----------------------------------------------------------------------------------
; MessageLength = Len(DeviceID) + Len(PDU); NB : NumberOfBytes follow
; the Transaction ID is an 'unique' user defined ID for each transaction
; it will be returned in the response to indentify the transaction
; The protocol identifier is normally zero, but you can use it To expand the behavior of the protocol.
; The length field is used by the protocol To delineate the length of the rest of the packet.
; The location of this element also indicates the dependency of this header format on a reliable networking layer.
; Because TCP packets have built-in error checking And ensure Data coherency And delivery, packet length
; can be located anywhere in the header. On a less inherently reliable network such As a serial network,
; a packet could be lost, having the effect that even If the stream of Data Read by the application included
; valid transaction and protocol information, corrupted length information would make the header invalid.
; TCP provides a reasonable amount of protection against this situation.
; The Unit ID is typically unused For TCP/IP devices. However, Modbus is such a common protocol that many gateways
; are developed, which convert the Modbus protocol into another protocol. In the original intended use Case,
; a Modbus TCP/IP To serial gateway could be used To allow connection between new TCP/IP networks and older serial networks.
; In such an environment, the Unit ID is used To determine the address of the slave device that the PDU is actually intended for.
; Finally, the ADU includes a PDU. The length of this PDU is still limited To 253 bytes For the standard protocol.
; ============================================================
; Example PDU For reading Coils with Request and Response
; ============================================================
; Byte | Request |Byte | Response
; ------------------------------------------------------------
; (Hex)| Fieldname |(Hex)| Fieldname
; ------------------------------------------------------------
; 01 | Transactoion ID | 01 | Transactoion ID
; 02 | | 02 |
; ------------------------------------------------------------
; 00 | Protocol | 00 | Protocol
; 00 | (always 00 or User def) | 00 |
; ------------------------------------------------------------
; 00 | Message Length | 00 | Message Length
; 06 | | 04 |
; ------------------------------------------------------------
; 01 | DeviceID, Address | 01 | DeviceID, Address
; ------------------------------------------------------------
; 01 | Function Code | 01 | Function Code
; ------------------------------------------------------------
; 00 | Addr Hi | 01 | No of Data Bytes follow
; ------------------------------------------------------------
; 00 | Addr Lo | 02 | Values of DO0 und DO1
; ------------------------------------------------------------
; 00 | No of Registers Hi Byte | 01 |
; 02 | No of Registers Hi Byte | 02 |
; ------------------------------------------------------------
; https://ipc2u.de/artikel/wissenswertes/detaillierte-beschreibung-des-modbus-tcp-protokolls-mit-befehlsbeispielen/#0x01
;}