Передача данных по COM-порту.

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
hclubmk
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 252
Зарегистрирован: 19.06.2009 (Пт) 14:23
Откуда: От-туда

Re: Передача данных по COM-порту.

Сообщение hclubmk » 08.05.2025 (Чт) 20:26

серверянин писал(а):Не стоит так завидовать.
Можете тоже попердеть в лужу - и будет Вам щастье :wink:
:mrgreen:
Научились ли Вы радоваться трудностям?

серверянин
Новичок
Новичок
 
Сообщения: 40
Зарегистрирован: 19.09.2023 (Вт) 8:00
Откуда: РФ

Re: Передача данных по COM-порту.

Сообщение серверянин » 08.05.2025 (Чт) 21:16

Ну, кто и пердит, а моим модулем, хоть он и неидеален, 698 человек уже пользуются. А Вы только язвить стараетесь, да и то не очень остро получается 8)

hclubmk
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 252
Зарегистрирован: 19.06.2009 (Пт) 14:23
Откуда: От-туда

Re: Передача данных по COM-порту.

Сообщение hclubmk » 08.05.2025 (Чт) 22:11

серверянин писал(а):698
я предложил тебе профессиональное решение, а ты ведешь себя как баттхёрт. Попробуй повзрослеть.
Научились ли Вы радоваться трудностям?

серверянин
Новичок
Новичок
 
Сообщения: 40
Зарегистрирован: 19.09.2023 (Вт) 8:00
Откуда: РФ

Re: Передача данных по COM-порту.

Сообщение серверянин » 08.05.2025 (Чт) 22:35

hclubmk писал(а): я предложил тебе профессиональное решение

Если это про тот драйвер времен WIN9x, то спасибо, не надо. У меня другой подход.

hclubmk
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 252
Зарегистрирован: 19.06.2009 (Пт) 14:23
Откуда: От-туда

Re: Передача данных по COM-порту.

Сообщение hclubmk » 08.05.2025 (Чт) 23:12

серверянин писал(а):Если это про тот драйвер времен WIN9x
ну-ка, ну-ка, расскажи мне про что-то новое в работе с com?
серверянин писал(а):У меня другой подход.
ага, через задний проход. Не позорься уже, и иди учить уроки, баттхёрт :mrgreen:
больше ответов не будет, с пассажиром серверянин всё плохо, просмотрел его посты - просто клиника.
Научились ли Вы радоваться трудностям?

серверянин
Новичок
Новичок
 
Сообщения: 40
Зарегистрирован: 19.09.2023 (Вт) 8:00
Откуда: РФ

Re: Передача данных по COM-порту.

Сообщение серверянин » 08.05.2025 (Чт) 23:48

hclubmk писал(а): ага, через задний проход. Не позорься уже, и иди учить уроки, баттхёрт :mrgreen:
больше ответов не будет, с пассажиром серверянин всё плохо, просмотрел его посты - просто клиника.
Ууууу, какой вонючей трольчатинкой понесло - аж до самого Киева.
Неее, я в такое не полезу, не моё амплуа.

hclubmk
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 252
Зарегистрирован: 19.06.2009 (Пт) 14:23
Откуда: От-туда

Re: Передача данных по COM-порту.

Сообщение hclubmk » 08.05.2025 (Чт) 23:49

Просьба к администрации форума удалить учетную запись пьяного подростка!
Научились ли Вы радоваться трудностям?

серверянин
Новичок
Новичок
 
Сообщения: 40
Зарегистрирован: 19.09.2023 (Вт) 8:00
Откуда: РФ

Re: Передача данных по COM-порту.

Сообщение серверянин » 09.05.2025 (Пт) 11:36

Итак, проигнорив тролля, продолжу по делу.

Бодания с искусственным интеллектом всё же не прошли бесполезно. Его советы помогли мне создать новую версию модуля для работы с COM-портами, которую выкладываю здесь ниже. По сравнению с предшествующей версией, здесь два главных улучшения.
Оформление в виде класса позволяет открывать несколько портов одновременно, а не один, как было в старой версии.
Во-вторых, преодолено ограничение на 9 номеров COM-а. Новый модуль открывает все номера. Я не мог это проверить на всех существовавших версиях Windows; возможно на очень древних может остаться проблема с двузначными номерами, но начиная с XP всё уже работает исправно.
Кроме того добавлен мелкий сервис, типа списка имеющихся портов.
Вызывать событие впрямую аппаратным прерыванием не получилось. Думаю, что в VB такое вряд ли возможно. Но удалось довольно похоже имитировать это через быстрый опрос в фоновом цикле. Но сразу же выяснилась странная заморочка: DoEvents почему-то не обрабатывает CheckBox-ы, поэтому во время цикла они перестают реагировать. Впрочем, все остальные кнопки продолжают нормально работать.
Хотя событийная модель теперь возможна, но практика показала, что вполне можно обойтись без использования событий, и в некоторых случаях даже удобнее, что я и рекомендую.

