Правильный подход обмена данных с устройствами через COM-порт. Целостность пакетов и производительность обмена26.02.2018, 23:52. Показов 21579. Ответов 71
Метки нет (Все метки)
Приветствую вас, коллеги!
Хочу с вами посоветоваться, ибо мне кажется, что я делаю это не совсем правильно, либо что-то не учёл... Делаю обмен данными с устройством через COM-порт (RS-232) по алгоритму: послал команду в порт (через .Write(...)), поставил задержку (Threading.Sleep(200)), читаю ответ (через .Read(...)). И вот тут меня смущает эта самая задержка. Если ответные пакеты приходят большие (ну например более 60 байтов), то что бы вычитать весь буфер, этой задержки как буд-то не хватает, пакет получаю не весь. Если увеличиваю задержку, то буфер весь вычитывается, однако, во-первых, буфера могут быть разной длины, и для каждого так подбирать задержки - не реально, во-вторых, если с устройством есть возможность обмениваться на разных скоростях (бод), это вообще дур-дом и всякая актуальность, например, выбора более высокой скорости обмена теряется, т.к. задержки будут одинаковыми, если их так железно задавать... В-третьих, когда такая функция обмена, с железно заданным Sleep'ом (подобранным на вскидку, чтоб не потерять большие пакеты), в цикле, например, ведёт обмен, то для более мелких пакетов, такая задержка, опять же, становится не актуальной, т.к. увеличивается драгоценное время простоя, и обмен происходит дольше, чем мог бы быть... Вот по этому я и задаюсь вопросом: как в таком случае правильно следует поступать? Не ужели чем длиннее ответный пакет, тем дольше его нужно ждать, чтоб он вычитался? Как избежать таких диких задержек? У кого был подобный опыт с обменом по СОМ-порту с устройствами, подскажите, пожалуйста, или поделитесь идеями, кто хотя бы понял суть вопроса. P.S. слышал что-то про подход асинхронного чтения данных из порта, но пока не понял что это и с чем это едят, и мой ли это вообще случай. Если да, то расскажите про такой подход, кто в курсе вообще. Только по понятнее пожалуйста, с примерами, если можно, а то про асинхронные приёмы работы пока вообще не в теме... Особо не доводилось использовать.
0
|
|
| 26.02.2018, 23:52 | |
|
Ответы с готовыми решениями:
71
Организация обмена данными через LPT-порт Функция для обмена HEX данными через COM порт Синхронизация обмена данных через LiFi |
|
|
|
| 19.04.2018, 13:31 | |
|
0
|
|
| 21.04.2018, 14:46 [ТС] | |||||||
... Буду признателен, если сможете наглядно это показать. ![]() Я вот тут так поразмыслил, а что, если преобразовать метод static void com_OnReceiving(object sender, RTSerialCom.DataStreamEventArgs e) в асинхроныый, добавив ему ключевое слово async, а потом в функции SendCommand, после Transmit, вызывать его через await? В таком случае, по идее, можно будет вообще избавиться от Thread.Sleep между посылкой и ожиданием получения ответа... Т.к. await должен сам по себе заставить вызывающий поток подождать, пока отработает вызываемый метод, а за тем уже продолжить дальше свои действия. Что думаете на этот счёт? Добавлено через 15 часов 34 минуты Если я правильно разобрался в применении BeginInvoke/EndInvoke, то мой код должен измениться так (наверное):
0
|
|||||||
| 23.04.2018, 10:52 [ТС] | |
|
Storm23, нет, всё же что-то я таки не так сделал, или не дописал... Сдаётся мне, что в параметры BeginInvoke нужно что-то другое а не null передать, как минимум первый параметр типа object мне кажется нужно передать, но я не знаю как правильно это сделать, ибо this не передаётся т.к. эти функции у меня находятся в основном статическом классе Program.cs
Или же я в принципе не правильно понял подход?
0
|
|
| 24.04.2018, 18:59 [ТС] | |
|
В общем вся затея псу под хвост. Видимо моя задумка утопична.
Как ни пробовал добиться передать уведомление основному потоку, что событие случилось и обработка в нём отработала, всё тщетно. То ли я не правильно эти механизмы синхронизации применяю, то ли в принципе подход не верный, либо действительно, от слипов между посылкой пакета и перехватом ответа не обойтись (чего я собственно и пытаюсь отчаянно добиться).
0
|
|
| 24.04.2018, 20:13 [ТС] | |
|
0
|
|
|
|
|
| 24.04.2018, 20:21 | |
|
Процент загрузки e.ProgressPercentage строка 109
Я такой применяю способ. Но он не единственный существующий и не единственно верный.
0
|
|
| 24.04.2018, 20:42 [ТС] | |||||||||||
|
Rius, Чуть позже ознакомлюсь с этой ссылкой. Спасибо.
А пока поделюсь своими наблюдениями в этой проблеме... Такое чувство, что решение у меня под носом, но я чего-то не доделываю... Или недопонимаю... Я покажу что имею. И объясню где что пытаюсь получить, но не получается)) Есть класс с реализацией методов по обмену данных СОМ-порта. В нём есть событие, возникающее в момент получения данных в порт и метод этого события. classA.cs
я в этой функции подписываюсь на это событие, а в методе подписанном на него, делаю обработку полученных данных. Program.cs
0
|
|||||||||||
| 24.04.2018, 23:34 [ТС] | ||
|
Добавлено через 16 минут Кстати, var task = Task.Factory.StartNew(...); я тоже пробовал. Пробовал даже через task.Wait(); чтоб дождаться, как я надеялся, срабатывания события и выполнения обработчика... Но почему-то так всё равно не сработало...
0
|
||
|
|
|
| 25.04.2018, 07:29 | |
|
Cha1000000,
одно дело передать в поток UI что-то принятое; а другое - удостовериться в принятии ответа и послать новый запрос. Эти вещи не обязаны выполняться в одном месте. Оставьте поток UI в покое и в качестве флага применяйте что-то типа AutoResetEvent. Его и из потока можно установить, и ожидать установки можно.
0
|
|
| 25.04.2018, 19:07 [ТС] | ||
|
Storm23, Вам ещё раз отдельное спасибо за предложенные примеры рабочих проектов!
0
|
||
| 25.04.2018, 19:07 | |
|
Виртуальный COM-порт на STM32, скорость обмена.
COM-порт, работа с двумя формами и одним буфером обмена Запретить вставку текста в TEdit из буфера обмена через Ctrl+V или через контекстное меню Обмена информации через сокеты Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Мобильное приложение 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 и пр.
Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала.
Ниже прикреплён. . .
|
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F
Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU.
Опрашиваются регистры. . .
|
|
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка:
Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
|
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо
Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
|
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман.
Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
|
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
|