Форум программистов, компьютерный форум, киберфорум
Кроссплатформенная разработка
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.62/21: Рейтинг темы: голосов - 21, средняя оценка - 4.62
0 / 0 / 0
Регистрация: 22.06.2016
Сообщений: 4
1

QT - Modbus

02.08.2018, 12:02. Показов 4305. Ответов 2

Добрый день форумчане. Необходима работа с пользовательскими командами протокола Modbus (например 11), и другими стандартными функциями (например read holding registers). Для этих целей использую встроенный класс QModbusClient. Для отладки использую программу AccessPort, и всё происходит на платформе windows 7. Мой код отправляет команду 11 на слейв устройство с каким то номером, и получает ожидаемый корректный ответ, но полученные данные через QModbusDataUnit показывает что данные отсутствуют и длинна сообщения 0. Похожая проблема есть в баг репорте https://bugreports.qt.io/browse/QTBUG-62192, но проблема в том что в ответном сообщении нету данных (по мнению либы). Вот код:

C++ (Qt)
1
2
3
4
5
6
7
8
9
CommandBlockInformation::CommandBlockInformation()
{
    QModbusResponse::registerDataSizeCalculator(
                QModbusPdu::FunctionCode(0x11),
                [](const QModbusResponse &pdu)->int {
        QByteArray data = pdu.data();
        return data.size() > 0 ? data[0]: -1;
        });
}
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
QModbusReply* CommandBlockInformation::execute(IConnector *connector, QByteArray data)
    {
        QModbusRequest request(QModbusPdu::FunctionCode::ReportServerId, data);
        QModbusReply *reply = connector->SendCommand(request);
        
        QTimer timer;
        timer.setSingleShot(true);
        QEventLoop loop;
        connect(reply,  SIGNAL(finished()), &loop, SLOT(quit()));
        connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
        timer.start(finishedWait);
        loop.exec(QEventLoop::AllEvents);
        
        connID = connector->GetID();
        
        return reply;
    }
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
QVector<QString> CommandBlockInformation::parse(QModbusReply *reply)
    {
        QVector<QString> result;
        
        const QModbusDataUnit dataUnit = reply->result();
        
        if(dataUnit.valueCount() == 0)
        {
            emit CommandError("Err");
            return result;
        }
        
        result << QString::number(connID);
        for (uint i = 0; i < dataUnit.valueCount(); i++)
        {
            result << QString::number(dataUnit.value(i));
        }
        
        return result;
    }
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
SerialConnector::SerialConnector(QString PortName, qint32 BaudRate, QSerialPort::DataBits DataBits, QSerialPort::StopBits StopBits, QSerialPort::Parity Parity, int Device_address, int RepeatCount, int Timeout) :
    Serial_Provider(new QModbusRtuSerialMaster(this))
{
    Serial_Provider->setConnectionParameter(QModbusDevice::SerialPortNameParameter, PortName);
    Serial_Provider->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, BaudRate);
    Serial_Provider->setConnectionParameter(QModbusDevice::SerialDataBitsParameter, DataBits);
    Serial_Provider->setConnectionParameter(QModbusDevice::SerialStopBitsParameter, StopBits);
    Serial_Provider->setConnectionParameter(QModbusDevice::SerialParityParameter, Parity);
    SlaveID = Device_address;
    Serial_Provider->setNumberOfRetries(RepeatCount);
    Serial_Provider->setTimeout(Timeout);
 
    connect(Serial_Provider, SIGNAL(stateChanged(QModbusDevice::State)), this, SLOT(catcherStateChanged(QModbusDevice::State)));
}
C++ (Qt)
1
2
3
4
QModbusReply* SerialConnector::SendCommand(QModbusRequest request)
{
    return Serial_Provider->sendRawRequest(request, SlaveID);
}
Добавлено через 2 часа 32 минуты
Цитата Сообщение от Forsage0375 Посмотреть сообщение
проблема в том что в ответном сообщении нету данных (по мнению либы)
И в качестве ошибки reply->errorString() возвращает Response timeout
__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
02.08.2018, 12:02
Ответы с готовыми решениями:

Modbus-сервер
Здравствуйте)Задали в универе выполнить такое задание: Необходимо с датчиков/приборов по протоколу...

C++ modbus
Здравствуйте! Задача вообщем такая. Есть параметры, передаваемые с метанольного цеха диспетчеру по...

Modbus master
Добрый день . Пишу программу для общения по протоколу Modbus. Формирую команду, отсылаю ее,жду...

Подключение библиотеки modbus в C++
Доброго времени суток! Самостоятельно с нуля учусь программированию на С++. Решил опросить по...

2
0 / 0 / 0
Регистрация: 22.06.2016
Сообщений: 4
03.08.2018, 15:14  [ТС] 2
Код взят из qt example, добавлена кнопка Func и она приводит к данной ошибке, запрос корректен, ответ приходит, modbus error: Response timeout
Вложения
Тип файла: rar ModbusExample.rar (91.1 Кб, 16 просмотров)
0
0 / 0 / 0
Регистрация: 22.06.2016
Сообщений: 4
14.08.2018, 09:31  [ТС] 3
Причину удалось установить, в файле исходных кодов qmodbusrtuserialmaster_p.h, есть строка
C++ (Qt)
1
int pduSizeWithoutFcode = QModbusResponse::calculateDataSize(tmpAdu.pdu());
Если задать калькулятор не правильно рассчитывающий длину ответа, то сверка будет происходить с первым считываемым куском байт (ошибка не верного расчёта crc). В моём случае помог возврат статичной ожидаемой длинны ответа
C++ (Qt)
1
2
3
4
5
6
    
QModbusResponse::registerDataSizeCalculator(
                QModbusPdu::FunctionCode(0x11),
                [](const QModbusResponse &pdu)->int {
        return 6;
        });
Для тестовой программы приведённой выше все заработало, но для боевой появилась другая проблема:
Ответ приходит и считывается полностью, но статус при этом не соответствует статусу приема
C++ (Qt)
1
2
3
            
if (m_state != State::Receive)
                return;
И готовое сообщение не приходит, возвращает всё ту же ошибку "(RTU client) Receive timeout:"
Вложения
Тип файла: rar qmodbusrtuserialmaster_p.rar (4.2 Кб, 23 просмотров)
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
14.08.2018, 09:31

Qt и протокол modbus Ascii
Здравствуйте. такой вопрос: есть прибор, работающий по протоколу modbus Ascii. с помощью matlab...

Modbus из Pascal в C++ Builder 5
помогите вот это переписать в С++ Builder 5, и если есть возможность исходник и откомпилированая...

Qt Modbus ответ сервера по TCP
Приветствую! Есть готовая программа клиент для опроса инвертора по протоколу ModBus через RTU,...

Реализация протокола ModBus RTU на Qt
Всем доброго время суток. Недавно начал осваивать программирование на Qt. Стоит тривиальная задача...

MODBUS-TCP обмен данными
Моё простенькое чудо-приложение должно принимать/посылать данные от/на внешнее устройство. Внешнее...

Как правильно создать ModBus ASCII запрос?
Адрес - 26 Код функции 03h начало - 0000 Количество -0004 расчет LRC char calculateLRC(...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru