Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.71/56: Рейтинг темы: голосов - 56, средняя оценка - 4.71
279 / 156 / 52
Регистрация: 30.06.2011
Сообщений: 1,712

И снова работа с COM портом

16.11.2016, 14:03. Показов 12819. Ответов 67
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Приветствую всех. Уже измучился и измаялся весь пытаясь написать функцию. Помогите, пожалуйста...

Описание задачи
Создается программа для работы с прибором. Соединение с прибором осуществляется посредством преобразователей, которые при подключении к компьютеру создают виртуальный COM порт. Преобразователь может подключаться к прибору посредством проводного (RS-485) или беспроводного (инфракрасный канал) соединения. Прибор всегда является ведущим, то есть информацию выдает только по запросу от компьютера (получил корректный запрос - выдал ответ). Целостность запросов и ответов определяется циклическим избыточным кодом в конце запроса или ответа.

Текущая реализация
На данный момент я создал класс для работы с прибором. Экземпляр этого класса будет создаваться и работать в отдельном потоке. В классе будут реализованы конкретные функции для работы с прибором (например - прочитать серийный номер прибора). Каждая из этих функций подготавливает соответствующий запрос прибору и вызывает внутреннюю функцию обмена данными SwapData. Указанная функция, по сути, выполняет основную работу класса: отправляет созданный запрос в COM порт и получает ответ из COM порта. Именно данную функцию я не могу написать. Начало функции SwapData выглядит примерно так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int SwapData()
{
 // COMHandle - хендл открытого COM порта
 // Data - вектор байт для запроса и ответа
 // eCOM... - константы ошибок обмена
 DWORD dw;
 
 /* Очистка буферов и очередей COM порта */
 if(!PurgeComm(COMHandle, 0x0F)) return eCOMPurge;                              // Не удается очистить буферы COM порта: возвращаю ошибку
 
 /* Отправка данных в COM порт */
 if(!WriteFile(COMHandle, &Data.front(), Data.size(), &dw, NULL) ||             // Не удается отправить данные в COM порт или
     dw != Data.size()) return eCOMWrite;                                       // отправлены не все данные: возвращаю ошибку
 
 /* Чтение данных из COM порта */
}
К приведенной части кода функции претензий нет: буферы очищаются, запрос отправляется (при этом функция WriteFile ждет пока не отправятся все данные, ибо синхронный режим). Проблема возникает с приемом ответа.

Описание проблемы
Прием ответа от прибора сопряжен с несколькими трудностями. Во первых, ответ необходимо принять максимально быстро. То есть, не должно быть простоев в работе функции SwapData. Во вторых, на один и тот же запрос прибор может ответить разным количеством байт (либо вообще не ответить). Это связано с тем, что прибор может получить некорректный запрос (например, ошибка при передаче). Тогда он, скорее всего, вообще не ответит. Так же в каком-то конкретном приборе может быть отключена какая-то функция и прибор на запрос, связанный с этой функцией, выдаст не ожидаемое количество байт, а другое, которое сигнализирует об ошибке. В связи со всем этим появилась попытка решения задачи приема данных.

Попытка реализации чтения данных
В нижеприведенном коде я реализовал алгоритм, когдаПривожу код, который отвечает за прием данных:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
 // COMHandle - хендл открытого COM порта
 // COMSpeed - скорость COM порта в бит/с
 COMSTATE cs;
 DWORD dw;
 
 /* Цикл ожидания ответа от прибора */
 for(DWORD in = 0, vl = 0, st = GetTickCount();;)
  {
   /* Останавливаю программу на время приема одного байта */
   Sleep(10000 / COMSpeed);
 
   /*  В буфер COM порта поступили новые данные */
   if(ClearCommError(COMHandle, &dw, &cs) && !dw && cs.cbInQue > in)
    {
     in = cs.cbInQue; /* Сохраняю количество данных в буфере COM порта */
     vl = 0; /* Обнуляю количество "пустых циклов" (когда данные не поступили) */
     continue;
    }
 
   /* Прерываю цикл ожидания ответа от прибора если:
      - в буфере COM порта нет данных и время ожидания превысило 3 секунды;
      - в буфере COM порта есть данные и было более одного "пустого цикла" */
   if((!in && ((GetTickCount() - st) > 3000)) || (in && ++vl > 1)) break;
  }
 
 /* Выполняю чтение данных из буфера COM порта */
 if(!cs.cbInQue) return eNotData;
 Data.resize(cs.cbInQue);
 if(!ReadFile(COMHandle, &Data.front(), Data.size(), &dw, NULL) ||
     dw != Data.size())) return eCOMRead;
Данный код отлично работает на скорости 300 бит/с, но на скорости 9600 бит/с цикл приема завершается до приема всех данных.

Помогите советом как реализовать прием данных максимально быстро и полно.
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
16.11.2016, 14:03
Ответы с готовыми решениями:

Работа с COM портом
по COM порту через Agilen подключается вольтметр с адресом 1. необходимо "прозвонить" все порты и автоматически сделать рабочим тот,...

работа с COM портом
здравствуйте всем,я в форумах в первие ,и просил бы не судить очень строго. помогите пожалуйста , хочу реализовать приложение работающую с...

Работа с COM-портом
Подскажите, какие компоненты нужны для работы с ком-портами? а именно (хотя бы для начала) отправка шестнадцатиричного кода на порт, к...

67
Модератор
 Аватар для vxg