Модуль ориентирован на работу с устройствами, подключенными к последовательному порту (как например Ардуино). Обмен, как правило, происходит в такой последовательности: программа посылает устройству команду из одного или нескольких байт, устройство что-либо делает и посылает отчет о своем новом состоянии, и/или другие данные в ответ.
Отсюда происходят некоторые особенности, с которыми я столкнулся в использовании старого модуля.
Передача с компьютера происходит аппаратно, то есть программа бросает данные в буфер передачи и сразу же переходит к приему ответа. А устройство еще не начало отвечать, потому что даже команда ему еще до конца не передалась. Приходилось везде ставить задержки.
Теперь этого не нужно, я сделал передачу с контролем окончания передачи и прием с ожиданием прихода всех символов. Так что глобальное непрерывное ожидание теперь не очень-то и нужно.

Вот список свойств и методов, которые дает модуль.

.OpenCOM -открытие порта. Аргументом имеет номер порта числового типа (а не строкового), чтобы легко было перебирать в цикле. За ним возможны несколько необязательных аргументов: скорость (по умолчанию 9600), битность, четность и стопы - по умолчанию стандартный режим 8, N, 1. (Лично мне ни разу не потребовался другой).
Если порт открыт - возвращает True, в противном случае False, так что открытие порта можно ставить непосредственно в If, проверяя таким образом доступность порта, и одновременно сразу же открывая его тем самым.
Повторное открытие уже открытого порта не является ошибкой. Порт автоматически корректно закрывается и затем открывается вновь, возможно с другими параметрами и номером.

.ClosePort -закрытие порта. Обязательно должно быть выполнено перед выходом из программы. Поставить в Form_Unload. Попытка закрытия уже закрытого или не открытого порта допустима и не приводит к ошибкам. Аргументов не имеет и ничего не возвращает.

.WritePort - простая передача строки в порт. Аргумент - строка байтов, преобразованных в символы. Не возвращает ничего.
.WritePortWait -то же самое, но выполнение приостанавливается и продолжается после фактического завершения передачи всех байтов.

.ReadPort -прием из порта. Имеет необязательный аргумент: количество принимаемых символов. Если аргумент не указан, считывает всё, что на текущий момент было в буфере приема. Возвращает принятые данные в виде символьной строки. Не выполняет ожидания. Если никаких данных не было принято, возвращает пустую строку сразу.
.WaitReadPort -перед началом приема ожидает время, рассчитанное по количеству символов и скорости приемопередачи. Аргумент - количество принимаемых символов. Аргумент обязательный, так как невозможно сделать расчет для неопределенного количества. Если данных нет, возвращает пустую строку.
.LineReadPort -прием строки, завершенной кодами перевода строки (CrLf). Имеет аргументом таймаут в секундах (против зависания, если перевод строки не появился). Если аргумент нулевой, то прием без ожидания.
Возвращает строку данных с кодом CrLf включительно. Если CrLf нет, возвращает то, что есть.

В случае ошибки все функции устанавливают свое сообщение об ошибке в свойство .LastError, где оно может быть прочитано (кириллица).
Если после выполнения любого из действий ошибки не было, это свойство содержит пустую строку.
Если подключены события, то при ошибках записи вызывается событие _WriteFault
а при ошибках чтения- _ReadFault
В обоих передается строка ErrMsg содержащая то же, что и .LastError .
Открытие порта этих событий не вызывает, так как возвращает результат выполнения в булевском формате.

Свойство .WaitData - ожидание данных.
После кода приравнивания этому свойству значения True, выполнение приостанавливается, входя в цикл бесконечного ожидания прихода данных. Приходом первого же байта в порт, этот цикл завершается и выполнение команд продолжается дальше.
.WaitData не считывает данных, а только ожидает факта их прихода. Считывать после нее любой из команд чтения порта.
Если подключены события, то .WaitData вызывает событие _DataReady . С этим вариантом ожидание можно запустить глобально сразу при запуске программы. Но делать это следует не в Form_Load, так как выполнение приостанавливается и форма тогда не сможет загрузиться.
Запускать ожидание глобально следует в самом конце Form_Activate. Как это правильно сделать можно посмотреть в коде прилагаемой тестовой программы; там события реализованы.
Ожидание можно прервать, установив свойству .WaitData значение False.

.PurgeData -очищает все данные, обнуляет все очереди. Предназначено для защиты от случайно сохранившихся данных, могущих вызвать помехи для программы. Аргументов не имеет и ничего не возвращает.

.ListPorts -массив, содержит список номеров портов, имеющихся в системе. Начальный элемент массива (с индексом 0) содержит общее количество портов и соответствует размеру массива. Если он равен нулю, значит COM-портов на машине нет.
Остальные элементы массива содержат номера портов.

.Tag -свободная переменная универсального типа, не участвующая в выполнении. Предназначена для какого-нибудь временного хранения или передачи данных между подпрограммами.


Лицензия: опенсорс :) AS IS, что мог, то сделал; кому не нравится - пусть сделают лучше и выложат здесь ко всеобщему удовольствию :wink:
Вложения
comctlcls.zip
Модуль класса для работы с COM-портами
(10.19 Кб) Скачиваний: 5

Пред.

Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: AhrefsBot, Google-бот и гости: 3

    TopList  
cron