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

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

16.11.2016, 14:03. Показов 12056. Ответов 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
3409 / 2180 / 354
Регистрация: 13.01.2012
Сообщений: 8,450
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
3409 / 2180 / 354
Регистрация: 13.01.2012
Сообщений: 8,450
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
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru