开源自制的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 
#include 
#include 
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!我们下期再见!

你可能感兴趣的:(Arduino)