Сигнал readyRead() QextSerialPort (QIODevice) вызывается недостаточно быстро

Я использую qextserialport на Raspberry Pi для связи с PanStamp (устройство, совместимое с Arduino).

Этот PanStamp, подключенный к Pi, выполняет две функции:

  • Каждую секунду отправлять показания датчика (около 12 байт);
  • Отправлять все данные, которые он получает, через беспроводную связь (около 60 байт примерно 6 раз в секунду).

Моя архитектура:

  • Хаб: PanStamp + Raspberry Pi;
  • Спутник: PanStamp + несколько датчиков.

Есть две ситуации:

  • Спутник по беспроводной передаче данных на концентратор. В этой ситуации Pi получает много данных через последовательный порт каждую секунду;
  • Спутник отключен, Pi получает около 12 байт каждую секунду через последовательный порт.

Когда спутник выключен, сигнал readyRead() не генерируется каждый раз, когда поступает байт, и он приводит мою программу в состояние «рассинхронизации», когда для каждого прочитанного пакета данных один или несколько остаются в буфере (который продолжает расти).

Однако, когда я включаю спутник и Pi начинает получать много данных, это состояние «рассинхронизации» исчезает, происходит всплеск данных (буфер растет быстрее и после этого очищается), и моя программа начинает работать «в реального времени».

Вот пример вывода моей программы: www.tiago.eti.br/storage/iSEDE. журнал

Как вы можете видеть в журнале, количество доступных байтов продолжает расти, и данные отправляются каждую секунду (строка, начинающаяся с HUB:, не обрабатывается каждую секунду. В начале есть отметка времени). Через некоторое время происходит всплеск (включен спутник) и каждую секунду обрабатывается много данных, начинают обрабатываться данные со спутника (строки, начинающиеся с 8), буфер очищается и моя программа начинает обработку данных в реальном времени".

Итак, что я могу сделать, чтобы избежать чрезмерного роста буфера и не потерять данные? Я попытался вызвать функцию, связанную с readyRead(), когда буфер стал больше 100 байт, но это создало беспорядок, и я начал терять некоторые пакеты.


person Tiago Queiroz    schedule 06.08.2013    source источник
comment
Пожалуйста, опубликуйте код, особенно то, что вы написали для чтения из файла QIODevice.   -  person RA.    schedule 06.08.2013
comment
Есть ли причина, по которой вы не используете QtSerialPort?   -  person lpapp    schedule 27.09.2013
comment
Да, когда я впервые использовал последовательный порт (несколько лет назад) с Qt, QtSerialPort был недоступен, поэтому я использовал то, что уже знал.   -  person Tiago Queiroz    schedule 30.09.2013


Ответы (1)


Ваша проблема заключается в наиболее распространенной ошибке, которую люди совершают с QIODevice. Вы ошибочно предполагаете, что readyRead вызывается для каждого байта, говоря больше, было бы совершенно неправильно, если бы это работало так. Идея состоит в том, что каждый раз, когда вы получаете readyRead, есть ЧТО-ТО для чтения с устройства.. это может быть 1 байт, 10 байт, 1k.. и т.д.. Проще говоря, это делается так, чтобы минимизировать Загрузка ЦП в случае блочной передачи, а также на аппаратном уровне для чтения данных в блоках, а не в байтах.

Итак, что вам нужно сделать, так это вызвать readAll(), чтобы получить все доступные данные, которые поступили, и обработать их так, как вам нравится.

вы можете посмотреть здесь. .

person evilruff    schedule 06.08.2013