crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

> Чтение из порта при помощи QSerialPort
borune
  опции профиля:
сообщение 20.11.2015, 16:04
Сообщение #1


Участник
**

Группа: Участник
Сообщений: 152
Регистрация: 1.1.2011
Пользователь №: 2314

Спасибо сказали: 0 раз(а)




Репутация:   0  


День добрый, господа.

Вопрос такой. Есть порт с перемычкой между TxD и RxD. Пишу в порт данные и читаю их же. Использую QtSerialPort в полной аналогии с примером (terminal example). Проблема заключается в чтении данных. Есть слот, приконнекченный к сигналу readyRead() объекта. Когда в порте появляются данные, этот слот вызывается всякий раз, когда размер этих данных равен 8 Байтам. Например, если размер считываемых данных составляет 14 Байт, слот вызывается 2 раза, если 27 Байт - 4 раза, 248 Байт - 31 раз. Т.е. порт ведет себя так, как будто бы размер буфера равен 8. Суть проблемы в том, что из-за вышеперечисленного невозможно отследить момент, когда все доступные данные считаны из порта:
Раскрывающийся текст
MainWindow::MainWindow(QWidget *parent) :    QMainWindow(parent)
{
       ...
       serial = new QSerialPort(this);
       serial->setReadBufferSize(0);
       connect(serial, SIGNAL(readyRead()), SLOT(readData()));
       ...
}
void MainWindow::readData()
{    
    port_data.append(serial->readAll());
    if(serial->bytesAvailable()==0){
      // здесь должна быть обработка всех полученных данных      
    }
}
При каждом вызове слота readData() условие if(serial->bytesAvailable()==0) по непонятной для меня причине оказывается верно. Так же, как и верно условие if(serial->atEnd()). Как победить это? В идеале хотелось бы, чтоб все данные считывались сразу, за один заход в слот readData(). Ну, на крайний случай, пускай заходит в него сколько угодно раз, но чтоб можно было б как-то отследить момент, когда все данные считаны.

UPD
Если добавить небольшой лок перед чтением, т.е.
Раскрывающийся текст
void MainWindow::readData()
{    
    QThread::msleep(400);
    port_data.append(serial->readAll());
    ...
}
то чтение происходит за 2 захода в метод readData() - в первый раз считывается 8 Байт, затем все остальное.

Я ничего не понимаю.

Сообщение отредактировал borune - 20.11.2015, 16:42
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
 
Начать новую тему
Ответов
Iron Bug
  опции профиля:
сообщение 22.11.2015, 10:43
Сообщение #2


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


8 байт - FIFO буффер COM порта. когда он заполняется, вызывается аппаратное прерывание, которое получает система и система уже дёргает юзерские коллбэки.
в принципе, размер буффера бывает 1,4,8 или 14 байт. видимо, в данном случае их 8. это совершенно нормально. в железе данные всегда режутся на куски и потом на другой стороне склеиваются.
определение конца пакета - это уже более верхний уровень, о котором COM-порт ничего не знает. он передаёт байты.
накручивай хэдер и длину пакета (можно ещё CRC для контроля целостности) в свои пакеты и разгребай поток с порта.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Сообщений в этой теме


Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 26.11.2024, 0:26