Russian Qt Forum
Ноябрь 23, 2024, 07:37 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: QSerialPort Искажение данных  (Прочитано 9297 раз)
Evgeniy
Гость
« : Декабрь 04, 2019, 17:01 »

Здравствуйте!

У меня есть следующая проблема. У меня написана программа, к которой подключено 6 последовательных портов. 5 из них работают нормально. В шестом порту происходит следующее:

1. Мне приходит запрос в виде сообщения длиной в один байт. Байт этот 0xD. Я отправляю один ответ
2. Через 10 мс приходит еще один запрос. Он тоже должен быть 0xD, и по нему я должен отправить другой ответ

Прием выглядит так:
Код:
void Sim_Ab::readIN()
{
    QTime time = QTime::currentTime();
    QString strTime = time.toString("hh.mm.ss.zzz");
    recIN.append(srlIN->readAll());

    //вывожу в консоль, что мне пришло
    qDebug()<<"priem IN" << strTime << "data =" << recIN.toHex();
    while (recIN.size()>0){
        if (recIN[0]==0xD){
            recIN.remove(0,1);
            if (numIn==1)
                sendIN(1);
            else sendIN(2);
            if (numIn==1)
                numIn = 2;
            else numIn = 1;
        }
        else{
            recIN.remove(0, 1);
        }
    }
}

В результате в консоль сыпется следующее:
Код:
priem IN "16.19.04.909" data = "0d"
priem IN "16.19.04.920" data = "f3"
priem IN "16.19.05.409" data = "0d"
priem IN "16.19.05.422" data = "fd"
priem IN "16.19.05.909" data = "0d"
priem IN "16.19.05.919" data = "6d"
priem IN "16.19.06.409" data = "0d"
priem IN "16.19.06.420" data = "fe"
priem IN "16.19.06.909" data = "0d"
priem IN "16.19.06.919" data = "9d"
Как видно из консоли, второй запрос не равен 0xD, следовательно, ответа нет.

Подключаем к этому порту другую программу, которая работает только с одним портом. Прием в ней следующий:
Код:
void byteRez::receive()
{
    QString str1, str2;
    recDat.append(serial->readAll());
    str1.append(recDat.toHex());
    for (i=0;i<str1.size(); i+= 2)
        str2.append(QString("%1%2 ").arg(str1[i]).arg(str1[i+1]));
   ui->readEdit->insertPlainText(str2);
   recDat.clear();
}

В этом случае видно, что все принятые байты равны 0xD.
Из этого я делаю вывод, что первая программа каким-то образом искажает принятые данные

Буду благодарен за любые мысли на этот счет.

Windows 7. Qt 5.3
« Последнее редактирование: Декабрь 04, 2019, 17:25 от Evgeniy » Записан
vbv
Чайник
*
Offline Offline

Сообщений: 59


Просмотр профиля
« Ответ #1 : Декабрь 04, 2019, 18:55 »

Как вариант: проверить инициализацию порта, скорость и т.п.
Как вызывается чтение порта?
По частоте прерываний нет затыка.... 10 мс это хорошая частота. т.е. это 115к  минимум.

Попробовать, как вариант, "многопортовку" натравить на первые 5 портов, и в это же время однопортовый вариант на последний.

Это на вскидку.
Записан
Evgeniy
Гость
« Ответ #2 : Декабрь 05, 2019, 09:57 »

Инициализация порта в обеих программах происходит из конфигурационного файла. Содержимое этих файлов одинаково:
8 бит данных, 2 стопа, контроль по нечетности, скорость 9600

Чтение из порта происходит по сигналу readyRead. Если "многопортовку" натравить на первые 5 портов, а однопортовый вариант на последний порт, то искажений в нет.
Записан
Evgeniy
Гость
« Ответ #3 : Декабрь 05, 2019, 10:51 »

В слот чтения добавил контроль контроль размера принятых данных:

Код:
 
   recIN.append(srlIN->readAll());
   if (recIN.size()<2)
        return;

Пока оба запроса не придут, отвечать не буду. Искажения после этого исчезли.
Если я все правильно понял, то происходило примерно следующее:
1. В com порт поступает запрос 0xD, по которому вызывается слот отправки ответа
2. Программа считывает с ui определенные параметры и посылает ответное сообщение, состоящее из десяти байт. И все это занимает больше 10 мс.
3. В это же время в порт поступает еще один запрос, который перекрывается по времени с ответом
Чтение и запись происходят одновременно, из-за чего вносятся искажения.

