Конференция "Начинающим" » Работа с сом портом в асинхронном режиме
 
  • Юрий К (07.02.19 18:44) [0]
    Здравствуйте уважаемые форумчане!
    Я далеко не профи, поэтому прошу совета.

    Я пытаюсь работать с контроллером ( Ардуино ) через сом порт. Вроде все получается ( данные передаются и принимаются обеими сторонами ). Но пока в упрощенном варианте ( функционал нужен более сложный и как реализовать не совсем понятно ).

    В конечном итоге я хочу получить следующий функционал:
    Структура передаваемых/принимаемых данных ( флаг начала сообщения, id получателя, длинна сообщения, данные, контрольная сумма, флаг конца сообщения )
    На одной шине RS-485 планируется одновременная работа нескольких ведомых с мастером ( ПК ).

    ( Речь идет например о том, чтобы включить/выключить электродвигатель или переместить какое-либо исполнительное устройство и пр. )
    Поэтому важно, чтобы мастер был в курсе, что там делает ведомый.

    На каждое сообщение мастера ведомый должен отправить ответ-подтверждение.
    То есть, ПК отправляет команду. Контроллер считывает ее ( если совпадает ID получателя ) и отправляет мастеру подтверждение.

    Возникают следующие возможные комбинации этих событий:
    1. Команда корректно доставлена, исполнена, подтверждение корректно доставлено и получено ( штатный режим )
    2. Команда не дошла до получателя и контроллер ничего не сделал ( сбой передачи )
    3. Команда дошла до получателя, контроллер отправил подтверждение, но оно дошло не корректно ( сбой на приеме )
    4. Команда дошла, но не может быть выполнена по каким либо причинам.

    Когда речь идет о двигателях и пр. механике - потеря связи с мастером чревата тем, что ведомый бесконечно будет гонять двигатель, пока не сожжет его.
    Поэтому я реализовал со стороны контроллера через таймауты ( команды мастер повторяет через 500 мс, если через 1000 мс контроллер не получит команду - двигатель остановится. )

    А вот на стороне ПК я, если честно, не до конца понимаю, как лучше сделать:
    1. Всю работу с контроллером я пытаюсь вывести в отдельный класс ( TObject )
    2. Управление экземпляром класса из основного приложения через методы класса.
    3. Так же через методы и свойства планирую получать информацию о состоянии устройства ( все данные хранить внутри переменных экземпляра класса )

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

    Но есть одно "но" - пока основное приложение обрабатывает полученные данные может наступить следующее событие чтения из порта и данные обработаются не корректно.
    Как поступить?
    Создавать каждый раз новую переменную методом GetMem и передавать основному приложению ссылку? Потом уничтожать ( после обработки ).

    Может быть есть более изящный способ гонять туда-сюда данные. Подскажите.

    Второе. Как быть когда подтверждение от контроллера не пришло?
    Мои размышления:
    1. при отправке команды выставить флаг внутри экземпляра класса, мол ожидание подтверждения.
    2. Одновременно создаем отдельный поток, который будет отслеживать время ожидания.
    3. Как только время таймаута истекло - генерируется событие "нет ответа" или "потеря связи". Отправка команды повторяется.
    4. Если во время ожидания пришло сообщение от контроллера анализируем его и по результатам анализа принимаем решение все нормально или что-то сбойнуло и повторяем отправку команды по новой.

    Вот как-то так... Только я уже начал путаться в реализации сего алгоритма. Получается коряво... Может кто подскажет более изящное решение?
    Заранее спасибо.
  • RWolf © (07.02.19 21:49) [1]

    > способ гонять туда-сюда данные


    Данные кладутся в потокобезопасную очередь, форме посылается сообщение о наличии данных в очереди. Для организации очереди можно использовать TThreadList.
  • ВладОшин © (08.02.19 10:29) [2]
    паттерн "машина состояний"
  • Германн © (09.02.19 02:55) [3]

    > Работа с сом портом в асинхронном режиме
    >
    > Юрий К   (07.02.19 18:44)

    Вот название темы у вас полностью соответствует вашей задаче. А предложенные варианты решения ни к чёрту не годятся. Да и вообще не из той оперы.
    СОМ-порт в IBM PC, с которого и началось семейство тех компьютеров, с которыми мы сейчас работаем (Макинтоши не в счёт, они слишком дороги), изначально предполагался к использованию в асинхронном режиме. Для чего в MS-DOS были назначены соответствующие аппаратные прерывания. MS-DOS канула в лету, но Билл Гейтс и Ко не отказались от асинхронной работы с СОМ-портом. Они создали Event'ы. https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-setcommmask
  • Германн © (09.02.19 03:12) [4]

    > А вот на стороне ПК я, если честно, не до конца понимаю,
    >  как лучше сделать:
    > 1. Всю работу с контроллером я пытаюсь вывести в отдельный
    > класс ( TObject )

    Это неправильно. Обменом данными управляет мастер. Т.е. ПО на компьютере. А ваш класс связанный с контроллером должен только уметь принимать "куски" данных, склеивать их и расшифровывать.
  • Юрий К (09.02.19 11:06) [5]
    to Германн

    Я уже понял, что облажался. Приложение работающее с ком портом получает к нему монопольный в системе доступ.

    Я планировал, что каждый экземпляр класса будет работать с портом напрямую, но не получится. Придется так:

    1. Количество экземпляров класса равно количеству контроллеров на шине.
    2. Есть кусок кода, состоящий из глобальных переменных и процедур чтения/записи в порт, который должен принимать от классов данные на запись, и отправлять их в порядке очереди, а так же получать из порта данные, и рассылать всем заинтересованным.
    3. Дальше уже каждый экземпляр решает для него эти данные или нет. И если да, обрабатывает их.
    4. Таймауты ожидания реализовывать внутри каждого экземпляра класса.

    Как-то так...
  • Германн © (10.02.19 02:49) [6]
    to Юрий К

    > Я планировал, что каждый экземпляр класса будет работать
    > с портом напрямую

    А нафига?
    Я конечно не знаю досконально вашу задачу, но что-то тут мне не нравится.
    Контроллер на основе Ардуина - вполне самодостаточное устройство для выполнения всех тех функций, которые в него заложены. Но вот зачем вам некий класс в программе который будет решать когда связанному с ним контроллеру посылать какие-то запросы?
    Это решать должна основная программа. Она должна знать какие контроллеры включены в систему, что они делают и когда им нужно посылать запросы/команды.
  • Юрий К (10.02.19 15:11) [7]
    Я сейчас пытаюсь реализовать работу ( упрощенно ) по протоколу AISG 2.0 ( Antenna Interface Standards Group ) ( это протокол для управления удаленными устройствами ( РЭТ-моторы регулирующие угол наклона антенн ) в сетях сотовой связи ).

    Зачем мне это надо? Во-первых: При монтаже таких железок неплохо бы убедиться до монтажа, что все они рабочие. т.е. подключил ноут, увидел железяки, все ОК - начал монтаж. Иначе ( заменил РЭТ/кабель и т.п. )
    Это можно сделать и штатным ПО базовой станции, но для этого надо собирать стенд ( системный модуль, удаленный радиомодуль, источник питания 48В ), что в полевых условиях - мало реально и требует много времени ( заливки софта в оборудование ).
    Поэтому хочу обойтись малой кровью - ноут, источник питания, преобразователь интерфейса RS-485 и кабель который в последующем будет подключен к радиомодулю а на этапе теста - к ноуту.

    Во-вторых: таких железок ( списанных с устаревших антенн ) у меня накопилось н-ное количество и хочется их пустить на самоделки. В устройстве есть контроллер ( STM-32 ) драйвер шагового двигателя, сам шаговый двигатель с редуктором и преобразователь интерфейса RS-485. Все это во всепогодном исполнении. То есть используя штатную систему команд протокола AISG 2.0 этими устройствами возможно управлять ( вращать двигатель, получать инфу от датчика тока при перегрузке двигателя и т.п. ).

    Читая даташиты на протокол AISG 2.0 ( https://aisg.org.uk/files/AISG-v2.0.pdf ) в попытках разобраться как он работает,
    натыкаюсь на множество ссылок на более универсальные протоколы.
    Например такой:
    3GPP TS25.463 UTRAN ( https://www.etsi.org/deliver/etsi_ts/125400_125499/125463/06.00.00_60/ts_125463v060000p.pdf )

    Или еще более универсальный HDLS (Higher-levelDataLinkControl):
    http://alice.pnzgu.ru:8080/~dvn/complex/gl7_2.html

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

    И я решил, используя доступную железяку на которую написано масса простого софта ( Ардуино ), и работать с ней доступно практически всем, отработать попытку взаимодействия с ней по протоколу HDLS

    Естественно, пока в упрощенном варианте, постепенно добавляя функционал, пока он не станет полноценным и не будут устранены все баги.

    Задача для новичка, прямо скажу, наверное мало реальная, но как минимум это попытка разобраться как работают железяки, которые приходится монтировать, и понимание принципа их работы, а так же чего им не хватает, поубавит ситуаций, когда сисадмин сети, с не очень прямыми руками, не смог настроить РЭТ, и посылает меня менять/устранять косяк. А эти РЭТы после монтажа часто за 100-200 километров, и "в открытом космосе" т.е. на высоте 50-70 метров и добраться до них можно только методом промышленного альпинизма, вывесившись под площадку обслуживания.
  • Германн © (11.02.19 02:19) [8]

    > Задача для новичка, прямо скажу, наверное мало реальная,
    >  но как минимум это попытка разобраться как работают железяки,
    >  которые приходится монтировать, и понимание принципа их
    > работы, а так же чего им не хватает, поубавит ситуаций,

    Удачи! Задача не такая уж суперсложная. Главное не усложняйте её реализацию разработкой лишних классов.
  • KSergey © (11.02.19 07:26) [9]
    Я бы таки всё управление сделал в ардуине (условно, в подходящем под задачу по мощности контроллере), в неё бы просто загружал управляющую последовательность, а всю логику управления моторчиками далала бы полностью ардуина, во избежании всех этих сложных "туда-сюда" и "дошло-не дошло".
    И еще. Есть же USB порт, там вроде не сложнее совсем, но при этом он как-то более распространён нынче.
  • Германн © (12.02.19 02:47) [10]

    > KSergey ©   (11.02.19 07:26) [9]
    >
    > Я бы таки всё управление сделал в ардуине

    ТС Ардуин использует только для тестирования своих идей. Реальное железо у него совсем иное.
  • KSergey © (12.02.19 07:45) [11]
    > Германн ©   (12.02.19 02:47) [10]
    > ТС Ардуин использует только для тестирования своих идей.
    >  Реальное железо у него совсем иное.

    Что это меняет?
    Я считаю саму идею всё управление вешать на ПК - провальной в том виде, как это представлено. Ну в смысле чреватой и принципиально не не позволяющей избежать описанных проблем.
  • dshot_600 (12.02.19 19:27) [12]
    Ну в смысле чреватой и принципиально не не позволяющей избежать описанных проблем.

    одруина умеет крутить шаговиками.

    но она не знает куда именно этими шаговиками "надо ехать"

    куда ехать знает человек, но ему нужен интерфейс через который он это расскажет адруине.
    для этого и нужен пульт или комп.
  • KSergey © (13.02.19 09:33) [13]
    > dshot_600   (12.02.19 19:27) [12]

    Ардуина и не должна "знать". Она должна лишь открутить шаговички туда, куда указано загруженными в неё данными.
    Разумеется, подготовить такие данные много проще на более традиционном компьютере.

    Я вот о чем: автор предлагает полностью управлять условными шаговиками непосредственно с компьютера. На мой же взгляд, такой вариант довольно неудачный по надёжности путь, о чем сам же автор и беспокоится, кстати.
    Значит надо просто убрать то самое ненадёжное звено из управления (канал связи) - и щастье.
  • dshot_600 (13.02.19 10:58) [14]
    ну и откуда она сегодня может узнать куда и насколько открутить ?
    из 32 к памяти которую прошили неделю назад?

    автор предлагает полностью управлять условными шаговиками непосредственно с компьютера.

    его ошибка в том, что не надо курить все эти протоколы чтобы крутить шаговиками с ардуины.
    ну а так ты прав.
    пишем код, который минуту крутит клоквайз, минуту каунтерклоквайз и минуту стоит.
    человек с писи здесь не нужен.
  • KSergey © (13.02.19 11:17) [15]
    > dshot_600   (13.02.19 10:58) [14]
    > из 32 к памяти которую прошили неделю назад?

    EEPROM в условной ардуине завсегда есть же.
    Мало - припаять еще не проблема.
  • dshot_600 (13.02.19 13:18) [16]
    его там 1 килобайт в старших моделях 328 и полкило в 168
  • Германн © (14.02.19 02:09) [17]

    > KSergey ©   (12.02.19 07:45) [11]
    >
    > > Германн ©   (12.02.19 02:47) [10]
    > > ТС Ардуин использует только для тестирования своих идей.
    >
    > >  Реальное железо у него совсем иное.
    >
    > Что это меняет?
    > Я считаю саму идею всё управление вешать на ПК - провальной
    > в том виде, как это представлено. Ну в смысле чреватой и
    > принципиально не не позволяющей избежать описанных проблем.
    >
    >

    Вообще-то это меняет всё! Основную свою задачу ТС не озвучил. Не уверен, что основную задачу нужно будет решать через микроконтроллер.
    Например на моём лицевом счету числится разработка нескольких стендов для научно-производственных лабораторий. Делать управление такими стендами только на микроконтроллерах просто глупо и безнадежно.
  • Юрий К (14.02.19 08:34) [18]
    Ну вообще-то, те самоделки, что я задумал напрямую связаны с работой ( монтажом сотовых базух ). Там есть куча простой работы ( например закручивать гайки ) которая выполняется в условиях опасных для жизни ( на весу в безопорном пространстве ).

    Моя задумка такова:
    Несколько независимых друг от друга устройств на контроллерах.
    Одно - аналог грузовой лебедки ( одна ардуина управляет двигателем, вторая - в пульте ДУ ). Лебедкой можно управлять как в ручную ( кнопками ), так и удаленно ( с пульта ), третий вариант через мастера ( при совместной работе лебедки с другими устройствами ).

    Если удастся собрать более сложный деавйс ( типа симбиоза манипулятора и гайковерта ) - то им придется работать в паре ( лебедка доставляет манипулятор до высоты, где надо крутить гайки, манипулятор - крутит ).

    Все это не сможет работать автономно. Нужен оператор. Оператору нужна связь для канала управления и практически наверняка понадобится канал видео данных ( с вэб камеры с двумя степенями свободы ).

    Реализовать этот на пульте ДУ - мало реально. Или придется поступать как с дронами ( пульт выполняет свою функцию, а видеопоток возвращается на смартфон ).

    Обратная связь нужна для того, чтобы ардуина не зависла на высоте, зафиксированная к металлоконструкциям своими захватами-манипуляторами. Чтобы при потере связи освобождала все рабочие органы и свободно повисала и ее возможно было бы снять, спустив лебедкой ( для устранения косяка ).

    А для лебедки без обратной связи вообще нельзя. Груз может зацепиться за металлоконструкции и т.п. Те. лебедка включает двигатель только тогда, когда есть четкая команда на подъем/спуск. И гарантированно не должна срабатывать от помех или еще чего.

    Без обратной связи алгоритм работы такого робота слишком усложняется. Нужно чтобы робот понимал что крутить, как крутить  и где крутить. А это куча датчиков, камер, систем распознавания и пр.

    Гораздо проще сделать дистанционно управляемый манипулятор.

    Хотя если подумать. В последующем все операции повторяются циклично ( на разной высоте ). Например крепление кабелей к кабельному мосту. Вполне возможно минимальным набором датчиков реализовать алгоритм автоматического выполнения данных операций.

    Покупка реального промышленного сборочного робота не обсуждается. Это убъет всю рентабельность проекта на многие годы. Там цифры с шестью нулями, но вполне понятно каков примерный вес манипулятора получится для манипуляции деталями весом, например 2-3 кг. Цифры реальные. Это можно сделать вполне компактно и не таскать наверх многосоткилограмогого монстра.

    Вообщем так. Я пока планирую научить ардуинку работать с ноутом по интерфейсу RS-485. Потому как все-таки планирую управлять всей этой хренью по кабелю ( надежнее ) + можно подать удаленное питание и не таскать наверх АКБ большой емкости. Например витая пара. Метраж - допустим для такого интерфейса. Скорости позволяют гонять и видео поток. Но надо управлять несколькими устройствами как минимум: камера, лебедка, манипулятор...

    Все это надо придумать так, чтобы не мешало друг другу на канале связи.

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

    Скорее всего вытянуть такой проект в одиночку - не реально. Поэтому пока ставлю себе задачи по проще. Разобраться как работает. Научиться управлять шаговиками. Дальше будет видно. Уже на этом этапе будет вполне понятно - хватает мозгов или нет.
  • dshot_60 (14.02.19 08:48) [19]
    Я пока планирую научить ардуинку работать с ноутом по интерфейсу RS-485.

    это примерно то же самое что учиться ходить по улице с закрытыми глазами, с ультразвуковым излучателем, и наушниках, подключенных к усилителю, который уз превращает в слышимый звук.
 
Конференция "Начинающим" » Работа с сом портом в асинхронном режиме
Есть новые Нет новых   [134427   +26][b:0][p:0.001]