Не получается опросить прибор ТРМ138 по протоколу modbus RTU через rs485

Скомпилировал программу для опроса прибора хоть какого-то регистра, что бы получить хоть какой то ответ. Но в консоль выводится "ожидание ответа прибора". Я так понимаю проблема в самой команде modbus? Вот код:

    #include <iostream>
#include <windows.h>
#include <vector>
#include <iomanip>
#include <fstream>
#include <locale>

// Функция для открытия последовательного порта
HANDLE openSerialPort(const std::string& portName, int baudRate, int byteSize, int stopBits, int parity) {
    HANDLE hSerial = CreateFile(portName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
    if (hSerial == INVALID_HANDLE_VALUE) {
        std::wcerr << L"Ошибка открытия порта: " << GetLastError() << std::endl;
        return INVALID_HANDLE_VALUE;
    }

    DCB dcbSerialParams = {0};
    dcbSerialParams.DCBlength = sizeof(dcbSerialParams);

    if (!GetCommState(hSerial, &dcbSerialParams)) {
        std::wcerr << L"Ошибка получения состояния порта: " << GetLastError() << std::endl;
        CloseHandle(hSerial);
        return INVALID_HANDLE_VALUE;
    }

    dcbSerialParams.BaudRate = baudRate;
    dcbSerialParams.ByteSize = byteSize;
    dcbSerialParams.StopBits = stopBits;
    dcbSerialParams.Parity = parity;

    if (!SetCommState(hSerial, &dcbSerialParams)) {
        std::wcerr << L"Ошибка установки параметров порта: " << GetLastError() << std::endl;
        CloseHandle(hSerial);
        return INVALID_HANDLE_VALUE;
    }

    return hSerial;
}

// Функция для отправки команды на устройство
bool sendCommand(HANDLE hSerial, const std::vector<uint8_t>& command) {
    DWORD bytesWritten;
    if (!WriteFile(hSerial, command.data(), command.size(), &bytesWritten, NULL)) {
        std::wcerr << L"Ошибка отправки команды: " << GetLastError() << std::endl;
        return false;
    }
    return bytesWritten == command.size();
}

// Функция для чтения ответа от устройства
std::vector<uint8_t> readResponse(HANDLE hSerial, size_t expectedSize) {
    std::vector<uint8_t> response(expectedSize);
    DWORD bytesRead;
    if (!ReadFile(hSerial, response.data(), expectedSize, &bytesRead, NULL)) {
        std::wcerr << L"Ошибка чтения ответа: " << GetLastError() << std::endl;
        return {};
    }
    response.resize(bytesRead);
    return response;
}

// Функция для вычисления контрольной суммы CRC
uint16_t calculateCRC(const std::vector<uint8_t>& data) {
    uint16_t crc = 0xFFFF;
    for (size_t i = 0; i < data.size(); i++) {
        crc ^= data[i];
        for (int j = 0; j < 8; j++) {
            if (crc & 1)
                crc = (crc >> 1) ^ 0xA001;
            else
                crc >>= 1;
        }
    }
    return crc;
}

// Функция для записи ответа в файл
void logResponse(const std::vector<uint8_t>& response, const std::string& filename) {
    std::ofstream file(filename);
    if (file.is_open()) {
        for (const auto& byte : response) {
            file << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(byte) << " ";
        }
        file.close();
    } else {
        std::wcerr << L"Не удалось открыть файл для записи: " << std::wstring(filename.begin(), filename.end()) << std::endl;
    }
}

int main() {
    setlocale(LC_ALL, "Russian");
    std::wcout.imbue(std::locale(""));

    const std::string portName = "COM6";
    int baudRate = 9600;
    int byteSize = 8;
    int stopBits = ONESTOPBIT;
    int parity = NOPARITY;
    uint8_t deviceAddress = 0x01; // Адрес устройства
    uint16_t registerAddress = 0x0000; // Адрес регистра для чтения
    const std::string logFilename = "modbus_log.txt";

    std::wcout << L"Открытие порта " << std::wstring(portName.begin(), portName.end()) << L"..." << std::endl;
    HANDLE hSerial = openSerialPort(portName, baudRate, byteSize, stopBits, parity);
    if (hSerial == INVALID_HANDLE_VALUE) {
        std::wcerr << L"Не удалось подключиться к порту " << std::wstring(portName.begin(), portName.end()) << std::endl;
        system("pause");
        return 1;
    }

    std::wcout << L"Порт открыт успешно." << std::endl;

    // Формирование команды на чтение регистра
    std::wcout << L"Формирование команды для чтения регистра..." << std::endl;
    std::vector<uint8_t> command = {deviceAddress, 0x03, static_cast<uint8_t>(registerAddress >> 8), static_cast<uint8_t>(registerAddress & 0xFF), 0x00, 0x01};
    uint16_t crc = calculateCRC(command);
    command.push_back(crc & 0xFF);
    command.push_back((crc >> 8) & 0xFF);

    std::wcout << L"Отправка команды на устройство..." << std::endl;
    if (!sendCommand(hSerial, command)) {
        std::wcerr << L"Не удалось отправить команду." << std::endl;
        CloseHandle(hSerial);
        system("pause");
        return 1;
    }

    std::wcout << L"Команда отправлена успешно." << std::endl;

    // Ожидание ответа от устройства
    std::wcout << L"Ожидание ответа от устройства..." << std::endl;
    std::vector<uint8_t> response = readResponse(hSerial, 7);
    if (response.empty()) {
        std::wcerr << L"Не удалось получить ответ от устройства." << std::endl;
        CloseHandle(hSerial);
        system("pause");
        return 1;
    }

    std::wcout << L"Ответ получен: ";
    for (uint8_t byte : response) {
        std::wcout << std::hex << std::setw(2) << std::setfill(L'0') << static_cast<int>(byte) << L" ";
    }
    std::wcout << std::endl;

    std::wcout << L"Запись ответа в файл..." << std::endl;
    logResponse(response, logFilename);
    std::wcout << L"Ответ сохранен в файл: " << std::wstring(logFilename.begin(), logFilename.end()) << std::endl;

    CloseHandle(hSerial);
    std::wcout << L"Завершение работы программы." << std::endl;
    system("pause");
    return 0;
}

У меня вопрос, причина того что прибор не отвечает на мои команды в том что команды не корректны? Что получается лучше использовать библиотеку modbus? Но она же будет делать тоже самое? Или она в автомате сможет найти нужный подход к прибору? К слову прибор отлично опрашивается программой конфигуратор от завода изготовителя.

Вот какие настройки в приборе для обмена: Скорость обмена 9600 Длина слова данных 8 бит Контроль по чётности отсутствует Количество стоп битов в посылке 1 Длина сетевого адреса 8 бит. Базовый адрес прибора 0 Количество фильтров сообщений 0 Протокол выставил modbus RTU

введите сюда описание изображения


Ответы (0 шт):