| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- package modbus
- import (
- "encoding/binary"
- "fmt"
- )
- // proto address limit
- const (
- AddressBroadCast = 0
- AddressMin = 1
- addressMax = 247
- )
- // AddressMax proto address max limit
- // you can change with SetSpecialAddressMax,
- // when your device have address upon addressMax
- var AddressMax byte = addressMax
- const (
- PduMinSize = 1 // funcCode(1)
- PduMaxSize = 253 // funcCode(1) + data(252)
- rtuAduMinSize = 4 // address(1) + funcCode(1) + crc(2)
- rtuAduMaxSize = 256 // address(1) + PDU(253) + crc(2)
- asciiAduMinSize = 3
- asciiAduMaxSize = 256
- asciiCharacterMaxSize = 513
- tcpProtocolIdentifier = 0x0000
- // Modbus Application Protocol
- tcpHeaderMbapSize = 7 // MBAP header
- tcpAduMinSize = 8 // MBAP + funcCode
- tcpAduMaxSize = 260
- )
- // proto register limit
- const (
- // ReadBitsQuantityMin Bits
- ReadBitsQuantityMin = 1 // 0x0001
- ReadBitsQuantityMax = 2000 // 0x07d0
- WriteBitsQuantityMin = 1 // 1
- WriteBitsQuantityMax = 1968 // 0x07b0
- // ReadRegQuantityMin 16 Bits
- ReadRegQuantityMin = 1 // 1
- ReadRegQuantityMax = 125 // 0x007d
- WriteRegQuantityMin = 1 // 1
- WriteRegQuantityMax = 123 // 0x007b
- ReadWriteOnReadRegQuantityMin = 1 // 1
- ReadWriteOnReadRegQuantityMax = 125 // 0x007d
- ReadWriteOnWriteRegQuantityMin = 1 // 1
- ReadWriteOnWriteRegQuantityMax = 121 // 0x0079
- )
- // Function Code
- const (
- // FuncCodeReadDiscreteInputs Bit access
- FuncCodeReadDiscreteInputs = 2 //读离散量输入
- FuncCodeReadCoils = 1 //读线圈
- FuncCodeWriteSingleCoil = 5 //写单个线圈
- FuncCodeWriteMultipleCoils = 15 // 写多个线圈
- // FuncCodeReadInputRegisters 16-bit access
- FuncCodeReadInputRegisters = 4 //读输入寄存器
- FuncCodeReadHoldingRegisters = 3 //读保持寄存器
- FuncCodeWriteSingleRegister = 6 //写单个寄存器
- FuncCodeWriteMultipleRegisters = 16 //写多个寄存器
- FuncCodeReadWriteMultipleRegisters = 23
- FuncCodeMaskWriteRegister = 22
- FuncCodeReadFIFOQueue = 24
- FuncCodeOtherReportSlaveID = 17
- // FuncCodeDiagReadException = 7
- // FuncCodeDiagDiagnostic = 8
- // FuncCodeDiagGetComEventCnt = 11
- // FuncCodeDiagGetComEventLog = 12
- )
- // Exception Code
- const (
- ExceptionCodeIllegalFunction = 1
- ExceptionCodeIllegalDataAddress = 2
- ExceptionCodeIllegalDataValue = 3
- ExceptionCodeServerDeviceFailure = 4
- ExceptionCodeAcknowledge = 5
- ExceptionCodeServerDeviceBusy = 6
- ExceptionCodeNegativeAcknowledge = 7
- ExceptionCodeMemoryParityError = 8
- ExceptionCodeGatewayPathUnavailable = 10
- ExceptionCodeGatewayTargetDeviceFailedToRespond = 11
- )
- // ExceptionError implements error interface.
- type ExceptionError struct {
- ExceptionCode byte
- }
- // Error converts known modbus exception code to error message.
- func (e *ExceptionError) Error() string {
- var name string
- switch e.ExceptionCode {
- case ExceptionCodeIllegalFunction:
- name = "illegal function"
- case ExceptionCodeIllegalDataAddress:
- name = "illegal data address"
- case ExceptionCodeIllegalDataValue:
- name = "illegal data value"
- case ExceptionCodeServerDeviceFailure:
- name = "server device failure"
- case ExceptionCodeAcknowledge:
- name = "acknowledge"
- case ExceptionCodeServerDeviceBusy:
- name = "server device busy"
- case ExceptionCodeNegativeAcknowledge:
- name = "Negative Acknowledge"
- case ExceptionCodeMemoryParityError:
- name = "memory parity error"
- case ExceptionCodeGatewayPathUnavailable:
- name = "gateway path unavailable"
- case ExceptionCodeGatewayTargetDeviceFailedToRespond:
- name = "gateway target device failed to respond"
- default:
- name = "unknown"
- }
- return fmt.Sprintf("modbus: exception '%v' (%s)", e.ExceptionCode, name)
- }
- // CalculateResponseLength modbus RTU 响应长度
- func CalculateResponseLength(adu []byte) int {
- length := rtuAduMinSize
- switch adu[1] {
- case FuncCodeReadDiscreteInputs,
- FuncCodeReadCoils:
- count := int(binary.BigEndian.Uint16(adu[4:]))
- length += 1 + count/8
- if count%8 != 0 {
- length++
- }
- case FuncCodeReadInputRegisters,
- FuncCodeReadHoldingRegisters,
- FuncCodeReadWriteMultipleRegisters:
- count := int(binary.BigEndian.Uint16(adu[4:]))
- length += 1 + count*2
- case FuncCodeWriteSingleCoil,
- FuncCodeWriteMultipleCoils,
- FuncCodeWriteSingleRegister,
- FuncCodeWriteMultipleRegisters:
- length += 4
- case FuncCodeMaskWriteRegister:
- length += 6
- case FuncCodeReadFIFOQueue:
- // undetermined
- default:
- }
- return length
- }
|