3410 / 2182 / 354
Регистрация: 13.01.2012
Сообщений: 8,476
21.11.2016, 09:08
Студворк — интернет-сервис помощи студентам
ITDeveloper, не понятно что вы хотите посоветовать. У ТС протокол который ТРЕБУЕТ использовать тайм-ауты. ТС понимает что на один порт можно повесить много устройств опрашиваемых последовательно. Никаких лагов и велосипедов. Широковещательные сообщения ТС не упоминает - может их нет в протоколе, но даже если есть применимость таких сообщений очень ограниченная так как отвечать на такое сообщение в общем случае устройства не должны.
0
279 / 156 / 52
Регистрация: 30.06.2011
Сообщений: 1,712
21.11.2016, 09:20  [ТС]
Цитата Сообщение от vxg Посмотреть сообщение
...но даже если есть применимость таких сообщений очень ограниченная так как отвечать на такое сообщение в общем случае устройства не должны.
Все именно так.
0
 Аватар для ITDeveloper
86 / 86 / 6
Регистрация: 14.01.2011
Сообщений: 265
21.11.2016, 09:50
Ну если даже нет необходимости и поддержки шировещательных запросов, все равно городить систему из кучи преобразователей или com портов это не правильно! Технически более оптимально использовать один порт и сеть устройств! Если вы хотите в дальнейшем использовать свои наработки и как то дальше развивать вашу систему, то необходимо правильно выстроить архитектуру на начальном этапе!
0
Модератор
 Аватар для vxg
3410 / 2182 / 354
Регистрация: 13.01.2012
Сообщений: 8,476
21.11.2016, 10:09
ITDeveloper, ТС знает о свойствах сети я надеюсь. несколько портов понадобится если будет желание сделать резервирование линии или поделить устройства по протоколам или из-за требований к скорости
0
279 / 156 / 52
Регистрация: 30.06.2011
Сообщений: 1,712
21.11.2016, 10:47  [ТС]
Цитата Сообщение от ITDeveloper Посмотреть сообщение
Ну если даже нет необходимости и поддержки шировещательных запросов, все равно городить систему из кучи преобразователей или com портов это не правильно! Технически более оптимально использовать один порт и сеть устройств! Если вы хотите в дальнейшем использовать свои наработки и как то дальше развивать вашу систему, то необходимо правильно выстроить архитектуру на начальном этапе!
Ну что же такое!!! ITDeveloper, я уже Вам сказал, что я был не прав. У меня не будет кучи преобразователей. Будет один преобразователь (и, соответственно, один COM порт) и от одного до нескольких приборов, подключенных к нему. Вы мои ответы на Ваши посты читаете вообще?
0
 Аватар для ITDeveloper
86 / 86 / 6
Регистрация: 14.01.2011
Сообщений: 265
21.11.2016, 11:19
Цитата Сообщение от d7d1cd Посмотреть сообщение
Ну что же такое!!! ITDeveloper, я уже Вам сказал, что я был не прав
Я не пытаюсь спорить и доказывать свою точку зрения! Просто хотел помочь и предостеречь от проблем!
1
279 / 156 / 52
Регистрация: 30.06.2011
Сообщений: 1,712
21.11.2016, 11:40  [ТС]
ITDeveloper, спасибо.
0
 Аватар для ITDeveloper
86 / 86 / 6
Регистрация: 14.01.2011
Сообщений: 265
21.11.2016, 12:30
Да пожалуйста! Вы пишите о результатах и способах решения тех или иных вопросов! Мы тут все учимся в процессе обсуждения! Думаю многим интересно!
2
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
21.11.2016, 12:30

Работа с COM портом
Здравствуйте! В процессе написания программы работы с устройством, подключенным к ПК через преобразователь интерфейсов RS485 - USB,...

Работа с Com портом
Привет всем! У меня собственно такая ситуация, есть bluetooth и телефон Nokia устанавливаю соединение через виртуальный com порт, мне...

Работа с COM портом в Builder C++ 6.0
Добрый день, уважаемые форумчане. Никогда не спрашивал совета на форумах, но нужна подсказка. Кто располагает временем, буду очень...

Работа с COM портом на С++ Builder 6
Работаю я с GSM модемами, пишу под них программу на C++ Builder 6. Посылаю в модем, через COM порт соответственно, AT команды (строку...

Работа с USB портом.
Доброго всем времени суток! Суть задачи в следующем: Есть устройство (USB принтер этикеток) и им можно управлять при помощи...


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

Или воспользуйтесь поиском по форуму:
68
Ответ Создать тему
Новые блоги и статьи
Особенности gif сгенерированных в Си
russiannick 21.10.2026
Рассмотрим генерацию gif файлов, которые в Си имеют свои особенности. Gif представляет собой графический формат популярный в интернете. Посмотрим на палитру. Gif файл сгенерированный в си отличается. . .
FPS контроллер с анимированными Y-Bot и 3D-звуком miniaudio (Box3D, Recast, BehaviorTree.CPP, ozz-animation, ImGui, OpenGL и SDL3)
8Observer8 18.10.2026
Содержание блога | English Version Полное мультиплатформенное руководство по стартовому проекту с FPS-контроллером игрока, анимированными роботами Y-Bot с 4-слойным блендингом, 3D-физикой Box3D,. . .
Локальный http сервер
Argus19 17.10.2026
Локальный http сервер На работе, на двух локальных компьютерах круглосуточно работают программы опроса приборов с записью в книги Excel,которые раз в сутки записываются на сервер компании. Т. к. . . .
Копировать Windows на новый диск на UEFI
damix 17.10.2026
https:/ / uriesk. wordpress. com/ 2016/ 11/ 01/ move-window-10-to-ssd-on-a-uefi-dualboot-system-with-basic-linux-tools/ TL DR Вставляем диск, а старый подключаем через переходник, грузимся с лайва. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru