Форум программистов, компьютерный форум, киберфорум
Наши страницы
C# Windows Forms
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 5.00/8: Рейтинг темы: голосов - 8, средняя оценка - 5.00
Cha1000000
2 / 2 / 2
Регистрация: 04.06.2015
Сообщений: 227
Записей в блоге: 1
1

Правильный подход обмена данных с устройствами через COM-порт. Целостность пакетов и производительность обмена

26.02.2018, 23:52. Просмотров 1606. Ответов 71
Метки нет (Все метки)

Приветствую вас, коллеги!
Хочу с вами посоветоваться, ибо мне кажется, что я делаю это не совсем правильно, либо что-то не учёл...
Делаю обмен данными с устройством через COM-порт (RS-232) по алгоритму: послал команду в порт (через .Write(...)), поставил задержку (Threading.Sleep(200)), читаю ответ (через .Read(...)). И вот тут меня смущает эта самая задержка. Если ответные пакеты приходят большие (ну например более 60 байтов), то что бы вычитать весь буфер, этой задержки как буд-то не хватает, пакет получаю не весь. Если увеличиваю задержку, то буфер весь вычитывается, однако, во-первых, буфера могут быть разной длины, и для каждого так подбирать задержки - не реально, во-вторых, если с устройством есть возможность обмениваться на разных скоростях (бод), это вообще дур-дом и всякая актуальность, например, выбора более высокой скорости обмена теряется, т.к. задержки будут одинаковыми, если их так железно задавать... В-третьих, когда такая функция обмена, с железно заданным Sleep'ом (подобранным на вскидку, чтоб не потерять большие пакеты), в цикле, например, ведёт обмен, то для более мелких пакетов, такая задержка, опять же, становится не актуальной, т.к. увеличивается драгоценное время простоя, и обмен происходит дольше, чем мог бы быть... Вот по этому я и задаюсь вопросом: как в таком случае правильно следует поступать? Не ужели чем длиннее ответный пакет, тем дольше его нужно ждать, чтоб он вычитался? Как избежать таких диких задержек? У кого был подобный опыт с обменом по СОМ-порту с устройствами, подскажите, пожалуйста, или поделитесь идеями, кто хотя бы понял суть вопроса.

P.S. слышал что-то про подход асинхронного чтения данных из порта, но пока не понял что это и с чем это едят, и мой ли это вообще случай. Если да, то расскажите про такой подход, кто в курсе вообще. Только по понятнее пожалуйста, с примерами, если можно, а то про асинхронные приёмы работы пока вообще не в теме... Особо не доводилось использовать.

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.02.2018, 23:52
Ответы с готовыми решениями:

Управление буфером обмена через другой поток
Надо удалять, добавлять, изменять буфер обмена через фоновой поток. //При...

Вставка множественных данных из буффера обмена в DevExpress GridControl v7.2
Добрый день. Подскажите, может кто сталкивался: Существует необходимость...

Правильный подход при взаимодйствии с Windows Forms
Смотрите, в PHP есть такой подход в написании сайтов (web-приложений) - MVC,...

Сервер на PHP + клиент на C#. Организовать процесс обмена данными клиента через PHP на сервере
Всем привет. Подскажите, как реализовать. Сейчас есть: сервер и клиент на...

Организация обмена данными через LPT-порт
разработайте программу определения адреса LPT - порта и вывода информации через...

71
Rius
Эксперт .NET
5127 / 3349 / 818
Регистрация: 25.05.2015
Сообщений: 10,282
Записей в блоге: 11
Завершенные тесты: 4
27.02.2018, 08:13 2
Цитата Сообщение от Cha1000000 Посмотреть сообщение
как в таком случае правильно следует поступать?
Не использовать Sleep вообще.
Цитата Сообщение от Cha1000000 Посмотреть сообщение
Как избежать таких диких задержек?
Полагаться на таймауты. Которые должны быть хорошо заметными при обмене вида запрос-ответ.

