Всем доброго времени суток.
Делаю 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