Правильный подход обмена данных с устройствами через COM-порт. Целостность пакетов и производительность обмена26.02.2018, 23:52. Показов 21675. Ответов 71
Метки нет (Все метки)
Приветствую вас, коллеги!
Хочу с вами посоветоваться, ибо мне кажется, что я делаю это не совсем правильно, либо что-то не учёл... Делаю обмен данными с устройством через COM-порт (RS-232) по алгоритму: послал команду в порт (через .Write(...)), поставил задержку (Threading.Sleep(200)), читаю ответ (через .Read(...)). И вот тут меня смущает эта самая задержка. Если ответные пакеты приходят большие (ну например более 60 байтов), то что бы вычитать весь буфер, этой задержки как буд-то не хватает, пакет получаю не весь. Если увеличиваю задержку, то буфер весь вычитывается, однако, во-первых, буфера могут быть разной длины, и для каждого так подбирать задержки - не реально, во-вторых, если с устройством есть возможность обмениваться на разных скоростях (бод), это вообще дур-дом и всякая актуальность, например, выбора более высокой скорости обмена теряется, т.к. задержки будут одинаковыми, если их так железно задавать... В-третьих, когда такая функция обмена, с железно заданным Sleep'ом (подобранным на вскидку, чтоб не потерять большие пакеты), в цикле, например, ведёт обмен, то для более мелких пакетов, такая задержка, опять же, становится не актуальной, т.к. увеличивается драгоценное время простоя, и обмен происходит дольше, чем мог бы быть... Вот по этому я и задаюсь вопросом: как в таком случае правильно следует поступать? Не ужели чем длиннее ответный пакет, тем дольше его нужно ждать, чтоб он вычитался? Как избежать таких диких задержек? У кого был подобный опыт с обменом по СОМ-порту с устройствами, подскажите, пожалуйста, или поделитесь идеями, кто хотя бы понял суть вопроса. P.S. слышал что-то про подход асинхронного чтения данных из порта, но пока не понял что это и с чем это едят, и мой ли это вообще случай. Если да, то расскажите про такой подход, кто в курсе вообще. Только по понятнее пожалуйста, с примерами, если можно, а то про асинхронные приёмы работы пока вообще не в теме... Особо не доводилось использовать.
0
|
|
| 26.02.2018, 23:52 | |
|
Ответы с готовыми решениями:
71
Организация обмена данными через LPT-порт Функция для обмена HEX данными через COM порт Синхронизация обмена данных через LiFi |
| 07.04.2018, 20:06 [ТС] | |||
.
0
|
|||
| 09.04.2018, 12:59 [ТС] | ||
|
Ну, если я правильно всё понял, то это очень хороший результат!
0
|
||
|
|
|
| 09.04.2018, 13:09 | |
|
AN3155 - USART protocol used in the STM32 bootloader, команда ReadMemory, до 256 байт примерно.
0
|
|
| 09.04.2018, 13:46 [ТС] | ||
|
Not Found Cannot serve request to /content/ccc/resource/technical/document/application_note/51/5f/03/1e/bd/9b/45/be/CD00264342.pdf/ ApacheSling/2.4 (jetty/9.2.9.v20150224, Java HotSpot(TM) 64-Bit Server VM 1.8.0_45, Linux 4.9.85-37.55.amzn1.x86_64 amd64)
0
|
||
|
|
|
| 09.04.2018, 13:50 | |
|
Хм. Вот так http://www.st.com/resource/en/... 264342.pdf
0
|
|
| 09.04.2018, 15:37 [ТС] | ||
|
Вы привели скриншоты с WinAPI. Это вы на нём обмен реализовали, или как? Его как-то в коде C# можно применить?
0
|
||
| 09.04.2018, 16:07 [ТС] | ||
0
|
||
|
|
||||||
| 09.04.2018, 18:54 | ||||||
|
В ЛС от 2018-03-01 11:37 мск.
Попробуйте применить то, что выше советовали: Правильный подход обмена данных с устройствами через COM-порт. Целостность пакетов и производительность обмена Это проще. Добавлено через 8 минут Код мой вам не поможет: весь я показать не могу, а часть - лишь верхушка айсберга. Непосредственно чтение на самом нижнем уровне выглядит так:
0
|
||||||
| 09.04.2018, 21:25 [ТС] | |||
![]() Добавлено через 1 час 48 минут А вот за "рабочие исходники" © был бы признателен! Хочется наглядно посмотреть, как правильно на деле вы применяете методы (и какие именно) этого класса... Особенно интересует метод чтения, а то что-то я его не заметил там...
0
|
|||
|
|
||||||||
| 10.04.2018, 11:20 | ||||||||
Вот нашел исходный код и пересобрал его (см присоединенный файл NETSerialComm.zip). Это COM терминал сделанный поверх CommBase. В нем есть класс BaseTerm который унаследован от CommBase. В нем есть переопределенный метод OnRxChar, который принимает входящие байты. Кроме того я нашел у себя еще один класс SerialClient. Это обертка поверх стандартного SerialPort. Он также работает быстрее стандартного SerialPort. В эттейче - пример (WindowsFormsApplication226.zip - это исходник принимающий данные с камеры, прием данных происходит в событии OnReceiving). Кроме того, этот код публиковался в MSDN Magazine, поэтому думаю с использованием проблем не должно быть.
2
|
||||||||
| 10.04.2018, 12:05 [ТС] | |||
0
|
|||
|
|
||
| 10.04.2018, 13:51 | ||
|
SerialClient - простой в использовании. Но он решает только проблему временных задержек стандартного SerialPort. Если проблема только с задержками - можно попробовать его. CommBase - более сложный. Но он низкоуровневый, на WinAPI, соответственно в нем можно сделать все что хочешь.
0
|
||
| 10.04.2018, 14:20 [ТС] | |
|
0
|
|
| 16.04.2018, 12:43 [ТС] | ||||||
|
Storm23, добрый день! Ещё раз спасибо за эти два отличных примера. Поизучав их на днях, долго не мог решить, каким из них всё же попробовать воспользоваться для изменения алгоритма обмена в своём проекте... Честно, даже до сих пор толком не определился, но думаю попробовать применить второй вариант. В связи с чем у меня появилась парочка вопросов по логике работы вашего примера.
1) Если я правильно понял, то в этой программе вы сначала настраиваете СОМ-порт на определённые настройки, после чего открываем порт и держим его открытым на протяжении всей работы программы? Если, как вы сообщили, эта программа принимает данные с камеры (непрерывно видимо), то это логично. А вот на сколько такой подход целесообразен, если приём данных в программе происходит только тогда, когда пользователь нажмёт соответствующие кнопки и пакеты при этом могут быть как единоразовыми (пакет с посылкой →, ответный пакет ←), так и вида: пакет с посылкой →, цикл ответных пакетов ← ? В моём нынешнем варианте я каждый раз открываю порт перед отправкой пакета в устройство и получением ответа (ответов), а по окончании обмена закрываю. Можно ли оставить такую концепцию, или всё стоит держать порт открытым пока программа запущена? 2) По обмену: опять же, если я всё правильно понял, отправка пакета осуществляется функцией void Transmit(byte[] packet), тайм-ауты приёма по умолчанию отсутствуют вообще (= -1), а для приёма нужно подписываться на событие OnReceiving, таким образом: com.OnReceiving += new EventHandler<RTSerialCom.DataStreamEvent Args>(com_OnReceiving); Всё верно? А в этом событии чтение в отдельном потоке происходит, так? И по этому нет ни тайма-аутов, не слипов? Добавлено через 1 час 49 минут Кстати. Немного доработал вашу функцию bool OpenConn() (в модуле FastSerial): после открытия порта ( _serialPort.Open(); ), добавил очистку буфера приёма/передачи:
0
|
||||||
|
|
||||
| 18.04.2018, 10:22 | ||||
|
0
|
||||
| 18.04.2018, 13:00 [ТС] | |||||||||||
|
Storm23, Ну вроде реализовал данный подход. Но со слипами всё равно какая-то хрень. Для пакетов поменьше хватает и 100мс, а для пакетов побольше приходится подбирать разные (и 200, и 400 и 600)... И как-то не особо стабильно ведёт себя: то успевает за это время задержки принять пакет, то нет... Пока не пойму, но делать большие слипы мне не нравится... Либо я что-то не так делаю?
Добавлено через 1 час 0 минут Storm23, что бы не гадать, я пожалуй покажу, что у меня получилось, а вы может свежим взглядом увидите, что я возможно делаю не правильно. Т.к. мне кажется, я не совсем понял механизм уведомления завершения приёма каждого отдельного ответного пакета. В вашем примере я так понимаю, включаем поток чтения один раз и больше его не перезапускаем, и вертимся в нем, накапливая буфер, и по ходу разбирая его... В своём алгоритме же я каждый раз, перед отправкой команды в устройство, вызываю метод RestartComPort(), тем самым запустив поток чтения, а после принятия ответного пакета в обработчике ответа дёргаю флаг, что пакет полностью принят и закрываю соединение, отписываясь вместе с тем от события обработки чтения... Но вот тут как раз я и не уверен, во-первых в целесообразности такого "передёргивания" порта и сессии чтения)), а во-вторых тут как раз и не совсем понятно, как сообщить из обработчика чтения, что пакет успешно принят, и передать управление коду дальше??? В общем вот мой вариант представления:
0
|
|||||||||||
| 18.04.2018, 19:59 | |
|
Не по теме: Cha1000000,
0
|
|
| 18.04.2018, 21:43 [ТС] | ||
|
Тут бы понять каким образом передавать управление основному потоку из потока чтения, когда посылка считана. Тогда не придётся подбирать слипы наугад... В вашем примере случайно не через Invoke такой механизм осуществляется? Спрашиваю потому, что этим инструментом ещё пользоваться не доводилось и только лишь интуиция мне подсказывает, что возможно именно он для этого и используется...
0
|
||
| 18.04.2018, 21:43 | |
|
Виртуальный COM-порт на STM32, скорость обмена.
COM-порт, работа с двумя формами и одним буфером обмена Запретить вставку текста в TEdit из буфера обмена через Ctrl+V или через контекстное меню Обмена информации через сокеты Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Запустил конкурс "тем и промптов для текстовых квестов созданных почти чисто ИИ"
Adler 06.10.2026
Всем привет!
За последние три-четыре дня я создал более 16 текстовых квестовых игр используя преимущественно по одному запросу к ИИ на игру. Мне так понравилось смотреть все ветки/ сцены во всех. . .
|
ИИ не может найти нужный язык в списке
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
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
|
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#.
Название изменил на ColorStep.
Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
|
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами:
- ВидТО (СправочникСсылка. ВидыТО);
- ВидГСМ. . .
|
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала.
Ниже прикреплён. . .
|