分享

遥控直升飞机协议解码+原理解读

 云深无际 2021-11-15

童年特别想要的小飞机,现在5块一个。。。,找了个朋友,整了一包回来了。想要的也可以私信我,拼着买,才便宜!

买了好多。。。

捡了垃圾我必然是想搞逆向的,不然能干嘛。。。

先说原理,在说协议~

我查原理一般是用谷歌学术查

很好用

还能导出文件做一些后处理

https://patents.google.com/

这个原理上面比较复杂,我只讲一点,等我有时间我再编辑一篇好文,现在就是简单的写写。

桨距和桨叶角

桨距指的是直升机的旋翼或固定翼的螺旋桨旋转一周360度,向上或向前行走的距离(理论上的)。就好比一个螺丝钉,拧一圈后,能够拧入的长度。桨距越大前进的距离就越大,反之越小!桨叶角也叫攻角,是指桨叶角指桨叶与垂直于主轴平面的夹角。可以直接测量。

换算公式为: 桨距=2πRtan(桨叶角),其中R为所计算位置与主轴的距离。

对于绝大多数的模型直升机,为了满足特技飞行的需要使用的旋翼常常是不等距旋翼,旋翼的外侧桨距大,内侧桨距小。对于这一类模型直升机,常常不使用桨距这一概念,取而代之的是桨叶角这一概念,桨叶角指旋翼与垂直于主轴平面的夹角。在不等距旋翼中,各处的桨叶角是相等的。

对于如图所示的简易直升机,使用的是等距旋翼,这种旋翼各处桨距相等,但是内侧桨叶角大,外侧桨叶角小。这种旋翼升力大,效率高,但是无法实现特技飞行。

这满满的廉价感。。。

这个东西叫:倾斜盘(也叫十字盘)以及各种连杆和跷跷板结构。

这种三通的直升飞机用的是双浆反向旋转设计的,上下浆反向旋转,如果扭力刚好相同者三通飞机左右转向靠的就是这原理。一般起飞时是刚好平衡的,三通的遥控器上会有微调。

直升飞机向前飞的原因是主螺旋翼和副螺旋翼不平行,副螺旋翼前倾,导致它旋转的时候会向后施加一个力道,这个力使得飞机向前飞。

贝尔-希拉操纵方式

找到两个玩具的专利,下面展示一下:

就是加了个大圈

尾翼双螺旋桨(这是一个玩具的专利)

关于这个控制协议,我找了一下,这个价位的东西应该是用的红外线控制的。然后协议也比较明了了。

16M的速度就可以把所有的信息保存下来。

https://qastack.cn/electronics/94343/help-with-or-hints-for-decoding-an-ir-protocol

拆机

它这里是把这个发射的电路怼示波器口子上面了

波形是使用油门和方向控制杆设置的组合记录的(点击放大)。为了获得这些波形,将示波器设置为深存储器模式,并对每次运行的结果进行调整,以便对齐命令的开头。请注意,X 轴不代表时间,它仅代表我的示波器屏幕截图中的像素数。

从上面的波形捕获可以看出,每个信号由 34 个脉冲组成。由于数字系统的信息以字节表示,因此可以合理地假设脉冲形成一个 4 字节的信号,其中额外的两个脉冲作为首部。基于此假设,第一个高-低-高转换标志着命令的开始。在这里,我将其称为头。由于脉冲宽度相同(头部除外),因此通过低电平的持续时间区分 1 和 0。下图显示了信号的时序:

38Khz的载波模式:

命令持续时间:180 毫秒标头高持续时间:2.04 毫秒标题低持续时间:2 us脉冲宽度:380us 0 的低持续时间:220 us1 的低持续时间:600 us

57Khz的载波模式:

命令持续时间:160 毫秒1 的低持续时间:660 us
No. Throttle Direction Binary Dec(Hex)00 ~0% Middle 00111100 00111111 10001011 00110100 60(3C) 63(3F) 139(8B) 52(34)01 ~25% Middle 00111100 00111111 10100111 00110100 60(3C) 63(3F) 167(A7) 52(34)02 ~50% Middle 00111100 00111111 11001000 00110100 60(3C) 63(3F) 200(C8) 52(34)03 ~75% Middle 00111100 00111111 11100110 00110100 60(3C) 63(3F) 230(E6) 52(34)04 100% Middle 00111100 00111111 11111101 00110100 60(3C) 63(3F) 253(FD) 52(34)05 100% Left 01101010 00111111 11111101 00110100 106(6A) 63(3F) 253(FD) 52(34)06 100% Right 00001000 00111111 11111101 00110100 8(8) 63(3F) 253(FD) 52(34)07 100% Forward 01000000 00000001 11111101 00110100 64(40) 1(1) 253(FD) 52(34)08 100% Backward 00111100 01111110 11111111 00110100 60(3C) 126(7E) 255(FF) 52(34)09 ~0% Left 01101010 00111111 10001101 00110100 106(6A) 63(3F) 141(8D) 52(34)10 ~0% Right 00001000 00111111 10001101 00110100 8(8) 63(3F) 141(8D) 52(34)11 ~0% Forward 01000000 00000001 10001101 00110100 64(40) 1(1) 141(8D) 52(34)12 ~0% Backward 00111100 01111101 10010001 00110100 60(3C) 125(7D) 145(91) 52(34)

