童年特别想要的小飞机,现在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 us 1 的低持续时间: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/ |
|