Чтение с последовательного порта без использования Sleep
Команда протокола формата запрос-ответ
1
Cha1000000
2 / 2 / 2
Регистрация: 04.06.2015
Сообщений: 227
Записей в блоге: 1
27.02.2018, 10:12  [ТС] 3
Цитата Сообщение от Rius Посмотреть сообщение
Полагаться на таймауты.
Таймауты чтения я уже тоже ставил высокие, но какие бы не ставил, если уменьшал слипы, или убирал их вовсе, большие пакеты полностью не долетали...
Почитаю инфу по вашим ссылкам. Спасибо, надеюсь поможет.
0
Rius
Эксперт .NET
5127 / 3349 / 818
Регистрация: 25.05.2015
Сообщений: 10,282
Записей в блоге: 11
Завершенные тесты: 4
27.02.2018, 10:32 4
Цитата Сообщение от Cha1000000 Посмотреть сообщение
Таймауты чтения я уже тоже ставил высокие, но какие бы не ставил, если уменьшал слипы, или убирал их вовсе, большие пакеты полностью не долетали...
Почитайте. Там описан приём (метод/способ) двух таймаутов. В этом отличие.
0
Cha1000000
2 / 2 / 2
Регистрация: 04.06.2015
Сообщений: 227
Записей в блоге: 1
13.03.2018, 10:37  [ТС] 5
Цитата Сообщение от Rius Посмотреть сообщение
метод/способ двух таймаутов
Заметил очень любопытную и непонятную мне пока ситуацию. На одном и том же ПК стоит ОС Windows 10 и Windows 7. Запускаю программу, с реализованным алгоритмом двух таймаутов, на семёрке, цикл чтения данных определённого кол-ва ответов от устройства, занимает время примерно в 2,5 раза быстрее, чем при тех же условиях, с теми же таймаутами, но запуская программу в десятке. WTF??? Проверенно на трёх разных ПК, где есть и 7 и 10. Странно, ведь 10ка вроде как в принципе сейчас по шустрее даже 7ки, особенно на неслабых ПК, но при этом чтение данных происходит ощутимо медленнее... В чём может быть тонкость, или какая-то особенность? Мелкософт либо забил на применение СОМ-портов в 10ке и не оптимизировал их реализацию в этой ОС (типа это уже реликт почти)??? ))
Или всё же что-то можно с этим сделать? И вообще, сравнивая работу программы на ПК разных характеристик и мощностей, и установленных на них ОС, заметна и ощутима разница времени циклов чтения одних и тех же данных. Причем, на средне-мощном и мощнее ПК, с семёркой подобрал максимально низкие таймауты и обмен проходит быстро, а вот при этих же таймаутах на компах чуть слабее и с ХР на борту, с такими таймаутами ответы от устройства уже недочитываются и таймауты приходится повышать, подстраиваясь под такие, более слабые ПК, что в свою очередь тогда увеличит кол-во времени и на ПК по мощнее... Вот такой вот замкнутый круг получается... Как бы осуществить некую универсальность для этого? Есть мысли?
0
Rius
Эксперт .NET
5127 / 3349 / 818
Регистрация: 25.05.2015
Сообщений: 10,282
Записей в блоге: 11
Завершенные тесты: 4
13.03.2018, 10:44 6
Какой baudrate при обмене и какие именно значения таймаутов выставляете?
Какая длина посылки при наблюдении проблемы?
0
Cha1000000
2 / 2 / 2
Регистрация: 04.06.2015
Сообщений: 227
Записей в блоге: 1
13.03.2018, 11:05  [ТС] 7
Цитата Сообщение от Rius Посмотреть сообщение
Какой baudrate при обмене и какие именно значения таймаутов выставляете?
Пробовал на BaudRate 9600 и 115200 (устройство может и на той и на другой скорости работать, но в нём предварительно это тоже нужно задать). При сравнении на разных ОСях, какую бы скорость не выбрал, в целом по времени все равно разница большая, как описывал выше.

Таймауты на приём первого байта и на последующие подобрал 100, 50 (соответственно). Это на более-менее мощных и мощнее ПК проходит, а для ПК послабее и с ХР ставил 300, 100.

Цитата Сообщение от Rius Посмотреть сообщение
Какая длина посылки при наблюдении проблемы?
Посылки, читаемые из устройства могут достигать максимальной длины 255 байт. Причем в цикле чтения, о котором я говорю все принимаемые посылки равной длины (примерно 180 байт, точнее не помню сейчас).
0
Rius
Эксперт .NET
5127 / 3349 / 818
Регистрация: 25.05.2015
Сообщений: 10,282
Записей в блоге: 11
Завершенные тесты: 4
13.03.2018, 13:37 8
Я ставил 500 мс на начало, хватало везде. Меньшие значения только на коротких пакетах. Попробовал меньшие значения на больших пакетах - действительно не работает определение начала приёма.
Устройство определённо начало отсылать ответную посылку через 5 мс после завершения приёма запроса. Но даже с 50 мс ReadByte(), Read() и BytesToRead реагируют правильно только после завершения приёма всей посылки.
Так что этот метод вам не подойдёт.
А мне надо будет затестить, как себя WinAPI поведёт.

Не по теме:

