Делаем радиоуправление для самолета

в 19:36, , рубрики: avr, RF-модули, Программинг микроконтроллеров, радиоуправление, робототехника, Электроника для начинающих, метки: , , ,

Делаем радиоуправление для самолета
Прочитав этот пост загорелся и я идеей склепать свой самолетик. Взял готовые чертежи, заказал у китайцев моторчики, аккумуляторы и пропеллеры. А вот радиоуправление решил сделать самостоятельно, во-первых — так интереснее, во-вторых — надо себя чем-то занять пока посылка с остальными запчастями будет ехать, ну и в третьих — появилась возможность соригинальничать и добавить всяких плюшек.
Осторожно, картинки!

Как и чем управлять

Нормальные люди берут приемник, втыкают в него сервомашинки, регулятор скорости, двигают рычажки на пульте и радуются жизни не задаваясь принципами работы и не углубляясь в подробности. В нашем случае такое не пройдет. Первой задачей стало узнать каким макаром управляются сервомашинки. Все оказывается достаточно просто, у привода есть три провода: + питания, — питания и сигнальный. На сигнальном проводе прямоугольные импульсы изменяемой скважности. Чтобы понять что это такое смотрим картинку:
Делаем радиоуправление для самолета
Итак, если мы хотим установить привод в крайнее левое положение нужно слать импульсы длительностью 0,9мс с интервалом 20мс, если в крайнее правое — длительность 2,1мс, интервал тот же, ну со средними положениями аналогично. Как оказалось, регуляторы скорости управляются аналогично. Те, кто в теме скажут что это обычный ШИМ, который реализовать на любом микроконтроллере — плевое дело. Вот и я так решил, купил в местном магазине сервомашинку и склепал на макетке для нее так называемый сервотестер на ATtiny13. И тут оказалось, что ШИМ не совсем простой, а с подводными камнями. Как видно из вышеприведенной диаграммы, скважность (отношение длительности импульса к длительности периода) от 5% до 10% (в дальнейшем я за крайние положения принимаю импульсы длительностью 1,0мс и 2,0мс) для 256-значного ШИМ счетчика ATtiny13 это соответствует значениям от 25 до 50. Но это при условии, что на заполнение счетчика уйдет 20мс, а на деле так не получится и для частоты 9,6МГц и предделителя 1024 нужно ограничить счетчик значением 187(ТОР), в таком случае у нас получится частота 50,134Гц. В большинстве (если не во всех) сервомашинок нету точного генератора опорной частоты и поэтому частота управляющего сигнала может немного плавать. Если оставить ТОР счетчика 255, то частота управляющего сигнала будет 36,76Гц — на некоторых приводах оно будет работать (возможно с глюками), но далеко не на всех. Итак, теперь у нас 187-значный счетчик, для него 5-10% соответствуют значениям от 10 до 20 — всего 10 значений, немного дискретно получится. Если думаете поиграть с тактовой частотой и предделителем ниже привожу сравнительную табличку для 8-битного ШИМа:
Делаем радиоуправление для самолета

Но ведь у большинства микроконтроллеров есть 16-битный (и больше) таймер для генерации ШИМ. Здесь проблема с дискретностью сразу пропадет еще и частоту можно точно выставить. Долго расписывать не буду, сразу даю табличку:
Делаем радиоуправление для самолета

Я не думаю, что для китайской сервомашинки есть существенная разница в 600 и 1200 значений, поэтому вопрос с точностью позиционирования можно считать закрытым.

Многоканальное управление

С одной сервомашинкой разобрались, но для самолета их нужно минимум три и еще регулятор скорости. Решение «в лоб» — взять микроконтроллер с четырьмя каналами 16-битного ШИМ, но такой контроллер будет стоять дорого и, скорее всего, займет много места на плате. Второй вариант — запилить программный ШИМ, но занимать процессорное время — это тоже не вариант. Если снова посмотреть на диаграммы сигнала, то 80% времени он не несет никакой информации, поэтому рациональнее было бы ШИМом задавать только сам импульс 1-2мс. Почему скважность изменяется в таких узких пределах, ведь проще было бы и формировать и считывать импульсы со скважностью хотя бы 10-90%? Зачем нужен тот неинформативный кусок сигнала занимающий 80% времени? Я заподозрил, что, возможно, эти 80% могут занимать импульсы для других исполнительных механизмов, а потом этот сигнал разделяется на несколько разных. То есть, в периоде длительностью 20мс могут уместится 10 импульсов длительностью 1-2мс, затем этот сигнал каким-то демультиплексором разделяется на 10 различных с длительностью периода как раз 20мс. Сказано — сделано, нарисовал в PROTEUS такую схемку:
Делаем радиоуправление для самолета
В роли демультиплексора — 74HC238, на его вход E подаются импульсы с выхода микроконтроллера. Эти импульсы — ШИМ с периодом 2мс (500Гц) и скважностью 50-100%. У каждого импульса своя скважность, обозначающая состояние каждого канала. Вот так выглядит сигнал на входе Е:
Делаем радиоуправление для самолета
Для того, чтобы 74HC238 знал на какой выход подать текущий сигнал используем PORTC микроконтроллера и входы A, B, C демультиплексора. В результате на выходах получаем такие сигналы:
Делаем радиоуправление для самолета
Сигналы на выходе получаются правильной частоты (50Гц) и скважности (5-10%). Итак, нужно генерировать ШИМ частотой 500Гц и заполнением 50-100%, вот табличка для настройки предделителя и ТОР 16-битного счетчика:
Делаем радиоуправление для самолета
Интересно, что возможное количество значений ШИМа ровно в 1000 раз меньше частоты таймера.

Программная реализация

Для ATmega8 с тактовой частотой 16МГц в AtmelStudio6 все реализуется следующим образом: вначале задефайним значения счетчика для крайних положений сервомашинок:

#define LOW 16000U
#define HIGH 32000U

затем инициализируем генератор ШИМа на таймере/счетчике1:

OCR1A = HIGH; //Устанавливаем ТОР
TCCR1A = 0<<COM1A1 | 0<<COM1A0 | 1<<COM1B1 | 0<<COM1B0 | 0<<FOC1A | 0<<FOC1B | 1<<WGM11 | 1<<WGM10; //Запускаем неинвертированный Fast PWM на выходе OC1B с верхним значением счетчика, которое записанно в OCR1A
TCCR1B = 0<<ICNC1 | 0<<ICES1 | 1<<WGM13 | 1<<WGM12 | 0<<CS12 | 0<<CS11 | 1<<CS10; //предделитель 1
TIMSK = 1<<OCIE1A | 1<<OCIE1B | 0<<TOIE1; //Разрешаем прерывания по совпадению

Остается реализовать прерывания:

ISR(TIMER1_COMPA_vect) //прерывание по достижению верхнего значения счетчика, непосредственно перед началом следующего импульса
{
        //c_num- переменная, обозначающая номер текущего канала, channels - массив значений каналов
	if (c_num <= 7)
	{
		OCR1B = channels[c_num];
	}
	else
	{
		OCR1B = 0; //отключаем ШИМогенератор для несуществующих в демультиплексоре 8 и 9 канала
	}
	
}

ISR(TIMER1_COMPB_vect, ISR_NOBLOCK)// прерывание возникающее в конце импульса
{
	if (c_num <= 7)
	{
		PORTC = c_num; //для каналов 0-7 выводим номер канала на PORTC
	}

	//и изменяем значение счетчика от 0 до 9
	if (c_num >= 9)
	{
		c_num = 0;
	}
	else
	{
		c_num++;
	}
}

Глобально разрешаем прерывания и готово, забивая в channels значения от LOW до HIGH изменяем значения на каналах.

Реализация в железе

