Russian Qt Forum
Ноябрь 25, 2024, 14:00 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Modbus RTU. Запись в modbus регистр.  (Прочитано 4131 раз)
bv7
Новичок

Offline Offline

Сообщений: 3


Просмотр профиля
« : Февраль 24, 2023, 17:58 »

Доброго всем времени суток.
qt5.15
Из приложения должен формироваться запрос — "01 06 00 00 00 05 49 C9", по факту же формируется "00 06 00 00 00 00 88 1B". Пробовал вместо spinBox->value() прописывать другие значения, например 100 или 5, все равно в запросе отправляется 0, судя по трафику. Т.к. реального контроллера нет все эксперименты провожу на виртуальных com портах. Виртуальные порты работают корректно, т.к. mobusPull и modbusSlave данные передают нормально. В чем причина? Как исправить?
Запись в регистр:
Код:
void MainWindow::write_registr(int num_device, int reg, quint16 data){
    if (!modbusDevice) return;
    QModbusDataUnit writeUnit;
    writeUnit.setRegisterType(QModbusDataUnit::HoldingRegisters);
    writeUnit.setStartAddress(reg);
    writeUnit.setValueCount(1);
    writeUnit.setValue(0,data);
    if (QModbusReply *lastRequest = modbusDevice->sendWriteRequest(writeUnit, num_device)){
        if(!lastRequest->isFinished()){
        connect(lastRequest, &QModbusReply::finished, this, [=](){
            if(lastRequest->error() == QModbusDevice::ProtocolError){
    //ошибка протокола
                ui->statusBar->showMessage("Ошибка протокола");
            }else if(lastRequest->error() == QModbusDevice::TimeoutError){
    //превышено время ожидания
                ui->statusBar->showMessage("Превышено время ожидания", 5000);
            }else if (lastRequest->error() != QModbusDevice::NoError){
    //прочие ошибки
                    ui->statusBar->showMessage("Ошибка");
                }else if(lastRequest->error() == QModbusDevice::NoError){
    //успешно
                ui->statusBar->showMessage("Успешно",5000);
                };
            lastRequest->deleteLater();
        });
        } else lastRequest->deleteLater();
    } else {
    //ошибка записи
        ui->statusBar->showMessage("Ошибка записи", 5000);
    };
};
    //Примечание: write_registr функция для записи регистра
Вызов функции записи:
Код:
void MainWindow::on_pushButton_write_clicked()
{
    write_registr(ui->spinBox_reg->value(), ui->spinBox_reg->value(), ui->spinBox_writedata->value());
}
Во вложении проект приложения
Записан
sergek
Гипер активный житель
*****
Offline Offline

Сообщений: 872


Мы должны приносить пользу людям.


Просмотр профиля
« Ответ #1 : Февраль 24, 2023, 20:10 »

Ошибка здесь:
Код:
    if (QModbusReply *lastRequest = modbusDevice->sendWriteRequest(writeUnit, num_device)){
Надо исправить на:
Код
C++ (Qt)
   QModbusReply *lastRequest = modbusDevice->sendWriteRequest(writeUnit, num_device);
   if (lastRequest){
 
То же самое и в read_registr.
Записан

Qt 5.13.0 Qt Creator 5.0.1
Win10, Ubuntu 20.04
bv7
Новичок

Offline Offline

Сообщений: 3


Просмотр профиля
« Ответ #2 : Февраль 25, 2023, 11:26 »

Ошибка здесь:
Код:
    if (QModbusReply *lastRequest = modbusDevice->sendWriteRequest(writeUnit, num_device)){

Надо исправить на:
Код
C++ (Qt)
   QModbusReply *lastRequest = modbusDevice->sendWriteRequest(writeUnit, num_device);
   if (lastRequest){
 
То же самое и в read_registr.

Спасибо, но не помогло Грустный должен отправлять 01 06 00 01 00 05 18 09. А отправляет 01 06 00 01 00 00 D8 0A
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #3 : Февраль 25, 2023, 15:27 »

Ошибка здесь:
Код:
    if (QModbusReply *lastRequest = modbusDevice->sendWriteRequest(writeUnit, num_device)){
Надо исправить на:
Код
C++ (Qt)
   QModbusReply *lastRequest = modbusDevice->sendWriteRequest(writeUnit, num_device);
   if (lastRequest){
 
То же самое и в read_registr.
и в чем тут ошибка? Улыбающийся
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #4 : Февраль 25, 2023, 15:29 »

я не знаю что такое Modbus, но случайно нет ошибки в on_pushButton_write_clicked()? в функцию подается одно и то же значение (ui->spinBox_reg->value()) в двух разных параметрах
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
sergek
Гипер активный житель
*****
Offline Offline

Сообщений: 872


Мы должны приносить пользу людям.


Просмотр профиля
« Ответ #5 : Февраль 25, 2023, 16:28 »

и в чем тут ошибка? Улыбающийся
Согласен, был не прав, погорячился))
Записан

Qt 5.13.0 Qt Creator 5.0.1
Win10, Ubuntu 20.04
sergek
Гипер активный житель
*****
Offline Offline

Сообщений: 872


Мы должны приносить пользу людям.


Просмотр профиля
« Ответ #6 : Февраль 25, 2023, 17:21 »

Спасибо, но не помогло Грустный должен отправлять 01 06 00 01 00 05 18 09. А отправляет 01 06 00 01 00 00 D8 0A
Это из-за особенности (или ошибки?) QModbusDataUnit, фрагмент
Код
C++ (Qt)
   QModbusDataUnit writeUnit;
   writeUnit.setRegisterType(QModbusDataUnit::HoldingRegisters);
   writeUnit.setStartAddress(reg);
   writeUnit.setValueCount(1);
   writeUnit.setValue(0,data);
Нужно заменить на
Код
C++ (Qt)
   QModbusDataUnit writeUnit(QModbusDataUnit::HoldingRegisters, reg, 1);
   writeUnit.setValue(0,data);
 
Почему так, не вникал, но можете почитать здесь: https://forum.qt.io/topic/90552/qmodbusdataunit-bug/4

Еще есть ошибка в слоте on_pushButton_write_clicked (там у вас вместо адреса устройства передается стартовый регистр). Нужно
Код
C++ (Qt)
void MainWindow::on_pushButton_write_clicked()
{
   write_registr(ui->spinBox_addr->value(), ui->spinBox_reg->value(), ui->spinBox_writedata->value());//ui->spinBox_writedata->value()
}
 

Записан

Qt 5.13.0 Qt Creator 5.0.1
Win10, Ubuntu 20.04
bv7
Новичок

Offline Offline

Сообщений: 3


Просмотр профиля
« Ответ #7 : Февраль 26, 2023, 08:55 »

Это из-за особенности (или ошибки?) QModbusDataUnit, фрагмент
Код
C++ (Qt)
   QModbusDataUnit writeUnit;
   writeUnit.setRegisterType(QModbusDataUnit::HoldingRegisters);
   writeUnit.setStartAddress(reg);
   writeUnit.setValueCount(1);
   writeUnit.setValue(0,data);
Нужно заменить на
Код
C++ (Qt)
   QModbusDataUnit writeUnit(QModbusDataUnit::HoldingRegisters, reg, 1);
   writeUnit.setValue(0,data);
 
Почему так, не вникал, но можете почитать здесь: https://forum.qt.io/topic/90552/qmodbusdataunit-bug/4

Еще есть ошибка в слоте on_pushButton_write_clicked (там у вас вместо адреса устройства передается стартовый регистр). Нужно
Код
C++ (Qt)
void MainWindow::on_pushButton_write_clicked()
{
   write_registr(ui->spinBox_addr->value(), ui->spinBox_reg->value(), ui->spinBox_writedata->value());//ui->spinBox_writedata->value()
}
 
1. Сделал по аналогии как с подключением к порту, но видимо не все подход одинаково полезны.
Код:
...
modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter,port_name);
modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter,parity);
...
2. Похоже глаз замылился, не заметил, что передаю не то. Оно скомпилировалось, ошибок нет. А вот данные не те.

В справке qt посмотрел, есть у класса QModbusDataUnit несколько конструкторов, буду внимательнее.
Спасибо за помощь. Теперь все работает,  как и положено.

P.S. говорила мама, читай инструкцию, а я все методом тыка. Вот и натыкал.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.315 секунд. Запросов: 23.