Arduino ile VTail Mikser Yapımı

Zafer ŞAHİN

Mahna Mahna ...
Katılım
29 Ağu 2013
Mesajlar
1,313
Tepkime puanı
2,193
Yaş
47
Konum
İstanbul
İlgi Alanı
Multikopter
Arduino ile servo reverser'dan sonraki proje de VTail mikser olsun, bunun üzerine tamam olur :)
 
Arduino ile VTail Mikser Yapımı

V-Tail mikserin tam işlevini kavrayabilsem bir şeyler yazmaya çalışırdım da temel felsefesini bilmiyorum. Tamam elevatör ve rudder işlevi birleştiriiliyor da yine de ne bileyim işte. :)
 
Arduino ile VTail Mikser Yapımı

V Tail Mixer elevatör ile rudder işlevlerini birleştiren bir sistem. Ben şöyle düşündüm:
Elevatör ve rudder sinyallerini okuyup bunları ikiye bölsem. Sonra bir çıkışa bunların toplamını diğer çıkışa da farkını yansıtsam olay çözülür.

Kod:
//V Tail mixer projesi V0.0

int elevator = 1;
int rudder = 2;
int elev_signal = 0;
int rudd_signal = 0;
int servo_1 = 3;
int servo_2 = 4;
int out_1 = 0;
int out_2 = 0;
unsigned long timer;
unsigned long x;


void setup()
{
  pinMode(elevator, INPUT);
  pinMode(rudder, INPUT);
  pinMode(servo_1, OUTPUT);
  pinMode(servo_2, OUTPUT);
}

void loop()
{
  elev_signal = pulseIn(elevator, HIGH, 25000);
  rudd_signal = pulseIn(rudder, HIGH, 25000);
  elev_signal = 1500 + (elev_signal - 1500) / 2;
  rudd_signal = 1500 + (rudd_signal - 1500) / 2;
  out_1 = elev_signal + rudd_signal;
  if(elev_signal > rudd_signal)
  {
    out_2 = elev_signal - rudd_signal;
  }
  else
  {
    out_2 = rudd_signal - elev_signal;
  }
  timer = micros();
  digitalWrite(servo_1, HIGH);
  digitalWrite(servo_2, HIGH);
  while(x < out_1 && x < out_2)
  {
    x = (micros() - timer);
    if(x >= out_1)
    {
      digitalWrite(servo_1, LOW);
    }
    if(x >= out_2)
    {
      digitalWrite(servo_2, LOW);
    }
  }
}
 
Arduino ile VTail Mikser Yapımı

Bu RESMİ görmek için izniniz yok. Giriş yap veya üye ol


Sinyalleri tek başına düşünürsek:

- A kanalından gelen sinyal(alıcının elevator kanalı) hem Elevatör hem de Aileron'a olduğu gibi gidecek
- B kanalından gelen sinyal(alıcının aileron kanalı), Elevator'a olduğu gibi, Aileron'a ters çevrilmiş halde (3000 - B) gidecek.

Sinyalleri beraber düşünürsek. Ve de dağılım oranını 1:1 kabul edersek.

- Elevator tarafındaki sinyal, A ve B'nin toplamının yarısı
- Aileron tarafındaki sinyal A + 3000 - B'nin yarısı.

Kod:
//VTail Mixer - 0.11

#include <Servo.h>

Servo revServoEle;  //Elevator Servo nesnesi olustur
Servo revServoAil;  //Aileron Servo nesnesi olustur

int rxPinEle = 11; //Alıcı Elevator bacağı seçimi
int rxPinAil = 12; //Alıcı Aileron bacağı seçimi
int servoPinEle = 5; //Çıkış Elevator bacağı seçimi
int servoPinAil = 6; //Çıkış Aileron bacağı seçimi
int inPulseEle = 0; //Giriş Elevator darbe süresi
int inPulseAil = 0; //Giriş Aileron darbe süresi
int servoPulseEle = 0; //Çıkış Elevator darbe süresi
int servoPulseAil = 0; //Çıkış Aileron darbe süresi

void setup()
{
pinMode(rxPinEle, INPUT); //Elevator Bacak işlevi giriş
pinMode(rxPinAil, INPUT); //Aileron Bacak işlevi giriş
revServoEle.attach(servoPinEle);  //Elevator servo nesnesini ilgili pine bagla
revServoAil.attach(servoPinAil);  //Aileron servo nesnesini ilgili pine bagla
}

