|
|
|
Класс для COM-порта с поддержкой событий05.09.2014, 11:48. Показов 12406. Ответов 30
Доброго. Мне нужен класс для работы с COM-портом с поддержкой событий.
У меня есть вариант: Serial Port Communication in Excel (VBA). Я его использую в Excel. Проблема в том, что нужно ручками регулировать время между командой и ответом, чтобы гарантировано принять данные во входной буфер. Хотелось бы иметь событие OnReceive(), которое основано на WaitCommEvent(). Без событийного решения трудно реализовать оптимальный по скорости алгоритм работы с устройствами. Мне нужно с определённой частотой читать данные и желательно получать их по мере заполнения входного буфера нужной посылкой. Можно ли что-то такое сделать на vb6? Мне не нужны сторонние решения в готовом виде (ActiveX, dll и т.п.). Нужно всё реализовать на макросах в таблице.
0
|
|
| 05.09.2014, 11:48 | |
|
Ответы с готовыми решениями:
30
Календарь событий с заметками и поддержкой файлов Кто встречал контрол типа стандартного Line, но с поддержкой событий? |
|
Модератор
|
|||
| 18.09.2014, 18:00 | |||
|
0
|
|||
|
|
|||||||
| 18.09.2014, 21:03 [ТС] | |||||||
|
Я эффект замеряю статистически как разницу во времени при разных подходах. Монитор показывает дамп обмена по последовательному порту.
У меня есть прибор, который шлёт посылки с частотой 10 Гц без команд. Я должен их гарантировано принять. Код выше, который я нашёл в сети, не имеет прямого метода ожидания приёма, поэтому для гарантированного приёма мне приходилось обходить недостаток функционала. Самый простой способ - добавить задержку в 1-2 интервала между посылками и читать буфер. Это работало, но я не мог достичь скорости 10 Гц из-за искусственных задержек. Поэтому я пришёл к более сложному методу с флагами и дополнительными winapi-функциями. Написал программу на с++ и сравнил в тех же условиях разницу по времени между запросом и ответом. На картинке выше изображен результат работы с другим прибором, у которого скорость можно задать до 38400 бод и возможно достичь скорости 45 отсчётов/сек. В текущем приборе тем же методом на скорости 9600 бод задержки были 150 мсек в среднем. Моя программа на c++ уменьшила это число в три раза, плюс даёт больше возможностей по синхронизации. В предыдущей версии для изменения частоты опроса я менял задержку и это приводило к пропускам (системный буфер у меня сбрасывается каждый раз). The trick, ты вообще на низком уровне с железом работал когда-нибудь? Ты знаешь назначение таймаутов операций чтения байтов? Через сколько буферов проходит байт прежде, чем он от провода придёт ко мне в программу? У меня такое чувство, что ты никогда не видел как ведётся отладка программы, которая работает с COM-портом. Вот пример лога, который я снял при работе с прибором в командном режиме на скорости 9600 бод (8-N-1):
Добавлено через 1 час 32 минуты Это сильные ограничения, но WinAPI тебе доступен. Далее, ты находишь в сети готовый код, который работает, но не совсем. К примеру, в командном режиме, если ты делаешь так: 1. Сброс буферов записи и чтения Windows. 2. WriteFile 3. ReadFile то это не работает (программный буфер пустой), а если ты делаешь так: 1. Сброс буферов записи и чтения Windows. 2. WriteFile 3. Sleep(100) 4. ReadFile то ответ всегда можно считать из приёмного буфера Windows. Можешь с ходу указать в том исходнике почему так? Вот отсюда все и проблемы. Sleep(100) на самом деле эмпирическая вещь, кроме того есть неучтённые задержки, которые зависят от производительности компа (мы работаем в Excel). Это +/- 20-50 мсек, точно не знаю. А эти задержки на больших скоростях уже сопоставимы с длиной пакетов байт команд. Считать-то мы уже умеем? Я уж не упоминаю DoEvents, которая там в коде используется для сброса буфера записи в физический порт. Это что-то вообще ненормальное. Так вот, чтобы понять, почему ReadFile там не ждёт посылки, а сразу возвращает управление, нужно разобраться в инициализации порта, используемом алгоритме и хорошо прочитать MSDN. И совершенно параллельно каким образом тут ReadFile работает с буфером пользователя.
0
|
|||||||
|
Модератор
|
|||||||||||||
| 18.09.2014, 21:31 | |||||||||||||
Сообщение было отмечено The trick как решение
Решение
Ты передаешь String по значению - это обозначает автоматическую конвертацию строки из Unicode в Ansi перед вызовом функции, передачи Ansi буфера в функцию и конвертации из Ansi в Unicode буфера при выходе из функции. Это знает любой более-менее разбирающийся программист на VB6. Смотри - у тебя асинхронная запись в буфер, т.е. после выхода из функции данные в буфер будут писаться в него, а у тебя уже этого временного буфера нет (данные пишутся в никуда, хорошо что приложение не вылетает и число прочитанных байт соответствуют истине), а с исходной строкой ничего не происходит, она вообще не участвует в операции. Если ты передашь туда указатель на первый элемент массива - то они будут писаться туда и никуда больше. И как после такого можно говорить о неважности типа?
0
|
|||||||||||||
|
|
||
| 18.09.2014, 22:06 [ТС] | ||
|
Молодец, приятно увидеть логичные рассуждения. Этот факт я не учитывал, так как не обратил внимания на ByVal по причине уже работающего кода. Мог бы и раньше сделать такое пояснение, оно не очевидное.
0
|
||
|
Модератор
|
||||
| 18.09.2014, 22:21 | ||||
|
0
|
||||
|
|
|||
| 19.09.2014, 10:18 [ТС] | |||
|
Я имел в виду двойную неявную конвертацию String при использовании WinAPI в vb6. Я к этому не привык. Ни за что бы не догадался о таком подводном камне.
На самом деле меня конечно смутило такое обертывание ReadFile, так как мне удобнее было работать с байтами (в примере выше текстовый протокол, есть ещё бинарный), но это строковое представление в коде сильно завязано и мне просто лень было всё переделывать, считай, писать заново. Добавлено через 13 минут Чтобы пока сильно не переделывать, попробую совет отсюда тоже:
Замена на байтовый буфер заработала. Признаю свою ошибку и ограниченность знания внутренней кухни vb6 при работе с WinAPI.
0
|
|||
|
|
|
| 25.09.2014, 08:43 [ТС] | |
|
Получил хорошие результаты с конкретным прибором. Длина команды 4 байта, ответа - 6 байт, скорость - 38400 бод. Получается теоретическое минимальное время между запросами: 10 / 3840 байт/сек ~= 2,6 мс. Практически у меня сейчас получается 180 Гц ~ 5,6 мсек (у меня введена дополнительная задержка между командой и ответом в 1 мсек). Стабильность между запросами пытаюсь поддерживать при помощи QueryPerformanceCounter(), регулируя задержку, которую делаю при помощи Sleep(). Но сам Sleep(), я думаю, не всегда может точно выдержать интервал в несколько мсек, хотя результаты достаточно стабильны: 5-6 мсек между отсчётами.
Зазубрины на графике связаны с ограниченной частотой измерения в самом приборе. Результаты для COM-порта и переходника USB-COM (Moxa) получились практически одинаковыми. Асинхронный режим работы позволил увеличить частоту опроса с 50 Гц до 180 Гц. Код оформлен в виде макросов для Excel.
0
|
|
|
|
|
| 25.09.2014, 09:10 [ТС] | |
|
Надо же, это заработало. Мне не пришло такое в голову, спасибо за идею. Я вбил в мониторе 10 байтов нулей между командами (длина ответа 6 байт) и прибор ответил на каждую. Пробовал пока вручную 2 и 3 команды.
0
|
|
| 25.09.2014, 09:10 | |
|
Класс длинная арифметика с поддержкой арифметических операций Нужен батник для создания отчета событий и их свойств из журнала событий на локальном компьютере Реализовать хранилище событий, для хранения событий в БД Подскажите бесплатный хостинг с поддержкой MySQL баз и с поддержкой внешних подключений к базе данных Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Паттерн очереди действий/команд (Action / Command Queue). Система очереди действий и кат-сцен с SDL3 Callbacks, cglm и OpenGL
8Observer8 07.11.2026
Содержание блога | English Version
Руководство для начинающих по реализации паттерна очереди действий/ команд (Action / Command Queue) на C++ (C++20) с использованием официального SDL3 Callbacks. . .
|
Проверка полного ФИО в типовом справочнике
Maks 07.11.2026
Решение реализовано в конфигурации КА2, на примере справочника "КонтактныеЛицаПартнеров".
Задача:
Запрет инициалов.
Не допускаеть использование сокращений вида "И. И. ", "И. И. ", "И И" и. . .
|
Про "Windows must die!"
kumehtar 04.11.2026
Знаете, чет накатило. . . .
Когда-то это было почти боевым кличем: мол, нормальный человек сидит на DOS, OS/ 2 или Linux, а вот это вот - Must Die. А теперь человек произносит «мастдай» с усмешкой - и. . .
|
Красочные поля с номером страницы svg+background-image
russiannick 04.11.2026
Красочные поля с номером страницы не менее важны чем в эпоху бумажных книг.
Посему спешу представить почтеннейшей публике этот важный инструмент который эти поля и формирует.
В процессе разработки. . .
|
|
Вступаем в новую фазу генерации favicons, векторную.
russiannick 02.11.2026
Теперь нет нужды скрывать что используется простой svg. Исходный код изображения помещаем в поле и жмем кнопку. Исходник преобразуется в вид корректный для помещения в favicon или в url(). Нажатие. . .
|
Генератор паролей (вариант №4)
Maks 01.11.2026
После публикации 3-го варианта генератора паролей, разослал его своим коллегам (с целью оценки), в итоге были получены следующие рекомендации:
1. Вернуть возможность использования знаков | 1 l I;. . .
|
Генератор паролей (вариант №3)
Maks 30.10.2026
Финальная версия генератора паролей 1С.
Доработка решения в этот раз коснулась только визуальной части, а именно, добавлен реквизит ДопПараметры (тип Булево), который скрывает/ отображает реквизиты:. . .
|
Магическое мышление и магия, современная наука не отличима от магии (говорит ИИ Джемени)
zorxor 30.10.2026
Джемени, расскажи, пожалуйста, что такое магическое мышление, что такое магия, почему современная наука чем-то напоминает магию?
Фраза «Любая достаточно развитая технология неотличима от магии». . .
|