Цитата Сообщение от Cha1000000 Посмотреть сообщение
В чём может быть тонкость, или какая-то особенность? Мелкософт либо забил на применение СОМ-портов в 10ке и не оптимизировал их реализацию в этой ОС (типа это уже реликт почти)??? ))
Microsoft просто не позиционировал Windows как ОС реального времени.

0
Cha1000000
2 / 2 / 2
Регистрация: 04.06.2015
Сообщений: 227
Записей в блоге: 1
13.03.2018, 14:11  [ТС] 9
Цитата Сообщение от Rius Посмотреть сообщение
А мне надо будет затестить, как себя WinAPI поведёт.
Не забудьте потом рассказать
Цитата Сообщение от Rius Посмотреть сообщение
Так что этот метод вам не подойдёт.
В смысле, метод двух таймаутов?? А какой тогда подойдёт лучше?
0
Rius
Эксперт .NET
5127 / 3349 / 818
Регистрация: 25.05.2015
Сообщений: 10,282
Записей в блоге: 11
Завершенные тесты: 4
13.03.2018, 14:14 10
Цитата Сообщение от Cha1000000 Посмотреть сообщение
В смысле, метод двух таймаутов?? А какой тогда подойдёт лучше?
Да. Он работает на RTOS + С/С++, а на Windows + .Net не очень, как оказывается.

Это надо ещё разбираться.
0
Cha1000000
2 / 2 / 2
Регистрация: 04.06.2015
Сообщений: 227
Записей в блоге: 1
13.03.2018, 14:34  [ТС] 11


Цитата Сообщение от Rius Посмотреть сообщение
Он работает на RTOS + С/С++, а на Windows + .Net не очень, как оказывается.
Ну не совсем так... Раньше, когда я использовал один таймаут на чтение всего буфера, и слипы, время обмена было в разы дольше... так, что хоть с этим, но уже выигрыш...
0
Cha1000000
2 / 2 / 2
Регистрация: 04.06.2015
Сообщений: 227
Записей в блоге: 1
07.04.2018, 11:38  [ТС] 12
Всем добрый день!
Хотелось бы продолжить тему. Ибо пока универсальное решение я так и не нашёл, которое бы меня удовлетворило. А вопросы появляются и остаются не до конца раскрытыми.
И так, может ли кто-то объяснить, действительно ли при одинаково выбранной скорости обмена (BaudRate) и одинаковых (заданных в коде программы "железно") таймаутах, но на компах разной производительности и с разными ОС (семейства Windows) на борту, время, за которое происходят одинаковые циклы обмена данными с устройством, заметно и значительно отличаются? Это первое, что не совсем понятно.
А второе: с чем может быть связано то, что на одном и том же ПК, но на разных ОС (в частности на 7 и 10), так же, если запустить цикл обмена данными, то на 10ке он раз в 5 дольше проходит???
В настройках СОМ-порта в диспетчере устройств, в обеих ОС отключил использование буферов FIFO (на всякий случай, ибо из многих разных источников слышал, что это (не помню точно для чего) помогает, а на практике сталкивался, что действительно, снятие этой галочки, решало проблемы с отсутствием связи в принципе...). Кстати, как в C# программно его отключить при настройке порта я так и не нашёл. Кто знает, подскажите, пожалуйста!

Цитата Сообщение от Rius Посмотреть сообщение
Я ставил 500 мс на начало, хватало везде.
Да, 500 вроде как хватает и на мощных ПК и на ПК по слабее. Однако, если на компе, что по мощнее, выставить это значение, скажем, в 200, обмен тоже проходит успешно, а по времени выходит вроде как чуть быстрее. По этому для работы программы на таких ПК жаль жертвовать этим выигрышам во времени. Может есть способ как-то обеспечить некую универсальность для ПК разных производительностей? Чтоб, к примеру, для слабеньких ПК оставлять значение 500, а для
ПК по шустрее, на 200-250... Или как-то ещё...
И кстати, как проходят ваши исследования в WinAPI по этому вопросу?
0
Rius
Эксперт .NET
5127 / 3349 / 818
Регистрация: 25.05.2015
Сообщений: 10,282
Записей в блоге: 11
Завершенные тесты: 4
07.04.2018, 17:29 13
Cha1000000,
Первое : Windows не является RTOS. Время её реакции на события пригодно для пользователя обыкновенного. Но оно не детерминировано.