Если я не прав, поправьте, пожалуйста
Записан
qate
Супер
******
Offline Offline

Сообщений: 1177


Просмотр профиля
« Ответ #4 : Декабрь 05, 2019, 11:23 »

Qt 5.3

3 или 13 ?

сигналами/слотами идет чтение из портов ?
Записан
Evgeniy
Гость
« Ответ #5 : Декабрь 05, 2019, 11:38 »

Qt 5.3, не 13

Сигналы readyRead привязаны к слотам чтения
Записан
qate
Супер
******
Offline Offline

Сообщений: 1177


Просмотр профиля
« Ответ #6 : Декабрь 05, 2019, 11:45 »

Qt 5.3, не 13

1. я бы обновился на всякий случай
2. если работать только с "шестым" портом - все ок ?

Записан
Evgeniy
Гость
« Ответ #7 : Декабрь 05, 2019, 11:53 »

1. Спасибо за совет, попробую
2. Если работать только с "шестым" портом, то искажения тоже есть.
Записан
qate
Супер
******
Offline Offline

Сообщений: 1177


Просмотр профиля
« Ответ #8 : Декабрь 05, 2019, 12:03 »

2. так может проблема не в порте, а в железяке "за" портом ?
Записан
Evgeniy
Гость
« Ответ #9 : Декабрь 05, 2019, 12:25 »

Возможно. Но проверить не получится, все железяки одинаковые, других нет. Менять местами пробовал, не помогло
Записан
qate
Супер
******
Offline Offline

Сообщений: 1177


Просмотр профиля
« Ответ #10 : Декабрь 05, 2019, 13:09 »

6 портов как организованы ?
это pci плата или 6 шнурков usb-rs232 ?

пиши показывай минимальный пример в виде проекта, иначе только гадать
Записан
Evgeniy
Гость
« Ответ #11 : Декабрь 05, 2019, 13:44 »

6 проводов, на конце которых 6 usb-485 конвертеров. Эти конвертеры воткнуты в usb хаб, который уже идет на компьютер.
Записан
qate
Супер
******
Offline Offline

Сообщений: 1177


Просмотр профиля
« Ответ #12 : Декабрь 05, 2019, 15:08 »

в данном конфиге я не вижу кто "шестой", может usb-хаб "не справляется" ?

сделай тест - 6 заглушек на концы и передавай сам-себе числа по порядку - будет ли затык приема\передачи ?
Записан
vbv
Чайник
*
Offline Offline

Сообщений: 59


Просмотр профиля
« Ответ #13 : Декабрь 05, 2019, 19:11 »

Ну если помогло чтение размера. То явно затык в скорости.
Изменить алгоритм работы, как вариант, поместить чтение в отдельные процессы/потоки.
Не известно как там Qt обрабатывает прием данных а точнее синхронизацию.
Возможно по пробовать читать/писать другой библиотекой. Qt это прикладной уровень. (хотя в данном случае - это вряд-ли.)
И скорость 9600 маловато будет, 10мс это что? микро- или мили- секунды? Если микро - маловато.
1/10Е-6=100 000 байт по одному байту. без служебной информации - только на прием.
1/10Е-3=100 байт в секунду без служебной информации только на прием.
Какая операционная система, возможно общий драйвер не подразумевает такой пропускной способности. С чем-то подобным под форточками сталкивался - только не помню с чем и как победили.

Еще: не пытаться обрабатывать сразу, сделать очередь. Читать все одним процессом а обрабатывать другим.

PS: если запросы поступают на несколько портов. И приходит запрос на другом порту пока идет обработка, слот для нового запроса не вызываться, а когда вызывается то там уже пришло больше одного запроса.
т.е. проблема чтения. - решение очередь.

Записан
vbv
Чайник
*
Offline Offline

Сообщений: 59


Просмотр профиля
« Ответ #14 : Декабрь 05, 2019, 19:15 »

И еще добавлю, если известна скорость поступления запросов, читать можно по таймеру все порты махом. Не дожидаясь сигнала. Существенно сократиться кол-во вызовов.
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.052 секунд. Запросов: 23.