Форум программистов, компьютерный форум, киберфорум
C/C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/6: Рейтинг темы: голосов - 6, средняя оценка - 5.00
5 / 5 / 2
Регистрация: 02.10.2013
Сообщений: 147

COM - порт, при приеме с частотой 16Гц процесс чтения не прерывается

13.05.2024, 10:03. Показов 1509. Ответов 19
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
При чтении с частотой 8Гц все проходит на ура, скорость порта 9600. увеличение скорости порта не меняет результат.
По логике вещей должен был срабатывать IDLE в железе, но возможно винда на это все плевала с высокой колокольни.
Прилагаю настройки таймаутов, но они по идеи не причем.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
GetCommState(Port2, &dcbSerialParams);
            dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
            dcbSerialParams.BaudRate = 9600;
            dcbSerialParams.ByteSize = 8;
            dcbSerialParams.StopBits = ONESTOPBIT;
            dcbSerialParams.Parity = NOPARITY;
            SetCommState(Port2, &dcbSerialParams);
            timeouts.ReadIntervalTimeout = 50;
            timeouts.ReadTotalTimeoutConstant = 50;
            timeouts.ReadTotalTimeoutMultiplier = 10;
            timeouts.WriteTotalTimeoutConstant = 50;
            timeouts.WriteTotalTimeoutMultiplier = 10;
            SetCommTimeouts(Port2, &timeouts);
и тестовое чтение данных, если данные идут с частотой 8 Гц буфер заполняется, каждый раз с нуля, т.к. мне и нужно. Но стоит посылать данные с частотой 16 Гц. Все продолжает сыпаться в буфер практически без остановки, что в моей задаче меня не очень устраивает.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int32_t glob_var = 16;
 