Ну с теорией разобрались, пришло время все это реализовать. Мозгом системы выбран микроконтроллер ATmega8A, тактируется от кварца на 16МГц (не потому, что я захотел 16000 позиций сервомашинки, а потому, что у меня такие валялись). Управляющий сигнал для МК будет поступать через UART. В результате получилась вот такая схемка:
Делаем радиоуправление для самолета
Спустя некоторое время появилась вот такая платка:
Делаем радиоуправление для самолета
Делаем радиоуправление для самолета
Два трехштыревых разъема я не припаял потому, что они мне не нужны, а не подряд они впаяны поскольку у меня нету металлизации отверстий, а в нижнем разъеме дорожки с двух сторон, можно было бы заменить проволочкой, но программно нету проблемы выводить сигнал на любой разъем. Также отсутствует 78L05 ибо в моем регуляторе двигателя есть встроенный стабилизатор (ВЕС).
Для получения данных к плате подключается радиомодуль HM-R868:
Делаем радиоуправление для самолета
Изначально думал втыкать его прямо в плату, но эта конструкция не помещалась в самолетик, пришлось сделать через шлейф. Если изменить прошивку, то контакты разъема для программирования можно использовать для включения/отключения каких-нибудь системам (бортовые огни и т.п.)
Плата обошлась примерно в 20грн = $2.50, приемник — 30грн = $3,75.

Передающая часть

Самолетная часть есть, осталось разобраться с наземной аппаратурой. Как уже писалось ранее, данные передаются по UART, на каждый канал по одному байту. Вначале подключал свою систему проводом через переходник к компьютеру и команды слал через терминал. Чтобы дешифратор определял начало посылки, а в будущем выделял посылки адресуемые именно ему, вначале шлется байт-идентификатор, затем 8 байт определяющих состояние каналов. Позже стал использовать радиомодули, при отключении передатчика все моторчики начинали дико дергаться. Дабы отфильтровать сигнал от шумов, десятым байтом шлю XOR всех 9 предыдущих байт. Помогло, но слабо, добавил еще проверку на таймаут между байтами, если он превышается — вся посылка игнорится и прием начинается заново, с ожидания байта-идентификатора. С добавлением контрольной суммы в виде XOR слать команды с терминала стало напряжным, поэтому я побыстрому наклепал вот такую программку с ползунками:
Делаем радиоуправление для самолета
Число в нижнем левом углу — контрольная сумма. Передвигая ползунки на компе двигались рули на самолете! Вообщем отладил я все это и стал думать о пульте ДУ, купил для него вот такие джойстики:
image
Но потом меня посетила одна мысль. В свое время я тащился от всяких авиасимуляторов: «Ил-2 Штурмовик», «Lock On», «MSFSX», «Ка-50 Черная Акула» и др. Соответственно был у меня джойстик Genius F-23 и решил я прикрутить его к вышеописанной проге с ползунками. Погуглил как это реализовать, нашел этот пост и получилось! Управлять самолетиком с помощью полноценного джойстика, мне кажется, гораздо круче, чем маленькой палочкой на пульте. Вообщем все вместе изображено на первой фотке — это нетбук, джойстик, преобразователь на FT232, и подключенный к нему передатчик HM-T868. Преобразователь подключается 2м кабелем от принтера, что позволяет закрепить его на каком нибудь дереве или чем-то подобном.

Пуск!

Итак, есть самолетик, есть радиоуправление — Поехали!(с) Первый полет производился над асфальтом, результат — сломанный пополам фюзеляж и полувырванный двигатель. Второй полет производился над более мягкой поверхностью:

Последующие полетов 10 были тоже не особо удачными. Основной причиной я считаю сильную дискретность джойстика — по крену он выдавал только 16 значений (вместо возможных 256), с осью тангажа — не лучше. Но так как в результате испытаний самолет был значительно поврежден и не подлежит ремонту:
Делаем радиоуправление для самолета
— проверить правдивость этой версии пока не представляется возможным. В пользу этой версии говорит и зафиксированная на видео попытка выровнять самолет — он летит накрененным, а потом резко заваливается в противоположную сторону (а должен плавно). Вот более наглядное видео:

Дальность действия аппаратуры — примерно 80м, дальше тоже ловит, но через раз.
Ну вот и все, благодарю за внимание. Надеюсь, приведенная информация окажется для кого-то полезной. Буду рад ответить на все вопросы.
В архиве схема и разводка платы для Протеуса.

Автор: KoteSoft

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js