要了解混控,需要先对比一般的遥控模式。一般遥控的每个操作控制都是一个通道,比如美国手的遥控器,左边摇杆前后控制油门,左右控制方向舵;右边摇杆前后控制升降舵,左右控制副翼(横滚)。混控,顾名思义,就是混合控制的意思。用最常见的三角翼混控来举例,就是2个通道来控制一个舵机,不管是你操作升降通道或是副翼通道,它都会做出一定的响应。比如右边摇杆的左右同时控制副翼和方向舵。
混控就是一个动作(升降或者横滚)可以和接收机两个通道连着,动作舵量可以是两个通道的矢量和,就是说两个杆的控制信号需要叠加运算,再通过两个通道输出给舵面。
航模上最常用的就是三角翼混控(其实叫升降副翼混控),因为三角翼将副翼和水平尾翼合为一体了,尾翼的两个舵面既控制升降,也控制横滚(左旋/右旋),所以要想满足飞手的操作习惯,必须用到混控,即roll通道和pitch通道能够自由切换对尾翼两个舵面的控制。一般混控在v型尾翼和直升机有应用。
接下来我们需要了解你需要混控的效果应该是什么样的。比如三角翼混控,有左右2个舵机。
左边舵机插接收机升降通道(通道2)
右边舵机插接收机副翼通道(通道1)
我们的目标的舵面效果应该是以下这样的:
操作副翼摇杆往右,应该是右边的舵面向上,左边舵面向下。
操作升降摇杆往上,应该是左右舵面一起往下。
更多内容可以参考(http://www.moz8.com/thread-62769-1-1.html?_dsign=47c07247)
基本了解了混控原理,接下来就可以用代码实现了。我简单用了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);
}
接收机的通道1和通道2分别接了两个舵机,可完成基本的自由切换,由于笔者手上没有V翼航模,无法进行飞行测试,有朋友如果做了测试,欢迎在评论区留言哈~
Stay creative!我们下期再见!