開源自制的6通道航模遙控器(三)-遙控器端增加MIX混控模式

1.瞭解什麼是混控

要了解混控,需要先對比一般的遙控模式。一般遙控的每個操作控制都是一個通道,比如美國手的遙控器,左邊搖桿前後控制油門,左右控制方向舵;右邊搖桿前後控制升降舵,左右控制副翼(橫滾)。混控,顧名思義,就是混合控制的意思。用最常見的三角翼混控來舉例,就是2個通道來控制一個舵機,不管是你操作升降通道或是副翼通道,它都會做出一定的響應。比如右邊搖桿的左右同時控制副翼和方向舵。

混控就是一個動作(升降或者橫滾)可以和接收機兩個通道連着,動作舵量可以是兩個通道的矢量和,就是說兩個杆的控制信號需要疊加運算,再通過兩個通道輸出給舵面。

航模上最常用的就是三角翼混控(其實叫升降副翼混控),因爲三角翼將副翼和水平尾翼合爲一體了,尾翼的兩個舵面既控制升降,也控制橫滾(左旋/右旋),所以要想滿足飛手的操作習慣,必須用到混控,即roll通道和pitch通道能夠自由切換對尾翼兩個舵面的控制。一般混控在v型尾翼和直升機有應用。

2.混控的效果

接下來我們需要了解你需要混控的效果應該是什麼樣的。比如三角翼混控,有左右2個舵機。
左邊舵機插接收機升降通道(通道2)
右邊舵機插接收機副翼通道(通道1)

我們的目標的舵面效果應該是以下這樣的:

操作副翼搖桿往右,應該是右邊的舵面向上,左邊舵面向下。
操作升降搖桿往上,應該是左右舵面一起往下。

更多內容可以參考(http://www.moz8.com/thread-62769-1-1.html?_dsign=47c07247

3.代碼實現

基本瞭解了混控原理,接下來就可以用代碼實現了。我簡單用了if else語句,代碼簡陋了點,但功能基本實現了,也可以用座標變換之類的,效果更好。該部分代碼如下:

/*三角翼混控*/
  if(digitalRead(9)){//混控開關MIX打開時
    x = chValue( analogRead(A1), 59,  517, 882, digitalRead(2));//副翼舵量
    y = chValue( analogRead(A0), 115, 525, 896, digitalRead(3));//升降舵量
    CtrlRange = 5; // 識別的波動範圍,超過範圍則切換通道
    if (x>127-CtrlRange and x<127+CtrlRange){ // X軸在小範圍內波動,說明沒有打副翼
      data.roll = y;          // 此時兩個舵機只受升降舵控制
      data.pitch = y;
    }
    else{
      data.roll = 255-x;
      data.pitch = x;
    }
  }
  /*需要對搖桿的最值、中值進行設置*/
  else{
    data.roll     = chValue( analogRead(A0), 59,  517, 882, digitalRead(2));
    data.pitch    = chValue( analogRead(A1), 115, 525, 896, digitalRead(3));
  }

再加上引腳定義、變量聲明,就基本實現了混控功能了,遙控器端完整代碼如下:

/* ArduinoProMini-6通道發射器 
 *     by Bilibili 蔡子CaiZi
 *     
 * A0~5 -> 六通道電位器輸入
 * A6 -> 電壓檢測
 * 2~5 -> 通道正反開關
 * 6 -> 蜂鳴器
 * 9 -> 混控開關
 * 
 * NRF24L01 | Arduino
 * CE    -> 7
 * CSN   -> 8
 * MOSI  -> 11
 * MISO  -> 12
 * SCK   -> 13
 * IRQ   -> 無連接
 * VCC   -> 小於3.6V
 * GND   -> GND
 */
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
const uint64_t pipeOut = 0xBBBBBBBBB;   //爲何這麼多B幣?與接收器中相同的地址進行通信
RF24 radio(7, 8); // SPI通信,引腳對應關係:CE ->7,CSN ->8
struct Signal {
  byte roll;
  byte pitch;
  byte throttle;
  byte yaw;
  byte gyr;
  byte pit;
};
Signal data;
void ResetData() 
{
  data.roll = 127; // 橫滾通道AIL(中心點127)
  data.pitch = 127; // 俯仰通道ELE
  data.throttle = 0; // 信號丟失時,關閉油門THR
  data.yaw = 127; // 航向通道RUD
  data.gyr = 0; //第五通道
  data.pit = 0; //第六通道
}
void setup()
{
  radio.begin();
  radio.openWritingPipe(pipeOut);//pipeOut通信地址
  radio.stopListening(); //發射模式
  ResetData();//初始化6個通道值
  Serial.begin(115200);
  pinMode(2,INPUT);//正反通道開關爲數字輸入
  pinMode(3,INPUT);
  pinMode(4,INPUT);
  pinMode(5,INPUT);
  pinMode(9,INPUT);//混控開關
  pinMode(6,OUTPUT);//蜂鳴器推輓輸出
  if (analogRead(A6)*3.28*3/1023<5){//調整3校準電壓檢測,5爲報警電壓
    for(int i=0;i<3;i++){
      digitalWrite(6,HIGH);//蜂鳴器響
      delay(100);
      digitalWrite(6,LOW);
      delay(100);
    }
  }
  else{
    digitalWrite(6,HIGH);//蜂鳴器響
    delay(100);
    digitalWrite(6,LOW);
  }
}

// 將ADC獲取的0~1023轉換到0~255
int chValue(int val, int lower, int middle, int upper, bool reverse)
{
  val = constrain(val, lower, upper);//將val限制在lower~upper範圍內
  if ( val < middle )
    val = map(val, lower, middle, 0, 128);
  else
    val = map(val, middle, upper, 128, 255);
  return ( reverse ? 255 - val : val );
}
long x, y, left, right;//混控變量
void loop()
{
//  Serial.print("\t");Serial.print(analogRead(A0));//將數據通過串口輸出
//  Serial.print("\t");Serial.print(analogRead(A1));
//  Serial.print("\t");Serial.print(analogRead(A2));
//  Serial.print("\t");Serial.println(analogRead(A3));
  /*三角翼混控*/
  if(digitalRead(9)){//混控開關MIX打開時
    x = chValue( analogRead(A1), 59,  517, 882, digitalRead(2));//副翼舵量
    y = chValue( analogRead(A0), 115, 525, 896, digitalRead(3));//升降舵量
    CtrlRange = 5; // 識別的波動範圍,超過範圍則切換通道
    if (x>127-CtrlRange and x<127+CtrlRange){ // X軸在小範圍內波動,說明沒有打副翼
      data.roll = y;          // 此時兩個舵機只受升降舵控制
      data.pitch = y;
    }
    else{
      data.roll = 255-x;
      data.pitch = x;
    }
  }
  /*需要對搖桿的最值、中值進行設置*/
  else{
    data.roll     = chValue( analogRead(A0), 59,  517, 882, digitalRead(2));
    data.pitch    = chValue( analogRead(A1), 115, 525, 896, digitalRead(3));
  }
  data.throttle = chValue( analogRead(A2), 145, 522, 920, digitalRead(4));
  data.yaw      = chValue( analogRead(A3), 70,  530, 925, digitalRead(5));
  data.gyr      = chValue( analogRead(A4), 0,   510, 1020, false ); 
  data.pit      = chValue( analogRead(A5), 0,   510, 1020, false );  
  radio.write(&data, sizeof(Signal));//將數據發送出去
//  Serial.print("\t");Serial.print(data.roll);
//  Serial.print("\t");Serial.print(data.pitch);
//  Serial.print("\t");Serial.print(data.throttle);
//  Serial.print("\t");Serial.print(data.yaw);
//  Serial.print("\t");Serial.print(data.gyr);
//  Serial.print("\t");Serial.println(data.pit);
}

4.實現效果

接收機的通道1和通道2分別接了兩個舵機,可完成基本的自由切換,由於筆者手上沒有V翼航模,無法進行飛行測試,有朋友如果做了測試,歡迎在評論區留言哈~

Stay creative!我們下期再見!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章