void test_reading_com(void) {
    while (glob_var--) {
        if (!ReadFile(Port2, buffer, sizeof(buffer), NULL, NULL))
        {
            printf("Error reading from serial port\n");
            CloseHandle(Port2);
          
        }
        cout << "data was read :" << -(glob_var - 16) << endl;
    }
 
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
13.05.2024, 10:03
Ответы с готовыми решениями:

Программа зависает при приеме сообщения через com порт
создал один виртуальный порт.Написал программу для чтения и записи по этому порту, но при приёме текста, всё зависает. думаю ошибка...

ReadFile() возвращает 0 считанных байт через COM-порт при приёме пакета ненулевой длины
Реализую обмен с датчиком через Modbus RTU. После передачи пакета package1 на устройство, оно отвечает пакетом: 0x09 0x04 0x02 0x00 0x08...

Процесс распаковки прерывается
Ребят, доброго дня. У меня тут проблема, почему то при распаковке архива с файлами, в середине процесса выскакивает ошибка - Неверный CRC в...

19
 Аватар для Azathtot
754 / 351 / 90
Регистрация: 07.01.2023
Сообщений: 1,451
15.05.2024, 06:35
Цитата Сообщение от dj_oni Посмотреть сообщение
Все продолжает сыпаться в буфер практически без остановки, что в моей задаче меня не очень устраивает.
Наверное дело-то не в задаче, а в способе решения?
Смотрите. У вас с порта лезет не произвольный поток байт, а вполне "осмысленные" сообщения, имеющие определенный размер. Ну так и вычитывайте их с разбором "на лету"
Вот пример моего кода. Тут идет один символ команды, и 8 байт данных (пробелы игнорируем)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
        while (ch != 'N') {
            if (!ReadFile(_hComm, &ch, sizeof(ch), &readed, NULL))
                goto endp;
        }
        char buf[8];
        FillMemory(buf,sizeof(buf),0);
        c = 0;
        for (int i = 0; i < 7; i++) {
            if (!ReadFile(_hComm, &buf[c], sizeof(char), &readed, NULL))
                goto endp;
            if (buf[c] != ' ')
                c++;
        }
Есть второй способ, вычитывать полный буфер, потом его парсить. "Хвосты" (то что пришло от следующего пакета данных) сдвигаем в голову буфера чтения...
1
5 / 5 / 2
Регистрация: 02.10.2013
Сообщений: 147
15.05.2024, 14:47  [ТС]
Цитата Сообщение от Azathtot Посмотреть сообщение
Смотрите. У вас с порта лезет не произвольный поток байт
Как раз получается условно - произвольный поток, если количество данных я еще могу знать , то когда прибор кидает uint32 как строку, получается сейчас значение это 7 символов, потом 8.... и таких значений там от 2 до 8 штук, в зависимости от настройки.
Второй способ возможен, но вот беда у меня открывается два потока, читаю с 1 порта скажем 100 значений( и мне нужно знать, что именно 100 значений я прочитал) пока эти значения считываются, со второго порта читаются другие значения( а скорость там намного ниже). Как только первый поток закончил, второй прерывает работу...
0
 Аватар для Azathtot
754 / 351 / 90
Регистрация: 07.01.2023
Сообщений: 1,451
15.05.2024, 16:10
Ну значения-то чем-то разделяются... вот и парсите по разделителю. Если нет - то это какой-то неправильный прибор...
1
5 / 5 / 2
Регистрация: 02.10.2013
Сообщений: 147
15.05.2024, 17:55  [ТС]
Сейчас я так и делаю, парсит по разделителю, после того как закончился прием. А если прием не закончился то как парсить то? Если как Вы предлагаете, указывать количество байт на прием допустим 10, а на самом деле их будет 12 , то значение при разборе строки совсем другое...
Меня интересовало другое, нет ли способа принимать данные по com - порту до тех пор пока не наступит событие IDLE, как это сделано в микроконтроллерах
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
15.05.2024, 23:20
Цитата Сообщение от dj_oni Посмотреть сообщение
Если как Вы предлагаете, указывать количество байт на прием допустим 10, а на самом деле их будет 12
А в чем проблема-то? Прочитали 10, затем еще 2, но с учетом первых 10. Для этого нужно организовать простейший конечный автомат, который будет на лету разбирать посылки. Если часть данных пришла, и автомат "завис" на середине, то вот и наступило IDLE (для этого чтение должно быть в блокирующем режиме, либо организовано через мультиплексор). Дальше ситуация может развиваться по двум сценариям: следующая посылка - это таки продолжение уже прочитанных данных, тогда автомат просто работает дальше, либо следующая посылка - это новая порция данных, тогда втомат "сбрасывается" и начинает анализ сначала. Конкретика, конечно же, зависит от конкретного протокола обмена.
В любом случае, вам все правильно выше говорят - именно таки надо делать и никак иначе (точнее иначе просто получите настабильное ПО, которое ломается, стоит лишь чуть-чуть изменить условия).
2
5 / 5 / 2
Регистрация: 02.10.2013
Сообщений: 147
16.05.2024, 13:05  [ТС]
DrOffset, код который предложил Azathtot, не сразу понял. Конечно можно висеть в цикле while и принимать по одному символу пока не дойдешь до конца строки... Но я надеялся на какое-нибудь более элегантное решение, нежели валятся в цикле.

Всем спасибо.
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
16.05.2024, 13:37
dj_oni, не, как раз принимать по одному символу совсем не обязательно. Читаете сразу буфер и отдаёте автомату его.
0
 Аватар для Azathtot
754 / 351 / 90
Регистрация: 07.01.2023
Сообщений: 1,451
16.05.2024, 13:59
dj_oni,
Тут код под конкретную задачу был. Но я сам же выше написал, что можно читать буферами и разбирать их, складывая "остатки" в голову буфера

Добавлено через 51 секунду
Цитата Сообщение от dj_oni Посмотреть сообщение
А если прием не закончился то как парсить то?
А "не закончился" это как? У вас буфер бесконечной длины? Заполнили буфер, распарсили. Остались хвостх - переместили в голову, читаем снова.
0
5 / 5 / 2
Регистрация: 02.10.2013
Сообщений: 147
16.05.2024, 14:16  [ТС]
Цитата Сообщение от Azathtot Посмотреть сообщение
А "не закончился" это как?
Не правильно выразился, я имел ввиду что принял условно 10 байт а в строка на самом деле 14 байт в этот раз и получается что нужно вводить доп проверки и тп. Тяжело перестроиться с микроконтроллеров на винду и обратно.
0
 Аватар для Azathtot
754 / 351 / 90
Регистрация: 07.01.2023
Сообщений: 1,451
16.05.2024, 16:24
Цитата Сообщение от dj_oni Посмотреть сообщение
Не правильно выразился, я имел ввиду что принял условно 10 байт а в строка на самом деле 14 байт
и что? Разделитель не найден, читаем в буфер дальше... вешаем будфер допустим на 8к и читаем его...
0
5 / 5 / 2
Регистрация: 02.10.2013
Сообщений: 147
17.05.2024, 12:51  [ТС]
Не хотелось открывать новую тему но собственно в те же ворота
при скорости 115200 и отправке команды в устройство
C++
1
"$112;SDF\r\n"
устройство с перепугу принимает только часть строки а именно
C++
1
"$112;D\r\n"
ощущение что просто не успевает обрабатывать строку.
из софта с костылями работает только так
C++
1
2
3
WriteFile(Port2, "$112;", 5, NULL, NULL);
Sleep(1);
WriteFile(Port2, "SDF\r\n", 5, NULL, NULL);
Но стоит отправить эту же строку целиком через терминал все проходит с первого раза.
Из программы отправляю в терминал, строка приходит целиком и не битая...
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
17.05.2024, 13:11
Цитата Сообщение от dj_oni Посмотреть сообщение
устройство с перепугу принимает только часть строки
Это нормально. Именно для обработки таких ситуаций и нужен конечный автомат.

Цитата Сообщение от dj_oni Посмотреть сообщение
из софта с костылями работает только так
Это как раз пример того самого нестабильного кода, который расчитывает на какие-то конкретные задержки. Лучше так не делать. Используйте поллинг (WaitFor... функции в эту же степь), либо блокирующие вызовы, либо Windows-специфичные механизмы (вроде портов завершения) - по сути все они приведут к одному исходу: функция чтения будет ждать новые данные и не грузить систему, выставлять никакие задержки не надо будет, а конечный автомат позволит не потерять данные если они пришли не полностью, или не сразу.
0
5 / 5 / 2
Регистрация: 02.10.2013
Сообщений: 147
17.05.2024, 16:43  [ТС]
DrOffset, Устройство конечное и его код я изменить не могу. Когда устройство принимает команду, оно возвращает принятую команду, по сути дела echo.
Цитата Сообщение от DrOffset Посмотреть сообщение
Это нормально. Именно для обработки таких ситуаций и нужен конечный автомат.
Конечный автомат для отправки 10 байт, которые мне изначально известны?
Мне кажется что тут все таки с настройками что то не то, у терминала проблем с приемом нет, команда проходит на ура.... а на устройстве какие проблемы. Отправлять по одному байту с ожиданием .... это просто нечто

Добавлено через 2 часа 46 минут
Не знаю что в приборе наворотили, но хохма вот в чем,
есть такая программа Terminal 16 если с нее отправлять в прибор (с учетом экранируемых символов) отправляется 10 байт и команда проходит на ура.
Есть программа Uartassist (от китайских братьев), отправляя команду из нее получаю такую же чудную потерю данных, хотя написано что отправлено тоже 10 байт. Идей просто никаких
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
17.05.2024, 17:31
Цитата Сообщение от dj_oni Посмотреть сообщение
Конечный автомат для отправки 10 байт, которые мне изначально известны?
Да.

Цитата Сообщение от dj_oni Посмотреть сообщение
и его код я изменить не могу.
Никто этого не предлагал.
Я к тому, что если что-то подобное делать самому, то также, а не хардкодить тайминги.
0
1186 / 468 / 68
Регистрация: 22.09.2023
Сообщений: 1,408
17.05.2024, 19:17
Цитата Сообщение от dj_oni Посмотреть сообщение
Но стоит отправить эту же строку целиком через терминал все проходит с первого раза.
Купите у китайцев логический анализатор (искать на али "8-channel logic analyzer", стоит как пара пива) - увидите разницу между посылками. В том числе и во времянке. И в жизни еще много раз пригодится в подобных ситуациях.
0
5 / 5 / 2
Регистрация: 02.10.2013
Сообщений: 147
20.05.2024, 08:36  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Я к тому, что если что-то подобное делать самому, то также, а не хардкодить тайминги.
Тут походу без вариантов, т.к. даже отправка по одному символу не позволяет добиться результата, все равно устройство не успевает за приемом пакетов .
Цитата Сообщение от Dushevny Посмотреть сообщение
Купите у китайцев логический анализатор
логический анализатор на прямую не льзя подключить RS232 не те уровни.
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
20.05.2024, 09:02
dj_oni, вероятно вы просто что-то не так делаете.
0
1186 / 468 / 68
Регистрация: 22.09.2023
Сообщений: 1,408
20.05.2024, 10:28
Цитата Сообщение от dj_oni Посмотреть сообщение
логический анализатор на прямую нельзя подключить RS232 не те уровни.
Этот - можно. И другой можно, через правильно выбранные токоограничительные резисторы. Но если требуется не решить задачу найдя причину, а угадать место подставления костыля - то да, можно считать, что подключать нельзя и продолжать тыкать наугад.
0
5 / 5 / 2
Регистрация: 02.10.2013
Сообщений: 147
21.05.2024, 15:16  [ТС]
В общем вся проблема в приборе, там два микроконтроллера, один с внешним миром, второй на внутреннем у первого скорость 115200 у второго 9600и обращение идет именно к внутреннему, который очень занятой и просто не успевает обработать более 5 символов (( так что тут хоть с тремя анализаторами лезь а без костылей не справится )))
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
21.05.2024, 15:16
Помогаю со студенческими работами здесь

Почему процесс прерывается?
char a; while ((a = getch()) != 'exit') { if (a == '1') { char path1, path2; cout &lt;&lt; &quot;Type First Adress&quot; &lt;&lt;...

Почему прерывается работа программы после чтения их файла?
После считывания данных с файла, программа останавливается,т.е на экран выводиться сообщение: для продолжения нажмите любую клавишу и все....

Как изменятся скорости записи и чтения при использовании карты памяти через USB порт?
При стандартном включении карты памяти в разъеме производителем указывается скорость записи и чтения инфы. А как эти параметры изменятся...

Процесс запуска Windows по истечении 2-х секунд прерывается и начинается перезагрузка
Здравствуйте,проблема очень сложная,создавал на паре форумов данную тему,но помочь там не смогли.Здесь тоже создавал тему в вирусной...

Процесс установки игр внезапно прерывается без сообщения об ошибке
Здравствуйте! С всеми подобными темами на вашем форуме я уже ознакомился и не нашел в них решения своей проблемы. Да и не уверен, живы ли...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США. Нашел на реддите интересную статью под названием «Кто-нибудь знает, где получить бесплатный компьютер или. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru