Консультация № 187279
13.04.2013, 21:25
126.01 руб.
0 9 0
Здравствуйте, уважаемые эксперты! Мне нужно написать приложение, которое будет работать с одним периферийным устройством. Нужно через графический интерфейс путем нажатия кнопок, выставления галочек и т.п. управлять устройством и получать данные от этого устройства. Использую Qt, c++,qextserialport и arduino(контроллер atmega 328p). ОС - Windows 7. Я уже сделал так, чтобы можно посылать данные (взял пример отсюда http://www.instructables.com/id/Cont...-your-Arduino/). Примитивное зажигание светодиодов получается. Можно также получать данные с порта по желанию, с этим я тоже разобрался, но как мне засекать в программе, что в последовательном порте что-то изменилось(имеется ввиду, что устройство что-то послало в порт)? Например, я нажимаю кнопку на устройстве и светодиод гаснет, а программа должна показать, что светодиод погас. Как это можно сделать? Гугл ничего не дал пока, просматриваю документацию, но что-то не вижу нужной функции. Всем заранее спасибо

Обсуждение

давно
Академик
20764
1861
13.04.2013, 21:42
общий
В классе QextSerialPort (точнее, в QIODevice() ) есть сигнал readyRead ().
Присоединяете к нему свой слот, в нём вызываете read() и анализируете принятые данные.
Основная проблема в том, что данные будут поступать постепенно, за несколько итераций, и их надо сначала накопить.
Неизвестный
14.04.2013, 01:42
общий
14.04.2013, 01:53
Адресаты:
Попытался сделать так, как вы советовали, но реакции нет никакой. Нашел похожие примеры, многие пишут, что у них тоже не работает readReady. Причина мне не совсем понятна, но ,порывшись на англоязычных ресурсах, сложилось впечатление, будто readReady работает только для объектов QIODevice, а в объектах классов, унаследованных от QIODevice, эта функция может не работать... Многие советуют как-то использовать bytesAvailable и таймер, но пока не могу разобрать, в чем суть.

Кроме того, многие активно советуют переходить на QSerialDevice
давно
Академик
20764
1861
14.04.2013, 14:12
общий
Под Linux всё замечательно работает, но там на самом нижнем уровне используется select() или его аналог. В Windows для последовательного порта такой способ не пройдёт, так что возможно, что это вообще не работает. Тогда - только опрашивать порт по таймеру.
Неизвестный
14.04.2013, 15:50
общий
Адресаты:
"только опрашивать порт по таймеру"

Т.е. создаю таймер и раз в какое-то время вызываю функцию read?
давно
Посетитель
7438
7205
16.04.2013, 02:19
общий
А программу на это устройство Вы тоже писали?
Если да, то тогда, как вариант, можно сделать немного по-другому.
Надо сделать, чтобы инициатором обмена был компьютер, а не устройство.
И пусть компьютер периодически выдает команды либо на отработку чего-то, либо на запрос состояния.
Устройство соответственно будет либо отрабатывать команду с ответом состояния, либо просто отвечать состоянием. И тогда компьютер всегда будет в курсе состояния устройства...
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
18.04.2013, 02:22
общий
Я взял простой пример для работы с портами, а на основе его стал писать свою программу.

А это не сильно скажется на производительности? Опрашивать ведь придется часто (наверное, раз в 50мс хотя бы), чтобы компьютер сразу выдавал нужное состояние, в которое привел его пользователь. Я это сделать могу, но это уже, так сказать, не самое полноценное решение проблемы. Как минимум, на будущее бы хотелось все-таки уметь получать состояние. Тем более, в будущем может понадобиться и быстродействие.
давно
Академик
20764
1861
18.04.2013, 08:20
общий
Если не нравится производительность или время реакции - отправьте чтение из порта в отдельный тред.
давно
Посетитель
7438
7205
18.04.2013, 10:54
общий
А это не сильно скажется на производительности?
А это зависит от реализации. Как правильно указал Сергей Хватов, необходимо организовывать отдельный тред, кроме того, надо не "висеть" на чтении с порта, а использовать режим OVERLAPPED, т.е. отдать команду и ждать наступления события (не загружая процессор!).
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
20.04.2013, 00:52
общий
Решил опрашивать порт по таймеру, все работает. Всем спасибо за помощь в решении
Форма ответа