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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: [Решено] Qt modbus sendReadRequest в цикле  (Прочитано 5578 раз)
solns
Новичок

Offline Offline

Сообщений: 2


Просмотр профиля
« : Декабрь 26, 2017, 13:42 »

Добрый день.
Для своей программы взял за основу пример
serialbus\modbus\master\master.pro из (QT 5.8, Win, mingw53_32)

Отличие : sendReadRequest вызывается в цикле, в примере - по кнопке.
Код сильно упрощен для вопроса, но рабочий.

В теле цикла я ожидаю и результаты запроса  ("replay Finished").
Однако, результаты (абсолютно все) появятся только после завершения цикла ("end readModbus")
Как будто запросы ставятся в очередь, и она запускается только после окончания цикла.
Данные modbus читаются нормально, здесь не приведено.
Код:
...
  modbusDevice = new QModbusRtuSerialMaster(this);
...
  readDataUnit  = new QModbusDataUnit(QModbusDataUnit::HoldingRegisters, mbCnf.holdingRead,  mbCnf.holdingReadLen);
  MainWindow::readModbus();
...
void MainWindow::readModbus() {
  for(int i = 1; i <= 1000; i++) {
     if(!modbusDevice) return;
     auto *readReply = modbusDevice->sendReadRequest(* readDataUnit, mbCnf.serverAddr);
     if(readReply) {
        if(!readReply->isFinished()) {
           qInfo() << "Connect readReady";
           connect(readReply, &QModbusReply::finished,
                   this,      [=] { qInfo() << "replay Finished"; }
           );  //, Qt::DirectConnection); - не помогает
        }
        else delete readReply;  
     }
     else qInfo() << tr("Read error: %1").arg(modbusDevice->errorString());
     qApp->processEvents();  // не помогает
     Sleeper::msleep(30);    // тем более
  }
  qInfo() << "end readModbus";
}
Голову сломал.  Почему так?
« Последнее редактирование: Декабрь 27, 2017, 15:38 от solns » Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #1 : Декабрь 26, 2017, 15:18 »

А в чем собственно то проблема? Все репли выполняются асинхронно ( и да, ставятся в очередь, а как иначе?). С чего взято утверждение, что результаты будут в теле цикла?  Реально работа начнется после выхода из MainWindow::readModbus().
Записан

ArchLinux x86_64 / Win10 64 bit
solns
Новичок

Offline Offline

Сообщений: 2


Просмотр профиля
« Ответ #2 : Декабрь 27, 2017, 12:51 »

Спасибо за подсказку (объяснение).
Убрал цикл в readModbus и заставил работать event loop.
Для начала так:
Код:
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(readModbus()));
timer->start(100);
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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