Система автопилотирования для радиоуправляемого вертолета. Часть 2: Перехват управления

Это продолжение статьи по разработки системы автопилотирования для радиоуправляемого вертолета.Так как у меня в плане нет строительства полноценного БПЛА, по большей части это все таки вертолет с ручным управлением, и совсем убирать из него приемник я не буду. Поэтому надо как нибудь реализовать коммуникацию между Arduino, радиоприемником и контроллером двигателей.Первым делом я решил разобраться каким образом приемник общается с контроллером. Раз сервоприводы подключены к приемнику также как и контроллер, значит принцип управления моторами такой же как и сервоприводами, в основе которого лежит ШИМ.Затем я решил попробовал подчитывать значения с выходов приемника.Расположение контактов на приемнике и контроллере двигателей: 1-GND, 2-VCC, 3-сигнал.imageДля этого подключаем выходы сигнала приемника (их всего 4, верхние 2 — сервоприводы, следующие 2 — для контроля двигателями) к Arduino pin 5,6,7,8, один из входов VCC к 5v Arduino, а один из входов GND к GND arduino. С помощью функции pulseIn (), считывающей длину сигнала на заданном входе, мы получаем значения, выдаваемые приемником. Максимально отклоняя рычаги на пульте управления я зафиксировал необходимые мне значения. Это значения от 1080 до 1800, при этом выдаваемые значения, когда ручки находятся в нормальном состоянии для крена, тангажа и курса — 1450, а для газа — 1080.imageСкетч достаточно простой: int c1; int c2; int c3; int c4; void setup () {

pinMode (5, INPUT); pinMode (6, INPUT); pinMode (7, INPUT); pinMode (8, INPUT);

Serial.begin (9600);

} void loop () {

c1 = pulseIn (5, HIGH, 25000); c2 = pulseIn (6, HIGH, 25000); c3 = pulseIn (7, HIGH, 25000); c4 = pulseIn (8, HIGH, 25000);

Serial.print («C1:»); Serial.println (c1); Serial.print («C2:»); Serial.println (c2); Serial.print («C3:»); Serial.println (c3); Serial.print («C4:»); Serial.println (c4); } Ну, собственно казалось бы все, можно уже передавать управление в руки Arduino? Соединяем теперь уже контроллер двигателей (Arduino pin 5 и 6) и сервоприводы (Arduino pin 7 и 8) с Arduino и пишем еще один скетч:

#include Servo right; Servo left; Servo rightmot; Servo nizmot; int rightmot_pin = 5; int nizmot_pin = 6; int serv_left_pin=7; int serv_right_pin=8; int js_position = 800; int max_position = 3000; int spd1_now;

void setup () { left.attach (serv_left_pin, js_position, max_position); right.attach (serv_right_pin, js_position, max_position); rightmot.attach (rightmot_pin, js_position, max_position); nizmot.attach (nizmot_pin, js_position, max_position); } void loop () { for (int i=1080, j=1800; i<1800,j>1080; i++, j--) { left.write (i); right.write (j); } for (int j=1800, i=1080; j>1080, i<1800;j--,i++) { left.write(j); right.write(i); } } Заливаем, ждем, и вот тут то начинаются проблемы. Во-первых, долго пришлось ломать голову над тем, почему контроллер включается, но не может откалиброваться и начать работу. Через полчаса я нашел решение: проблема была в том, что включается и моргает он при любом напряжении, а вот работать начинает только при использовании аккумулятора с минимальным напряжением 7.4 Вольт. Вообще, это даже пошло на пользу, Arduino очень даже хорошо питается и работает от аккумулятора через контроллер, и не прийдется ставить один аккумулятор на управление а другой на контроллер двигателей (Обычно для контроллера стоит мощный аккумулятор с большой емкостью и напряжением 11.1V, а на управлении аккумулятор небольшой емкости(850 мАч) и напряжения 7.4V).

Подключаем батарею, пробуем снова. Опять просто мигает. На решение этой проблемы ушло часа 3. Оказывается, чтобы контроллер заработал, ему нужно каким-то образом при включении повзаимодействовать с приемником. Как именно, мне пока не удалось узнать, возможно приемник посылает в него какие-то особенные значения. Чтобы это решить, подключаем к Arduino еще и приемник (Arduino pin 9,10,11,12), считываем с него значения поступающие с пульта, и передаем их контроллеру:

#include Servo right; Servo left; Servo rightmot; Servo nizmot; int rightmot_pin = 5; int nizmot_pin = 6; int serv_left_pin=7; int serv_right_pin=8; int js_position = 800; int max_position = 3000; int c1; int c2; int c3; int c4; int spd1_now;

void setup () { pinMode (9, INPUT); pinMode (10, INPUT); pinMode (11, INPUT); pinMode (12, INPUT); left.attach (serv_left_pin, js_position, max_position); right.attach (serv_right_pin, js_position, max_position); rightmot.attach (rightmot_pin, js_position, max_position); nizmot.attach (nizmot_pin, js_position, max_position); } void loop () { c1 = pulseIn (5, HIGH, 25000); nizmot.write (c1); c2 = pulseIn (6, HIGH, 25000); rightmot.write (c2); c3 = pulseIn (7, HIGH, 25000); left.write (c3); c4 = pulseIn (8, HIGH, 25000); right.write (4); } Заливаем, подключаем, работает!!! Теперь приемник подключен к контроллеру через Arduino, который перехватывает сигнал и отправляет на нужный канал контроллера. Даже несмотря на то, что сигнал изменяется (обычно значение уменьшается на 15–20 единиц), вертолет Даже получается поднять в воздух.Теперь добавляем к Arduino кнопку, когда она зажата включается автоматическое управление.Скетч:

#include Servo right; const int SEL = 2; // digital

Servo left; Servo rightmot; Servo nizmot; int rightmot_pin = 5; int nizmot_pin = 6; int serv_left_pin=7; int serv_right_pin=8; int js_position = 800; int max_position = 3000; int c1; int c2; int c3; int c4; int spd1_now;

void setup () { pinMode (SEL, INPUT);

digitalWrite (SEL, HIGH); pinMode (9, INPUT); pinMode (10, INPUT); pinMode (11, INPUT); pinMode (12, INPUT); left.attach (serv_left_pin, js_position, max_position); right.attach (serv_right_pin, js_position, max_position); rightmot.attach (rightmot_pin, js_position, max_position); nizmot.attach (nizmot_pin, js_position, max_position); } void loop () { if (SEL == HIGH) { c1 = pulseIn (5, HIGH, 25000); nizmot.write (c1); c2 = pulseIn (6, HIGH, 25000); rightmot.write (c2); c3 = pulseIn (7, HIGH, 25000); left.write (c3); c4 = pulseIn (8, HIGH, 25000); right.write (4); } else { for (int i=1080, j=1800; i<1800,j>1080; i++, j--) { left.write (i); right.write (j);

} for (int j=1800, i=1080; j>1080, i<1800;j--,i++) { left.write(j); right.write(i); } } } Чтобы передать управление Arduino, необходимо подключить аккумулятор, подождать пока индикатор на контроллере не начнет постоянно гореть, а затем можно в принципе даже отключить приемник, т.к. после инициализации контроллер может уже работать без приемника.В этом примере с помощью цикла (для плавности хода сервопривода) изменяется угол наклона лопастей. В дальнейшем, этим же способом будет осуществляться управление вертолетом в полете.Демонстрация работы:[embedded content]

© Habrahabr.ru