Russian Qt Forum

Qt => Дополнительные компоненты => Тема начата: sergeykr от Январь 22, 2014, 10:03



Название: Вопрос про QSerialport. Ошибка при приеме данных больше 128.
Отправлено: sergeykr от Январь 22, 2014, 10:03
Установил QT5.1. В состав уже входила библиотека qserialport, которой я попытался воспользоваться. Возникла следующая проблема.
Стенд: есть микроконтроллер Atmega8, он формирует счетчик размера 32 разряда. Число разбивается на 3 байта ( больше мне не надо ) и отсылается через com порт. Т.е. через com порт идет : 1 0 0 , 2 0 0 , 3 0 0 ........3 2 0 ..... и .т.д. Параметры com порта 2400, 8 бит, even, 1 stop, noflowcontrol.
Принимающая сторона компьютер с двумя операционными системами (Linux & win(на virtual box)). Есть программа на QT которая принимает эти данные. Проблема возникает в win, когда число переваливает за 128 ( т.е. за размер char),
 то один бит как бы переходит в след. байт. В LINUX такой проблемы нет.
Пример приема данных:
1 0 0 , 2 0 0 ...... 127 0 0 , 128 0 0 , 1 1 0 ( ?????).

Собирается программа без ошибок. Странности возникают при запуске:
1. Предупреждение void QSerialPortPrivate::detectDefaultSettings(): Unexpected flow control settings. ( в программе стоит
Код:
if(!serial_port.setFlowControl(QSerialPort::NoFlowControl))
        {
           qDebug()<<"error set flow control"<<com_port_name<<endl;
           qDebug()<<"error number"<<serial_port.errorString()<<endl;
           serial_port.close();
           emit connect_status("error set flow control");
           return;
        }
2. Один раз воникло такое же предупреждение о размере данных ( data8) и о чудо программа заработала как надо) т.е.
128 0 0 , 129 0 0 ........ 255 0 0 , 1 1 0  и т.д.

Может быть кто сталкивался с такой ситуацией.
Всем заранее спасибо за внимание.


Название: Re: Вопрос про QSerialport. Ошибка при приеме данных больше 128.
Отправлено: kuzulis от Январь 22, 2014, 10:48
Цитировать
Проблема возникает в win, когда число переваливает за 128 ( т.е. за размер char),

Нужно правильно сконфигурировтаь порт после его открытия, в твоем случае это:

Код
C++ (Qt)
 
bool ret = port.setDataBits(QSerialPort::Data8);
if (!ret) {
   // process error
}
 
 

Цитировать
Предупреждение void QSerialPortPrivate::detectDefaultSettings(): Unexpected flow control settings.

Не смотри на это. Оно появляется при открытии порта когда порт не может распарсить текущие параметры DCB касающиеся flow control.
Раньше порт выставлял их в Unknown, но потом решили не использовать Unknown, а писать варнинг (как оно есть сейчас), и заменять на NoFlow.
Поэтому в любом случае нельзя полагаться на параметры, полученные после открытия порта - нужно всегда устанавливать их самому при помощи setXX() методов.


Название: Re: Вопрос про QSerialport. Ошибка при приеме данных больше 128.
Отправлено: sergeykr от Январь 22, 2014, 11:05
Я устанавливаю параметры порта

Код:
if (serial_port.open(QIODevice::ReadOnly))
    {
        if ((!serial_port.setBaudRate(QSerialPort::Baud2400)) &&
            (!serial_port.setDataBits(QSerialPort::Data8))      &&
            (!serial_port.setParity(QSerialPort::EvenParity)) &&
            (!serial_port.setStopBits(QSerialPort::OneStop)))
        {
            qDebug()<<"error set up port"<<com_port_name<<endl;
            serial_port.close();
            emit connect_status("connect to com port error");
            return;
        }
        if(!serial_port.setFlowControl(QSerialPort::NoFlowControl))
        {
           qDebug()<<"error set flow control"<<com_port_name<<endl;
           qDebug()<<"error number"<<serial_port.errorString()<<endl;
           serial_port.close();
           emit connect_status("error set flow control");
           return;
        }
        serial_port.clear();
emit connect_status("connect to com port ok");
}// end if

Каждый раз при запуске программы вылезает сообщение о неправильной установке controlflow и программа работает неправильно. Один раз вылезло сообщение что неправильно установлен размер данных и QT установил
их по умолчанию и программа заработала. К сожалению повторить данную ошибку не удалось.
Есть мнение , что неправильно установился размер данных ( не 8,  а 7 бит) поэтому старшая единица переходит в другой байт.


Название: Re: Вопрос про QSerialport. Ошибка при приеме данных больше 128.
Отправлено: kuzulis от Январь 22, 2014, 11:22
Цитировать
Каждый раз при запуске программы вылезает сообщение о неправильной установке controlflow и программа работает неправильно.

Это потому что по умолчанию свойство settingsRestoredOnClose всегда true.
Таким образом, перед закрытием, порт снова установит те параметры, которые были перед открытием. т.е. с "кривым" flow control.

Чтобы он оставил твои настройки скорости, четности и пр., нужно написать setSettingsRestoredOnClose(false).

Цитировать
Один раз вылезло сообщение что неправильно установлен размер данных и QT установил
их по умолчанию и программа заработала.

Оно ничего не устанавливает по-умолчанию, класс QSerialPort просто сбрасывает свои внутренние переменные на умолчательные, например скорость на 9600.
Но это не значит что он будет работать на 9600 (тут он будет работать на хрен-знает какой скорости). Чтобы он работал на 9600 нужно сделать setBaudRate(9600).

Цитировать
Есть мнение , что неправильно установился размер данных ( не 8,  а 7 бит) поэтому старшая единица переходит в другой байт.

Такого быть не может. Если setDataBits() возвратил true, значит все установилось как надо.

UPD:

Гы, ты неправильно конфигуришь. Что даст это условие:
Код
C++ (Qt)
if (!x && !y && !z) {}
 

? :)


Название: Re: Вопрос про QSerialport. Ошибка при приеме данных больше 128.
Отправлено: sergeykr от Январь 22, 2014, 11:48
Ок. Тоже только сейчас заметил, что у меня неправильная конфигурация. Спасибо.
Исправил. Все заработало.

Еще раз спасибо.