Правильный подход обмена данных с устройствами через COM-порт. Целостность пакетов и производительность обмена26.02.2018, 23:52. Показов 21324. Ответов 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 или через контекстное меню Обмена информации через сокеты Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
сукцессия 30. Фосфорный и азотный замки по "честному" закону лимитирования Либиха
anaschu 16.07.2026
Основные достижения за последние дни
1. Механизм отложенного высвобождения фосфора
Добавлен специальный пул для медленного разложения меланизированных гиф ЕСМ
Реализована разная скорость. . .
|
Запрет пометки на удаление и отмены проведения
Maks 16.07.2026
Алгоритм из решения ниже реализован на нетиповом документе "ПутевойЛист" разработанного в КА2.
Задача: запретить помечать на удаление и отменять проведения путевого листа при условии, если он сдан. . .
|
Как надо было делать правильно - вообще не слушать ИИ, его дело - текст.
Hrethgir 15.07.2026
А вообще надо было делать не так, чтобы не исправлять ошибку https:/ / www. cyberforum. ru/ blogs/ 223907/ 10996. html , правильно было : удалил кнопку, а потом добавил её.
Всё это стресс конечно. Почему?. . .
|
Знаете, от чего появляется стресс?
kumehtar 15.07.2026
Стресс появляется оттого, что вы, зная как поступить правильно, делаете наоборот.
Ларри Уингет
|
|
Нас бьют, а мы крепчаем? Какая чушь!
kumehtar 15.07.2026
Вот это вот бытующее мнение, что человек меняется только под действием проблем, всегда считал вредоносным. Поверь, от проблем у людей появляются не изменения, а нервное расстройство и ПТСР. А. . .
|
сукцессия 29. Переход от одних деревьев на другие делать более или менее вероятностным?
anaschu 12.07.2026
Насколько смена типов микоризы — исключительное событие в двухвековой сукцессии? Оценка вероятности в пространстве параметров
В текущей версии модели успешно реализован ключевой механизм. . .
|
сукцессия 27. Думаю, как переделывать уже написанную статью с планами на сукцессию.
anaschu 12.07.2026
Анализ соответствия модели требованиям
Реализованные компоненты:
Механизм закисления почвы через протонную помпу
Конкуренция между типами микориз
pH как триггер сукцессии
C/ P соотношение. . .
|
Сукцессия 26. Мат модель создана.
anaschu 12.07.2026
Модель смены растительных сукцессий посредством управления грибами работает внутри небольшой ячейки почвы, восстанавливающейся после пожара, где ненадолго бывшее царство хвойных снова захватили. . .
|