Всем доброго времени суток.
Делаю Modbus RTU клиента для опроса одного устройства.
В терминале видно, что программа шлет запрос, но ответ от устройства не совсем то что нужно.
Кое что взял со сторонних форумов.
Где что упустил - поправьте пожалуйста:
; Настройки Modbus
Define deviceAddress.b = 6
Define registerStart.b = 0 ; Начальный Holding Register
Define registerCount.b = 10 ; Количество Holding Registers для опроса
; Настройки COM-порта
#ComPort = 1; Идентификатор COM порта
Define baudRate.b = 9600 ; Скорость передачи данных
Define parity.b = 0 ; Четность: 0 - нет, 1 - нечетность, 2 - четность
Define dataBits.b = 8 ; Количество бит данных
Define stopBits.b = 1 ; Количество стоп-битов
; Функция расчета CRC-16
Procedure.i CalculateCRC(buffer, length)
Define.i crc = $FFFF
Define.i i, j
For i = 0 To length - 1
crc = crc ! PeekB(buffer + i) ; Используем оператор XOR (!)
For j = 0 To 7
If (crc & $0001) <> 0
crc = (crc >> 1) ! $A001
Else
crc = crc >> 1
EndIf
Next
Next
ProcedureReturn crc
EndProcedure
; Инициализация COM-порта
;If OpenSerialPort(comPort, "COM1", baudRate, parity, dataBits, stopBits)
If OpenSerialPort(#ComPort, "COM1", baudRate, parity, 8, stopBits, #PB_SerialPort_NoHandshake, 255, 255)
; Отправка запроса на чтение Holding Registers
Define requestSize.b = 8
Define responseSize.b = 50
Dim requestBuffer.b(requestSize)
Dim responseBuffer.b(responseSize)
; Создание запроса (Формат: [Адрес устройства] [Функция] [Начальный регистр] [Количество регистров])
requestBuffer(0) = deviceAddress
requestBuffer(1) = 3 ; Функция "Чтение Holding Registers"
PokeW(@requestBuffer(2), registerStart) ; Начальный регистр
PokeW(@requestBuffer(4), registerCount) ; Количество регистров
; Рассчитать CRC
Define crc = CalculateCRC(@requestBuffer(0), requestSize - 2)
PokeW(@requestBuffer(requestSize - 2), crc) ; CRC-16
; Отправка запроса
WriteSerialPortData(#ComPort, @requestBuffer(0), requestSize)
; Ожидание ответа
If ReadSerialPortData(#ComPort, @responseBuffer(0), responseSize) >0
; Проверка CRC
If CalculateCRC(@responseBuffer(0), responseSize - 2) = PeekW(@responseBuffer(responseSize - 2))
; Обработка ответа
For i = 0 To registerCount - 1
Define registerValue = PeekW(@responseBuffer(3 + i * 2))
Debug "Register " + Str(i) + ": " + Str(registerValue)
Next
Else
Debug "CRC Check Failed"
EndIf
Else
Debug "No Response from Device"
EndIf
CloseSerialPort(comPort)
Else
Debug "Failed to Open Serial Port"
EndIf