Название: [Решено] Qt modbus sendReadRequest в цикле Отправлено: solns от Декабрь 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"; } Название: Re: Qt modbus sendReadRequest в цикле Отправлено: kuzulis от Декабрь 26, 2017, 15:18 А в чем собственно то проблема? Все репли выполняются асинхронно ( и да, ставятся в очередь, а как иначе?). С чего взято утверждение, что результаты будут в теле цикла? Реально работа начнется после выхода из MainWindow::readModbus().
Название: Re: Qt modbus sendReadRequest в цикле Отправлено: solns от Декабрь 27, 2017, 12:51 Спасибо за подсказку (объяснение).
Убрал цикл в readModbus и заставил работать event loop. Для начала так: Код: QTimer *timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(readModbus())); timer->start(100); |