Система автопилотирования для радиоуправляемого вертолета. Часть 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.h>  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.h>  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.h>  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, необходимо подключить аккумулятор, подождать пока индикатор на контроллере не начнет постоянно гореть, а затем можно в принципе даже отключить приемник, т.к. после инициализации контроллер может уже работать без приемника.
В этом примере с помощью цикла (для плавности хода сервопривода) изменяется угол наклона лопастей. В дальнейшем, этим же способом будет осуществляться управление вертолетом в полете.
Демонстрация работы:

ссылка на оригинал статьи http://habrahabr.ru/post/259683/


Комментарии

Добавить комментарий

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