Декодер PWM и плата реле
Для удобства в мультироторном FPV-аэрофото аппарате установлено несколько камер
камера с широким углом обзора для управления полетом
камера с узким углом обзора для поиска объекта съемки
вид с видеовыхода фотоаппарата для точного наведения на объект съемки
для обеспечения надежности передачи видеоинформации используется один из двух передатчиков работающих на разных частотах, с различной мощностью.
Нижеприведенное устройство позволяет использовать один канал приемника для комутации всех этих устройств при помощи двух переключателей на пульте.
В качестве "мозга" декодера может быть использована любая ардуино- плата, например такая которая изначально была задумана для выбора режимов автопилота на стороне передатчика,
Программа дешифратора PWM
Скетч для ардуино принимающий на вход 1 PWM канал и в зависимости от его значения выбирающий один из шести режимов:
int pinRelay1 = 5;
int pinRelay2 = 6;
int pinRelay3 = 7;
volatile unsigned long StartTime = millis();
volatile unsigned long Pulse;
volatile int Mode=1; // 1 to 6 0 - pwm out of range and six modes
volatile int OldMode;
volatile int OldModePulses;
static int ModeRanges[6];
void setup()
{
//under
ModeRanges[1] = 1100;
ModeRanges[2] = 1300;
ModeRanges[3] = 1500;
ModeRanges[4] = 1700;
ModeRanges[5] = 1900;
ModeRanges[6] = 2100;
pinMode (pinRelay1, OUTPUT);
digitalWrite(pinRelay1,LOW);
pinMode (pinRelay2, OUTPUT);
digitalWrite(pinRelay2,LOW);
pinMode (pinRelay3, OUTPUT);
digitalWrite(pinRelay3,LOW);
attachInterrupt(1, ch_state, CHANGE); //two external interrupts: numbers 0 (on digital pin 2) and 1 (on digital pin 3). may be used for inerrupt
Serial.begin(115200);
}
void loop()
{
Serial.print("Mode:");
Serial.print(Mode, DEC);
Serial.print(" Pulse:");
Serial.println(Pulse, DEC);
delay(1000);
}
void ch_state()
{
unsigned long CurTime = micros();
bool state = digitalRead(3);
if (state==LOW && CurTime > StartTime)
{
Pulse = CurTime - StartTime;
checkMode();
}
else
StartTime = CurTime;
}
void checkMode()
{
int NewMode =1;
for (int i=1 ; i <= 6; i++)
{
if (Pulse < ModeRanges[i] ) { NewMode = i; break; }
}
if (Pulse > ModeRanges[6] + 200) NewMode = 1;
setMode(NewMode);
//Mode = NewMode;
}
void setMode(int NewMode) //check for pulse range 5 times in some range before switch
{
if (OldMode != NewMode)
{ OldModePulses = 0;
OldMode = NewMode; }
else
OldModePulses = OldModePulses + 1;
if (OldModePulses >= 25)
{ Mode = NewMode;
OldModePulses = 25;
SwRelays();
}
}
void SwRelays()
{
if (Mode == 1 || Mode == 3 || Mode == 5 ) //transmitter 1 power on else transmitter 2 power on
digitalWrite(pinRelay1,LOW);
else
digitalWrite(pinRelay1,HIGH);
if (Mode <= 2 ) // video 1 on (else 2 or 3 used)
digitalWrite(pinRelay2,LOW);
else
digitalWrite(pinRelay2,HIGH);
if (Mode > 4 ) // video 3 on (else 2 used)
digitalWrite(pinRelay3,LOW);
else
digitalWrite(pinRelay3,HIGH);
}
Как подключить
Для удобства настройки аппаратуры отладочная информация выводится в последовательный порт (на скорости 115200)
сигнальный провод от приемника следует подключить к пину ардуино D3
обмотки трех реле подключаются к выходам D5 D6 D7
Как работает скетч:
в массив ModeRanges[] устанавливаются необходимые границы для уровней ппм сигнала в микросекундах. эти значения следует менять лишь если вы решили изменить количество режимов или подогнать длительность под возможности вашей аппаратуры
в процессе загрузки программы выполняется процедура attachInterrupt(1, ch_state, CHANGE);
которая указывает что пр каждом изменении уровня сигнала на D3 нужно запустить подсчет длительности импульса
сам подсчет выполняется в процедуре ch_state эта функция определяет принадлежность значения импульса к определенному диапазону и вызывает процедуру предотвращающую переключение при "помехе" setMode
setMode при приеме 25 одинаковых значений (во избежание ложных срабатываний) изменяет глобальную переменную Mode которую можно использвать в любом месте вашего кода, не привязываясь к непрерывному циклу измерений
В данном примере функция SwRelays вызывается изнутри setMode однако это необязательно если скорость ракции на переключение не критична - в этом случае ее вызов можно переместить процедуру Loop
Вот что получилось:
Как настроить передатчик
Для независимого переключения двух передатчиков и используется 2 позиционный тумблер, трех камер - трехпозиционный. Оба смикшированы в одном канале следующим образом:
расходы выбранного канала установлены таким образом чтобы минимальный PWM был 1000ms а максимальный 2000ms при этом в ниженм положении трехпозиционного тумблера должно быть 1000 в среднем 1400 в максимальном 1800. включение двухпозиционного тумблера прибавляет 200ms к любой из позиций трехпозийионного тумблера.
соответственно получаем 6 комбинаций из двух тумблеров
1000 - mode 1
1200 - mode 2
1400 - mode 3
1600 - mode 4
1800 - mode 5
2000 - mode 6
Настройка миксов 2х и 3хпозиционных переключателей на 5 канал futaba
Плата реле и комутации
Плата комутации передатчиков и камер разработана для одного слоя, но потербуется несколько перемычек.
под все камеры и передатчики разведена вся комутация и питание, что позволяет легко менять передатчики и камеры местами, использовать два различных напряжения питания и избегать возможности перепутать его (в вилке подключения устройства используйте в зависимости от необходимости либо v1 либо v2 контакт)
файлы Eagle для изготовления печатной платы тут
использованы вилки с шагом 2,5 мм типа chu на 3,4,5 контактов и гнезда типа SWF
реле как в ардупилоте AXICOM
Ардуино-плата для декодирования сигнала и управления реле использована как в этом примере
В данном примере в процедуре SwRelays задан порядок включения трех реле, однако под свои нужды в этой процедуре возможно заложить любую необходимую логику и использовать необходимое количество выходов.