С Новым годом! Форум программистов, компьютерный форум, киберфорум
C++ Qt
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.86/58: Рейтинг темы: голосов - 58, средняя оценка - 4.86
5 / 5 / 0
Регистрация: 29.05.2011
Сообщений: 39

QSerialPort и readyRead

13.12.2013, 14:31. Показов 12394. Ответов 13
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток. Проблема состоит в том, как правильно переписать работу целого класса и при том с наименьшим переписыванием кода.
У меня был класс для работы с приборами через сом-порт. Раньше я использовал библиотеку qserialdevice v. 0.2.0 и при помощи выставления задержки setCharIntervalTimeout(), заставлял работать код примерно следующего содержания:
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
bool XModem::initConnection()
{
    asDevice->setCharIntervalTimeout(200);
    QByteArray baWrite;
    baWrite.resize(1);
    baWrite.clear();
    QByteArray baRead;
    baRead.resize(1);
    baRead.clear();
    baWrite[0] = INIT_BYTE;
    for (int i = 0; i < 3; i++) {
        asDevice->write(baWrite);
        baRead = asDevice->read(1);
    if (baRead[0].operator == (INIT)) {
            /*  Ответный инит байт есть   */
            emit portStatusChanged("Connection initialized");
            return true;
        }
    }
    emit portStatusChanged("Connection NOT initialized. Check connection settings!");
    return false;
то есть запись и чтение происходили внутри одной функции с определенным интервалом и концепция работы через сигнал readyRead отброшена. Сделано это в силу того, что отправка 1 команды в девайс представляет собой целый диалог с записью пакета и нескольких управляющих кодов, а также чтения ответов на каждый из них.

Сейчас же класс для работы с последовательными портами появился и в КуТ, но приостановки выполнения кода, до прихода сигнала readyRead там нет. И появилась идея приостанавливать код через
C++ (Qt)
1
bool    wait(QMutex * lockedMutex, unsigned long time = ULONG_MAX)
ожидать получения сигнала readyRead c ответом на команду. После чего отпирать мутекс и возобновлять поток для завершения диалога с прибором
C++ (Qt)
1
void    wakeOne()
Вопрос в том можно ли остановить главный процесс и притом дождаться сигнала readyRead для его отпирания, дабы не перегружать метод run() для отправки каждой команды и кодов?

Добавлено через 40 минут
Если не остановить, то хотя бы добавить задержку, которую можно было бы прервать при получении ответа или которая продолжала код по истечении времени.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
13.12.2013, 14:31
Ответы с готовыми решениями:

QUdpSocket readyRead
Здравствуйте, люди добрые. Уже месяц мучаюсь с одной проблемой. Пишу курсовую работу на Qt: голосовая связь по протоколу UDP....

Баг QAudioInput + readyRead
Связываю сигналом readyRead() поток из дефолтного микрофона, но сигнал не срабатывает. . Когда сам дозаписываешь методом write в...

QAbstractSocket::readyRead и winsockets
Всем привет. Есть сервер, написанный с использованием winapi. Данные он отправляет через функцию int WSAAPI send( ...

13
13.12.2013, 14:41

Не по теме:

Цитата Сообщение от Apprentice Посмотреть сообщение
Сейчас же класс для работы с последовательными портами появился и в КуТ
и в чем профит от перехода? работает - не трогай

0
5 / 5 / 0
Регистрация: 29.05.2011
Сообщений: 39
13.12.2013, 15:05  [ТС]
В версии 0.2.0 нет необходимых мне скоростей, а именно 460800 и выше. В версии 0.4.0 есть эти скорости, но толи из-за того что скорости 460800 и тд. являются enhanced speed(experimental), толи из-за того что метод setCharIntervalTimeout отрабатывает не корректно и код в итоге работает не правильно. Через сигнал readyRead ответы отлавливаются на ура и не смотря что под него придется переписывать код, необходимости в библиотеке qserialdevice больше нет.
Также использовал метод setTotalReadConstantTimeout. Эффекта не было..
0
 Аватар для RazrFalcon
1403 / 1260 / 262
Регистрация: 10.11.2013
Сообщений: 3,763
13.12.2013, 18:13
Почему бы не использовать:
waitForReadyRead(500)
?
0
5 / 5 / 0
Регистрация: 29.05.2011
Сообщений: 39
17.12.2013, 17:50  [ТС]
Я пробовал работать с waitForReadyRead(), но метод также работает не корректно. Даже если удастся считать данные в первый раз, то в цикле в последующие разы остановки не происходит, waitForReadyRead() возвращает false и дальше код отрабатывает неверно.
Немного погуглив наткнулся на американский форум:
Кликните здесь для просмотра всего текста

About QtSerialPort:
Use blocking I / O is necessary only in a separate thread.
Also have some features using the methods read() / write(). The fact is that in blocking mode, these functions do not work correctly by themselves, because do not work event-loop.
For their proper functioning is necessary to use methods such as waitForXXX (), that handle events that I / O.
Should be the following guidelines on blocking I / O:
1. After call write() need call waitForBytesWritten()
2. Before call read() need call waitForReadyRead()
At the moment, blocking I / O does not work in QtSerialPort on Windows, but the solution is available, but not yet merged to master branch.
Please use this patch:
https://codereview.qt-project.org/#change,39635
Also exists examples of the use of blocking I / O:
https://codereview.qt-project.org/#change,39343

вроде как там пофиксили баг с waitForReadyRead(), но после пересобирания библиотеки координально ни чего не изменилось. возможно я что то не так сделал или этот патч не совместим с 5.1.1
0
98 / 40 / 1
Регистрация: 08.08.2012
Сообщений: 86
17.12.2013, 18:59
подтверждаю проблемы с waitForReadyRead(), в моем случае мне проще было сменить логику работы программы
Не совсем понимаю что вы пересобрали, конкретно этот патч вы указали просто как пример, или использовали его? Потому как он довольно бородатый.

Пофиксить то пофиксили, а время от времени всплывают подобные проблемы в баг репортах
0
5 / 5 / 0
Регистрация: 29.05.2011
Сообщений: 39
18.12.2013, 14:42  [ТС]
Я подозреваю, что патч был написан для версии 5.1, тк в версии 5.1.1 довольно много расхождений, как в названиях методов, так и в полях и прочем. Потому я в сорцах QtSerialDevice 5.1.1 отредактировал методы связанные с петлей событий AbstractOverlappedEventNotifier по аналогии с сорцами патча, а также другие методы зависящие от него и добавил тех, которых там не было или были исключены в версии 5.1.1. Видимо я чего лишнего исправил, либо у меня просто руки кривые, но новые либы хоть и встали нормально, эффекта лечебного не возымели.
0
98 / 40 / 1
Регистрация: 08.08.2012
Сообщений: 86
18.12.2013, 15:02
Цитата Сообщение от Apprentice Посмотреть сообщение
Я подозреваю, что патч был написан для версии 5.1,
Этот патч датирован ноябрем 2012, 5.1 вышел в июле 2013, я подозреваю что патч был написан для Qt 4
Не могу сказать, как сделать правильно, но по-моему не так
1
5 / 5 / 0
Регистрация: 29.05.2011
Сообщений: 39
18.12.2013, 15:52  [ТС]
Лол, действительно) Что ж вышла 5.2.0 попробую на ней пересобрать. Посмотрим, что выйдет..
0
42 / 40 / 7
Регистрация: 21.05.2012
Сообщений: 199
18.12.2013, 17:22
Этот патч не был применен, поэтому этот баг еще не исправлен.
0
5 / 5 / 0
Регистрация: 29.05.2011
Сообщений: 39
20.12.2013, 01:07  [ТС]
В конечном итоге после долгих плясок с бубном, мансований кода и перекомпилирования проекта получилось запустить код на waitForReadyRead() и waitForBytesWritten() не коннектя сигнал readyRead(). Только для получения стабильности пришлось поиграться с задержкой при чтении и записи.
Собственно, использовал конструкцию как написано в гайде:
Цитата Сообщение от Apprentice Посмотреть сообщение
1. After call write() need call waitForBytesWritten()
2. Before call read() need call waitForReadyRead()
0
98 / 40 / 1
Регистрация: 08.08.2012
Сообщений: 86
20.12.2013, 10:32
Таки требую подробностей
Версия Qt? Что там с патчами, ставили/не ставили?
Код типа такого?

C++ (Qt)
1
2
3
4
serialPort.write(someData);
serialPort.waitForBytesWritten();
serialPort.waitForReadyRead();
responce = serialPort.readAll();
0
42 / 40 / 7
Регистрация: 21.05.2012
Сообщений: 199
20.12.2013, 11:15
Цитата Сообщение от k0ndaa Посмотреть сообщение
Таки требую подробностей
Версия Qt? Что там с патчами, ставили/не ставили?
Еще раз повторяю, баг: https://bugreports.qt-project.... TBUG-33987
не был исправлен.

Но может быть, чудесным образом, он уже самоисправился.

Попробуйте собрать версию QtSeriaPort из Git, как описано в Вики: http://qt-project.org/wiki/QtSerialPort_Russian

PS: Но в любом случае вызов методов waitForXXX() необходим как воздух, и это не баг - так надо.
Кроме того, я рекомендовал бы отказаться вообще от синхронного подхода и переписать код с использованием сигналов/слотов, т.к. это надежнее, проще и т.д.
0
5 / 5 / 0
Регистрация: 29.05.2011
Сообщений: 39
20.12.2013, 14:12  [ТС]
Собрал на Qt5.1.1 в MSVC2010 SP1 x32. Патч убрал, тк сомневался в его совместимости с текущей либой.
Для скорости 460800 на запись и чтение ставил задержку в 50мс для пакетов длиной ~ 130 байт.
C++ (Qt)
1
2
3
4
    asDevice->write(baRequest);
    asDevice->waitForBytesWritten(50);
    asDevice->waitForReadyRead(50);
    baAnswer = asDevice->readAll();
Также очень помогла отладка уже в релизе через qDebug(), поскольку ни какие точки остановки и дебажные либы не вносили задержек.

Цитата Сообщение от kuzulis Посмотреть сообщение
Но может быть, чудесным образом, он уже самоисправился.
При упорном использовании такого древнего и магического предмета как бубен можно даже самый безнадежный код поднять на ноги


Цитата Сообщение от kuzulis Посмотреть сообщение
Кроме того, я рекомендовал бы отказаться вообще от синхронного подхода и переписать код с использованием сигналов/слотов, т.к. это надежнее, проще и т.д.
На счет надежности полностью согласен, да и необходимость рассчитывать задержки в зависимости от скорости пропадает, но этот метод подходит для простых запросов и ответов, а если необходимо реализовывать диалог модемом, то для обработки ответов и последующих кодов для завершения протокола передачи от разных команд в разы усложняет написание обработчика сигнала readyRead(). Имхо, в таком случае понятнее будет синхронная реализация.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
20.12.2013, 14:12
Помогаю со студенческими работами здесь

Не работает QTcpSocket::readyRead
имеется рабочий ftp клиент и необходимо написать ftp сервер при подключении к серверу клиента void Server::incomingConnection(int...

Сигнал readyRead не запускает слот
Привет! У меня относительно большой девайс (два компа, соединенные по ком порту). Данные с одного компьютера передаются на другой...

QUdpSocket::readyRead() не работает в openSUSE 42.3
Перестал работать QUdpSocket::readyRead().. В Windows 7(64bit) работает, в openSUSE 42.3 нет. Версия Qt 5.10.1 В Wireshark запрос и ответ...

ReadyRead будит поток с задержкой?
Работаем с COM-портами... есть линия на которой висит 6 клиентов и один запросчик... запросчик опрашивает клиентов по очереди, а они ему...

Dll + QTcpSocket + signal readyRead()
Доброго времени суток! Столкнулся со следующей проблемой! Создаю клиент-серверное приложение, работа с сетью осуществляется по...


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

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Old Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru