Итак, в одной из ранних статей я писал о создании пульта для квадрокоптера, на основе радиопередатчика APC220. По просьбам трудящихся, опишу подробнее по какому протоколу осуществляется общение пульта и машины.
APC220
Напомню, дабы не испытывать проблем с дальностью передачи, в самом начале проекта я закупил комплект из двух приемопередатчиков APC220. Эти волшебные устройства прохватывают сотни метров открытого пространства (по паспорту >2км). Подключаются они к микроконтроллеру через обычный UART. Соответственно, передача данных между двумя узлами осуществляется при помощи известного класса SoftwareSerial, который входит в состав штатных библиотек Arduino IDE.
Для примера, один узел заставим отправлять в эфир каждую секунду байт 0xA0.
Второй узел будет слушать эфир, и при получении правильного байта - мигать светодиодом.
Библиотека SerialFlowКак минимум, теперь мы умеем передавать байты. Осталось научиться передавать на машину управляющие команды и величины, а также получать от неё телеметрию. Конечно, можно обмениваться текстовыми сообщениями типа "engine on" или "thrust 110, dir 35", но это избыточно и некрасиво, верно? Можно было, наверное, воспользоваться готовыми библиотеками именно для таких целей. Но мне было проще написать свою библиотеку
В библиотеке SerialFlow описан класс, который оборачивает стандартный Serial, и позволяет передавать через него массивы двухбайтных чисел. Предположим, что команда 0xA1 отвечает за установку тяги двигателей, а 0x01FF - значение тяги (511 в десятеричной системе). Тогда пакет, передаваемый SerialFlow будет иметь вид: 0x12,0x0,0xA1,0x10,0xFF,0x01,0x13 Здесь 0x12 и 0x13 - стартовый и стоповый байты. 0x10 - разделитель. Есть еще один служебный байт - 0x7D, служащий для экранирования. В общем, имеем достаточно компактный пакет, который сильно экономит трафик радиоканала. Для инициализации передатчика, нужно вызвать метод setPacketFormat: apc.setPacketFormat( SerialFlow::COMPLEX, 2, 8 ); COMPLEX - тип пакета. В библиотеке предусмотрен еще SIMPLE, но в данном случае он нам не подходит. 2 - размер числа (2 байта, больше пока не предусмотрено); 8 - количество чисел в пакете. Затем, когда нам нужно отправить числа, складываем их поочередно в пакет: apc.setPacketValue( 0x00A1 ); apc.setPacketValue( 0x01FF ); Наконец, отправляем весь пакет: apc.sendPacket(); Вот как будут выглядеть предыдущие программы, если в них использовать SerialFlow. Признаюсь, для мой задачи, в которой пульт служит лишь для первичной настройки машины, использование такого протокола особого смысла не имеет. Но я терпеть не могу передачу данных строками. К тому же, мой монитор порта SFMonitor заточен именно под SerialFlow. Ведущий, ведомый, квитанцииКакими данными обмениваются пульт и мультикоптер? Во-первых - это самая важная команда включения/выключения. К этой команде вообще следует отнестись очень трепетно, особенно, если учесть повышенную травмоопасность винтокрылой машины. Вы всегда должны иметь возможность экстренно выключить мультикоптер. Никаких глюков здесь быть не может - рискуете кусочками своего тела. На втором месте идут команды управления: газ, рыскание, крен и тангаж. Далее, настроечные параметры, к которым относятся коэффициенты ПИД регулятора. В своем проекте я наделил пульт правами ведущего (master). Мультикоптер же стал ведомым (slave). Каждые 50мс, мастер отправляет в эфир пакет управления. А каждые 500мс, беспилотнику дается команда о необходимости отправить телеметрию. После отправки пакетов включения/выключения, управления и телеметрии, ведущий дожидается квитанций о получении ведомым этих пакетов. Пока квитанция не получена, ведущий продолжает отправлять последнюю команду. Полный код пульта и обоих контроллеров машины выложу чуть позже. Если есть конкретные вопросы, пишите письма. |
События >