void loop()
{
inPulseEle = pulseIn(rxPin, HIGH); //1 saniyelik varsayılan zamanaşımı süresince Elevator giriş darbesi okunuyor, yoksa anlik kesintiler genel isleyise zarar verebilir.
inPulseAil = pulseIn(rxPin, HIGH); //1 saniyelik varsayılan zamanaşımı süresince Aileron giriş darbesi okunuyor, yoksa anlik kesintiler genel isleyise zarar verebilir.
if((inPulseEle > 800 && inPulseEle < 2200) && (inPulseAil > 800 && inPulseAil < 2200)) //İki alici kanalindan da sinyal aliniyorsa
  {
  servoPulseEle = (inPulseEle + inPulseAil) / 2; //Elevator servosu, iki girisin surelerinin toplamının yapisi
  servoPulseAil = (inPulseEle + (3000 - inPulseAil)) / 2; //Aileron servosu, Elevatorun ve ters cevrilmis aileronun surelerinin toplaminin yarisi
  revServoEle.writeMicroseconds(servoPulseEle); // Elevator Servo nesnesine bulunan degeri yaz.
  revServoAil.writeMicroseconds(servoPulseAil); // Aileron Servo nesnesine bulunan degeri yaz.
  } else {
  revServoEle.writeMicroseconds(1500); // Sinyal gelmiyorsa Servolari ortala
  revServoAil.writeMicroseconds(1500); // Sinyal gelmiyorsa Servolari ortala
  }
}

Yukarıdaki kod zagi'de gayet iyi iş görür ama Koaksiyel bir helikopter yapılacaksa(throttle ve rudder) 1:1 oranının throttle lehine ayarlanması gerekecektir. Elimdeki iki tane koaksiyel (Lama v3 ve THK Lama5 :) ) helikopteri, 3in1 mikserlerinden kurtarıp tamemen özelleştirilebilir hale getirmeyi düşünüyorum da :).
 
Arduino ile VTail Mikser Yapımı

Bu V Tail Mix değil Elevon Mix olmuş. :)
V Tail Mix dediğimizde elevatör ve rudder kombinasyonu oluyor. Ama aileron yerine rudder yazarsak anlaşırız! :D
 
Arduino ile VTail Mikser Yapımı

Sümer Yamaner' Alıntı:
V Tail Mix dediğimizde elevatör ve rudder kombinasyonu oluyor. Ama aileron yerine rudder yazarsak anlaşırız! :D

Uçak terimlerine ne kadar aşina olduğum buradan da anlaşılıyor :). Bu konuyu, elimdeki koaksiyel helikopterleri modifiye etmek için araştırmıştım ve tüm dökümanlarda "vtail mikser" kullanarak "throttle-rudder" miks işlemini gerçekleştirin diye yazıyor.

Ayrıca miks özelliği olmayan kumandalar ile zagi kontrol edilecekse, orada da vtail mikser ile yapılmış bir sürü setup var. Bu sebeple, girişlerden birini iki çıkışa olduğu gibi, diğerini ise birini düz birini ters olarak gönderen her cihaz benim için vtail mikser :) .
 
Arduino ile VTail Mikser Yapımı

Elevator, throttle, aileron ya da rudder ne kullanılacaksa kullansın, oranlı olarak giriş sinyallerini, çıkış sinyalleri ile miksleyecek şekilde kodu düzenledim. Aşağıdaki resmi elevator ve aileron değil de 1. çıkış ve 2. çıkış olarak düşünelim.

Bu RESMİ görmek için izniniz yok. Giriş yap veya üye ol


Çıkıştaki dağilim oranları, koddaki "int inRatio = {7,3};" değeri ile belirleniyor. Yani 1.girişin ağırlık oranı yedi, 2.girişin ağırlık oranı ise üç. Yani ilk girişin 7/10'u ikinci girişin ise 3/10'u hesaba katılarak çıkışa yansıtılıyor.

Koaksiyel helikopterler için düşünürsek, normal şartlarda tam ortada(1500 mikrosaniye) olan rudder değenin, pervaneleri döndürmesini engellemek için bir ofset değeri ya da limit değeri belirlenmesi gerekebilir. Onun için biraz daha düşüneceğim...

Kod:
//VTail Mixer - 0.2

#include <Servo.h>

Servo ServoA;  //Servo nesnesi olustur
Servo ServoB;  //Servo nesnesi olustur

Servo servos[] = {ServoA, ServoB}; //Kolay kullanim icin servoları array icine at

int rxPins[] = {11,12}; //Alıcı bacaklari seçimi
int servoPins[] = {5,6}; //Cikis servo bacaklari seçimi
int inPulses[] = {0,0}; //Giris alici darbe süresi
int servoPulses[] = {0,0}; //Cikis servo darbe süresi