解码表在此

Timer1 来生成 180 毫秒的命令重复间隔。Timer2 用于生成 38kHz 50% 占空比 PWM 载波信号。通过使用delayMicroseconds在所需持续时间内打开和关闭 38kHz 信号来生成0和1。

三个电位器分别用于控制转子速度(油门)、向前/向后运动和向左/向右旋转。由于校准可以提前完成,这里选择在代码中硬编码校准值以简化控制。当然,可以为此使用第四个电位计,就地调节。

简单的连线

正常控制

#include <TimerOne.h>
//comment this out to see the demodulated waveform//it is useful for debugging purpose.#define MODULATED 1
const int IR_PIN = 3;const unsigned long DURATION = 180000l;const int HEADER_DURATION = 2000;const int HIGH_DURATION = 380;const int ZERO_LOW_DURATION = 220;const int ONE_LOW_DURATION = 600;const byte ROTATION_STATIONARY = 60;const byte CAL_BYTE = 52;
int Throttle, LeftRight, FwdBack;
void sendHeader(){#ifndef MODULATED digitalWrite(IR_PIN, HIGH);#else TCCR2A |= _BV(COM2B1);#endif
delayMicroseconds(HEADER_DURATION);
#ifndef MODULATED digitalWrite(IR_PIN, LOW);#else TCCR2A &= ~_BV(COM2B1);#endif
delayMicroseconds(HEADER_DURATION);
#ifndef MODULATED digitalWrite(IR_PIN, HIGH);#else TCCR2A |= _BV(COM2B1);#endif
delayMicroseconds(HIGH_DURATION);
#ifndef MODULATED digitalWrite(IR_PIN, LOW);#else TCCR2A &= ~_BV(COM2B1);#endif}
void sendZero(){ delayMicroseconds(ZERO_LOW_DURATION);
#ifndef MODULATED digitalWrite(IR_PIN, HIGH);#else TCCR2A |= _BV(COM2B1);#endif
delayMicroseconds(HIGH_DURATION);
#ifndef MODULATED digitalWrite(IR_PIN, LOW);#else TCCR2A &= ~_BV(COM2B1);#endif}
void sendOne(){ delayMicroseconds(ONE_LOW_DURATION);
#ifndef MODULATED digitalWrite(IR_PIN, HIGH);#else TCCR2A |= _BV(COM2B1);#endif
delayMicroseconds(HIGH_DURATION);
#ifndef MODULATED digitalWrite(IR_PIN, LOW);#else TCCR2A &= ~_BV(COM2B1);#endif}
void sendCommand(int throttle, int leftRight, int forwardBackward){ byte b;
sendHeader();
for (int i = 7; i >= 0; i--) { b = ((ROTATION_STATIONARY + leftRight) & (1 << i)) >> i; if (b > 0) sendOne(); else sendZero(); }
for (int i = 7; i >= 0; i--) { b = ((63 + forwardBackward) & (1 << i)) >> i; if (b > 0) sendOne(); else sendZero(); }
for (int i = 7; i >= 0; i--) { b = (throttle & (1 << i)) >> i; if (b > 0) sendOne(); else sendZero(); }
for (int i = 7; i >= 0; i--) { b = (CAL_BYTE & (1 << i)) >> i; if (b > 0) sendOne(); else sendZero(); }}
void setup(){ pinMode(IR_PIN, OUTPUT); digitalWrite(IR_PIN, LOW);
//setup interrupt interval: 180ms Timer1.initialize(DURATION); Timer1.attachInterrupt(timerISR);
//setup PWM: f=38Khz PWM=0.5 byte v = 8000 / 38; TCCR2A = _BV(WGM20); TCCR2B = _BV(WGM22) | _BV(CS20); OCR2A = v; OCR2B = v / 2;}
void loop(){}
void timerISR(){ //read control values from potentiometers Throttle = analogRead(0); LeftRight = analogRead(1); FwdBack = analogRead(2);
Throttle = Throttle / 4; //convert to 0 to 255 LeftRight = LeftRight / 8 - 64; //convert to -64 to 63 FwdBack = FwdBack / 4 - 128; //convert to -128 to 127
sendCommand(Throttle, LeftRight, FwdBack);}

宏变量和函数

一些固定参数

配置

关于直升飞机的原理我也参考了一些论文和专利,需要的话私聊

超过几个月的就不要来要了,我肯定找不到了。。。

http://www.kerrywong.com/2012/08/27/reverse-engineering-the-syma-s107g-ir-protocol/

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多