Цитата Сообщение от Cha1000000 Посмотреть сообщение
И кстати, как проходят ваши исследования в WinAPI по этому вопросу?
Последние месяцы занят разработкой устройства с USB интерфейсом, времени на посторонние опыты нет.
0
insite2012
Модератор
Эксперт .NET
4865 / 3818 / 1096
Регистрация: 12.10.2013
Сообщений: 11,095
Записей в блоге: 2
07.04.2018, 18:22 14
Cha1000000, ответ на ваш вопрос зависит от того, специфицирован ли ваш обмен данными с устройством (проще говоря, знаете ли вы в каждый момент после отправки пакета, сколько именно данных должно прийти).
Если знаете-то тут особо ничего сложного не будет, цикл с задержкой и проверкой буфера приема порта (да, это может и не айс, но я сколько не экспериментировал, и с тем кодом что тут предлагали не раз, и со своими вариантами-лучшего варианта, который бы гарантировано работал на всех ПК без сбоев не нашел).
0
Rius
Эксперт .NET
5127 / 3349 / 818
Регистрация: 25.05.2015
Сообщений: 10,282
Записей в блоге: 11
Завершенные тесты: 4
07.04.2018, 18:33 15
insite2012, а задержка какая? На высокочастотном счётчике или обычном слипе? И как на одноядерных ПК работает?
0
insite2012
Модератор
Эксперт .NET
4865 / 3818 / 1096
Регистрация: 12.10.2013
Сообщений: 11,095
Записей в блоге: 2
07.04.2018, 18:43 16
Rius, я делал и так, и эдак. Но в самом простом случае-простой слип. Да, как я выше сказал, вариант не идеальный, но в моем случае лучшего просто нет (поверьте, поэкспериментировал достаточно). Там сама связка довольно сложна, обмен с мк по RxD/TxD, потом он уже обменивается по шине IIC с другим мк, и возврат ответа по той же схеме.
Если не прокручивать задержку - то не на всех ПК стабильно работает.
Да, работает стабильно на любых ПК (я сам проверяю на нескольких, поскольку приложение не тестовое, а рабочее).
Кстати, неоднократно приходилось декомпилировать чужой код (приложения для работы с последовательным портом, только протокол другой), и тоже в том или ином варианте используется тот же подход.
1
Rius
Эксперт .NET
5127 / 3349 / 818
Регистрация: 25.05.2015
Сообщений: 10,282
Записей в блоге: 11
Завершенные тесты: 4
07.04.2018, 18:45 17
Спасибо, тоже надо будет попробовать.

Простой слип смущает тем, что он работает или с дискретностью 1 мс при задействовании мультимедиа, или с 50 мс без неё.
А счётчик - загзрузкой процессора...
0
Cha1000000
2 / 2 / 2
Регистрация: 04.06.2015
Сообщений: 227
Записей в блоге: 1
07.04.2018, 18:46  [ТС] 18
Цитата Сообщение от insite2012 Посмотреть сообщение
цикл с задержкой
Не, не, не... Если речь идёт о слипе, то в топку такие задержки! У меня был реализован алгоритм со слипом... Да вроде стабильность была, и вроде даже по времени особо не отличалось на разных компах с разной производительностью... Но я стремлюсь максимально, на сколько это возможно, уменьшить время, за которое будет проходить обмен. И в этом случае метод двух тайм-аутов, ранее предложенный Rius'ом, показал лучшие по времени результаты, чем вариант со слипом. Вот только время обмена на компах с разной производительностью и разными ОС отличается... Вот это мне не нравится((
0
insite2012
Модератор
Эксперт .NET
4865 / 3818 / 1096
Регистрация: 12.10.2013
Сообщений: 11,095
Записей в блоге: 2
07.04.2018, 18:50 19
Цитата Сообщение от Rius Посмотреть сообщение
тоже надо будет попробовать.
Пробуйте. В моем случае вариантов других просто не было. Несколько типов мк на целевых устройствах, плюс еще само железо для обмена разное-настоящий порт, эмулированный через переходник, эмулированный через БТ канал.
0
Rius
Эксперт .NET
5127 / 3349 / 818
Регистрация: 25.05.2015
Сообщений: 10,282
Записей в блоге: 11
Завершенные тесты: 4
07.04.2018, 18:52 20
insite2012, а посылки у вас были заранее известного объёма?
0
07.04.2018, 18:52
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
07.04.2018, 18:52

Функция для обмена HEX данными через COM порт
Помогите реализовать функцию работы с COM портом в консольном приложении....

Синхронизация обмена данных через LiFi
Здравствуйте. Никак не могу придумать способ реализации обмена через свет. ...

Виртуальный COM-порт на STM32, скорость обмена.
Всем привет. Прошу помощи :) Экспериментирую с USB - CDC-класс, стоит задача...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru