无线电遥控发射器 - 操纵杆
基于 Arduino 的自制操纵杆式无线电遥控发射器。
引言
传统上,遥控飞机/直升机/四轴飞行器的飞行员使用双拇指摇杆式发射器,但特别是对于四轴飞行器的飞行员来说,这不是一种非常直观的飞行方式,尤其是对于初学者来说。
我们都看过电影,并且至少模糊地知道真正的飞机/宇宙飞船的飞行员使用摇杆。那么为什么不在遥控飞机上使用呢?
我项目的基本想法是以尽可能简单的方式实现摇杆解决方案,但要满足我的确切要求。
背景
Arduino 是一个开源电子原型平台,基于灵活、易于使用的硬件和软件。
对于这个项目,我选择了 Arduino NANO,因为它体积小,I/O 要求低。它与摇杆电位器 (0-5vdc)、开关和串行 LCD 接口。然后输出串行数据流 (PPM),并与现成的 430Mhz 发射器模块/pcb 接口。
照片
外部 - 这是两个不同 PC 游戏摇杆的混合体,一个是底座,另一个是手柄。手柄是 3D 类型的,即通过扭动手柄以及通常的副翼/升降舵控制(前进/后退/左/右)来提供方向舵控制。
内部 - 家庭项目不应该是整洁的(把这留给日常工作!)。
在这里,您将看到 Arduino NANO pcb、430Mhz Tx pcb、底座中的 Lipo 电池以及盖子中的 LCD 模块和开关。
PPM 数据流 - 整个项目围绕提供与 430Mhz Tx 板上的输入兼容的 PPM 流展开。这在传统的遥控发射器制造商中几乎是一种行业标准,他们使用此接口将两个发射器连接在一起,用于新手飞行员的“主/伙伴”场景。参考 Futaba。
430MHz 发射器 pcb 的制造商将其电路板设计为适合这种情况,因此相对来说,我很清楚需要向发射器发送什么才能使飞机上的伺服系统等做出相应的反应。
PPM 是一种 PWM。在下面的照片中,有 6 个通道构成 PPM 流,并且每 22 毫秒重复一次。因此,从长的同步脉冲开始,您将获得 300uS 的固定 LO 脉冲,然后是通道脉冲 HI(范围 700 到 1700 uS),然后是下一个固定 LO 脉冲,依此类推。
附注:忽略红色轨迹,它仅用于同步我的示波器。
视频
Using the Code
代码分为两部分,主 PDE 和一个包含文件(LCD 例程)
- RCJoystick_IanJ_V2.pde
- LCD0821.pde
大多数 VAR 设置都在主代码的顶部完成,但是,底部附近需要额外的设置来选择摇杆速率。
主例程 = RCJoystick_IanJ_V2.pde。
// RC Joystick 430mHz
// For use with Arduino Nano V3.0
// Ian Johnston 28/04/2010
//
// Ver 1.6 - Now using Timer1 to set 22mS refresh for PPM output.
// Dual rates are implemented but need custom setup.
// Trimming is not working.
// Battery monitor sub tweaked
// Adjusted timing off various subs
// Various tweaks to LCD & battery monitor
//
// LCD type = LCD0821 Matrix Orbital (serial TTL)
// Make sure LCD0821.pde is in the same dir as RCJoystick_IanJ_V2.pde
ISR 在所需的 22mS 间隔调用 ppmoutput
例程,还会更新用于其他地方计时的时钟节拍。
ISR(TIMER1_COMPA_vect) {
ppmoutput(); // Jump to ppmoutput subroutine
tick = tick + 1; // update timing tick for subs
tick2 = tick2 + 1; // update tick
}
定时器设置。这是整个事情的核心,它定义了一个 22 毫秒的定时器,该定时器创建循环 PPM 流。一些遥控发射器对 22 毫秒的定时非常敏感,因此使用精确的定时器而不是即时定时至关重要。
// Setup timer
TCCR1A = B00110001; // Compare register B used in mode '3'
TCCR1B = B00010010; // WGM13 and CS11 set to 1
TCCR1C = B00000000; // All set to 0
TIMSK1 = B00000010; // Interrupt on compare B
TIFR1 = B00000010; // Interrupt on compare B
OCR1A = 22000; // 22mS PPM output refresh
OCR1B = 1000;
}
这是主循环的一部分,其中使用时钟节拍来生成 LCD 刷新和调用面板开关以及电池监视器子例程的定时。
if (tick >= 11) { // only run certain subs every 1/4 sec or so (22mS * 11 = 242mS)
tick = 0;
switchesRates(); // Run sub - read panel switches
batterymonitor(); // Run sub - check battery
}
// generate slow changing flag, about 2sec on/off
if (tick2 <= 50) {
slowflag = 0;
}
if (tick2 >= 50 && tick2 <=100) {
slowflag = 1;
}
if (tick2 >= 100) {
slowflag = 0;
tick2 = 0;
}
}
从摇杆电位器读取原始值后,现在使用 Y=MX+C 将其缩放到适合在 PPM 流上直接输出的值。
使用 MAP,可以轻松地在物理电位器反转的情况下反转方向。没有精巧/简单的校准程序,所有内容都必须硬编码在代码中,每次进行更改时都编译并上传到 Arduino。
// Compensate for discrepancy in pot inputs including centering offset.
// Also use this to invert inputs if necessary (swap x1 & y1)
// y=mx+c, x to y scales to x1 to y1
AI_TIpot = map(AI_Raw_TIpot, 0, 1023, 1023, 0) + 0; // TI pot
AI_Throt = map(AI_Raw_Throt, 0, 1023, -25, 1150) - 0; // Throttle
AI_Rudde = map(AI_Raw_Rudde, 0, 1023, 0, 1023) + 0; // Rudder
AI_Eleva = map(AI_Raw_Eleva, 0, 1023, 0, 1023) + 0; // Elevator
AI_Aeler = map(AI_Raw_Aeler, 0, 1023, 0, 1023) + 0; // Aeleron
AI_Batte = AI_Raw_Batte / 36.2; // Battery
添加偏移量和额外缩放。这是“速率”选择,它为摇杆提供从温和到粗略的功能。
// Map analogue inputs to PPM rates for each of the channels
Aeleron_uS = (AI_Aeler * DualrateMultAel) + pulseMin + DualrateAdjAel;
Elevator_uS = (AI_Eleva * DualrateMultEle) + pulseMin + DualrateAdjEle;
Throttle_uS = (AI_Throt * DualrateMultThr) + pulseMin + DualrateAdjThr;
Rudder_uS = (AI_Rudde * DualrateMultRud) + pulseMin + DualrateAdjRud;
TI_uS = (AI_TIpot * DualrateMultTI) + pulseMin + DualrateAdjTI;
}
这是 PPM 输出子程序的一部分。只需按顺序构建输出流。当然,有更多精巧的方法来编码这样的数据流,例如使用数组,但是按照我的简报,目的是在短时间内启动并运行它。
void ppmoutput() { // PPM output sub
// Channel 1 - Aeleron
digitalWrite(outPinPPM, LOW);
delayMicroseconds(Fixed_uS); // Hold
digitalWrite(outPinPPM, HIGH);
delayMicroseconds(Aeleron_uS); // Hold for Aeleron_uS microseconds
// Channel 2 - Elevator
digitalWrite(outPinPPM, LOW);
delayMicroseconds(Fixed_uS); // Hold
digitalWrite(outPinPPM, HIGH);
delayMicroseconds(Elevator_uS); // Hold for Elevator_uS microseconds
// Channel 3 - Throttle
digitalWrite(outPinPPM, LOW);
delayMicroseconds(Fixed_uS); // Hold
digitalWrite(outPinPPM, HIGH);
delayMicroseconds(Throttle_uS); // Hold for Throttle_uS microseconds
// Channel 4 - Rudder
digitalWrite(outPinPPM, LOW);
delayMicroseconds(Fixed_uS); // Hold
digitalWrite(outPinPPM, HIGH);
delayMicroseconds(Rudder_uS); // Hold for Rudder_uS microseconds
// Channel 5 - TI Switch
digitalWrite(outPinPPM, LOW);
delayMicroseconds(Fixed_uS); // Hold
digitalWrite(outPinPPM, HIGH);
delayMicroseconds(TIsw_uS); // Hold for TIsw_uS microseconds
// Channel 6 - TI pot
digitalWrite(outPinPPM, LOW);
delayMicroseconds(Fixed_uS); // Hold
digitalWrite(outPinPPM, HIGH);
delayMicroseconds(TI_uS); // Hold for TI_uS microseconds
构建 PPM 流的最后一部分是生成同步脉冲,该脉冲构成从最后一个 PPM 通道(其定时会变化)到下一次第 1 个通道开始的时间。
因此,启动脉冲,但不要立即完成它,因为现在可以完成内务管理,例如更新 LCD、读取面板开关等。
// Synchro pulse
digitalWrite(outPinPPM, LOW);
delayMicroseconds(Fixed_uS); // Hold
digitalWrite(outPinPPM, HIGH); // Start Synchro pulse
}
关注点
对于我们遥控新手来说,使用摇杆飞行要容易得多,并且为了增加一个额外的维度,只需尝试在晚上黑暗中使用一些高功率 LED。非常有趣!
历史
- V1.6 Current (V1.6 电流)