int inRatio = {7,3}; // Cikis sinyallerinin, cikistaki dagilim orani

void setup() {
    pinMode(rxPins[0], INPUT); //Servolarin pinlerini giris icin ayarla
    pinMode(rxPins[1], INPUT); //Servolarin pinlerini giris icin ayarla
    servos[0].attach(servoPins[0]);  //Servo nesnesini ilgili pine bagla
    servos[1].attach(servoPins[1]);  //Servo nesnesini ilgili pine bagla
}

void loop() {
    inPulses[0] = pulseIn(rxPin, HIGH, 100000); //Max. 100 milisaniye boyunca giriş darbesi okunuyor
    inPulses[1] = pulseIn(rxPin, HIGH, 100000); //Max. 100 milisaniye boyunca giriş darbesi okunuyor
    if((inPulses[0] > 800 && inPulses[0] < 2200) && (inPulses[1] > 800 && inPulses[1] < 2200)) { //İki alici kanalindan da sinyal aliniyorsa
        servoPulses[0] = ((inPulses[0] * inRatio[0]) + (inPulses[1] * inRatio[1])) / (inRatio[0] + inRatio[1]); // Oranlı olarak iki girisi topla ve cikisa ver
        servoPulses[1] = ((inPulses[0] * inRatio[0]) + ((3000 - inPulses[1]) * inRatio[1])) / (inRatio[0] + inRatio[1]); //Oranlı olarak girislerden birinin duzunu ve digerinin tersini topla ve cikisa ver
        servos[0].writeMicroseconds(servoPulses[0]); // Servo nesnesine bulunan degeri yaz.
        servos[1].writeMicroseconds(servoPulses[1]); // Servo nesnesine bulunan degeri yaz.
    }
}
 
Arduino ile VTail Mikser Yapımı

Demek ki bu oranlar plakete konulup analog girişten okunacak bir potansiyometre ile belirli sınırlar içinde değiştirilecek! :D :D :D
 
Arduino ile VTail Mikser Yapımı

Kafada kurulan algoritmanın koda dökülmesi çok zor. Beklenmedik, akla gelmedik hatalar çıkıyor. Ama V-Tail Mixer tamamdır. Test edildi. İstenildiği şekilde çalışıyor.

Elevatörü bir girişe rudder ya da aileronu diğer girişe (2 ve 3 No'lu digital girişler) bağlıyoruz.
İki servo çıkışı da 4 ve 5 No'lu digital çıkışlar.
İlk bağlantıda bir deneme yapıyoruz. Elevatör komutu ile yüzeyler aynı yönde, rudder/aileron komutu ile ters yönlerde hareket etmeli. Eğer bu olmuyorsa girişlerin yerini değiştiriyoruz.


Kod:
int elevator = 2;
int rudder = 3;
int elev_signal = 0;
int rudd_signal = 0;
int servo_1 = 4;
int servo_2 = 5;
int out_1 = 0;
int out_2 = 0;
unsigned long timer;
unsigned long x = 0;
unsigned long frame;


void setup()
{
  Serial.begin(9600);
  pinMode(elevator, INPUT);
  pinMode(rudder, INPUT);
  pinMode(servo_1, OUTPUT);
  pinMode(servo_2, OUTPUT);
}

void loop()
{
  elev_signal = pulseIn(elevator, HIGH, 25000);
  rudd_signal = pulseIn(rudder, HIGH, 25000);
  elev_signal = elev_signal - 1000;
  rudd_signal = rudd_signal - 1000;
  elev_signal = elev_signal / 2;
  rudd_signal = rudd_signal / 2;
  out_1 = elev_signal + rudd_signal + 1000;
  constrain(out_1, 800, 2200);
  out_2 = rudd_signal - elev_signal + 1500;
  constrain(out_2, 800, 2200);
  Serial.print("OUT2 = ");
  Serial.println(out_2);
  servoout();
}


void servoout()
{
  digitalWrite(servo_1, LOW);
  digitalWrite(servo_2, LOW);
  timer = micros();
  frame = timer;
  digitalWrite(servo_1, HIGH);
  while((micros() - timer) < out_1)
  {
  }
  digitalWrite(servo_1, LOW);
  digitalWrite(servo_2, HIGH);
  timer = micros();
  while((micros() - timer) < out_2)
  {
  }
  digitalWrite(servo_2, LOW);
  while((micros() - frame) < 20000)
    {
    }
}