我已经很自由地回答我自己的问题,因为我已经弄清了大部分问题,这是分享我的发现的一种好方法。感谢Olin Lathrop给我一个起点,并尝试了一些想法,但是最终,该协议与Olin的猜测完全不同,因此我发布了这个答案。
更新:我发布了有关后8位的后续问题,我没有完全理解,然后Dave Tweed弄清楚了。我将在此处提供详细信息,因此该答案可以作为完整的协议规范使用,但是请务必查看Dave的答案。
我必须尝试一些不同的事情才能弄清楚这个问题,但是我很自信我明白了。奇怪的是,我没有在其他地方找到任何类似于此协议的东西,但这很可能是我不知道的常见协议。
无论如何,这就是我所发现的:
协议/编码
脉冲和两者之间的空格均用于编码数据。长脉冲/空格为二进制一(1),短脉冲/空格为二进制零(0)。使用标准的消费者红外38kHz调制@ 50%占空比发送脉冲。
脉冲/空间时序是原始问题,但是为了完整起见,我将在这里重复它们:
Bit Pulse Space
-----+---------+---------
0 | 275µs | 285µs
1 | 855µs | 795µs
所有最大值为±10µs,典型值为±5µs。这是基于逻辑分析仪在16MHz频率下捕获的样本。我没有示波器,所以我不知道确切的轮廓(即上升/下降时间)。
只要应用了控制输入,数据包就会重复,并且看起来至少间隔100毫秒。
数据包传输以“脉冲1”前导开始,该前导是固定的,不是数据的一部分。接下来的空间编码数据包的第一个数据位,最后一个脉冲编码最后一个位。
每个数据包长32位,并包含遥控器可以提供的每个输入。值读为小端,即MSB在前。
数据结构
以下是各个数据包的基本结构。最后8位让我感到困惑,但是现在已经知道了(请参阅下文)。
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2
--+---------------------------+-----------+---+-------+-----------
P| Yaw | Throttle | Pitch | T | Chan. | Check
P: Preamble (always a pulse-1), T: Trim, Chan.: Channel
Bit Length Description (see note below)
-----------------------------------------------
0 1 Preamble. High 1
1-6 6 Yaw. Range 0-36 for left-right, 17 being neutral
7-14 8 Throttle. Range 0-134
15-20 6 Pitch. Range 0-38 for forward-back, 17 being neutral
21-22 2 Trim. Left = 1, right = 2, no trim = 0
23-26 4 Channel. A = 5, B = 2, C = 8
27-32 6 Check bits
注意:范围基于我得到的最高读数。该协议具有更大的范围-节气门最大255,俯仰/偏航最大63-但上限仅为该范围的一半。
音高值似乎具有14-21(含)的死区;只有高于或低于此值才能使直升机做出反应。我不知道偏航是否相同(很难说,因为直升机无论如何都是不稳定的,可能会自行稍微旋转)。
这是图形形式的(与原始问题中的图形相比)
6个校验位是通过对所有先前值进行异或运算而得出的。每个值均视为6位。这意味着将仅忽略8位调节值的2个MSB。即
check = yaw ^ (throttle & 0x3F) ^ pitch ^ trim ^ channel
实用笔记
信号时序和调制不需要非常精确。与真正的遥控器相比,即使我的Arduino的计时精度也不尽如人意,尽管调制方式比较笨拙,而且脉冲/空间持续时间有些打不上。
我相信-但尚未经过测试-直升机只会将其锁定在找到的第一个信号通道上。如果没有信号的时间过长(几秒钟),它似乎会回到“搜索”模式,直到再次获取信号为止。
如果油门为零,则直升机将忽略俯仰和偏航值。
修整命令仅在遥控器上每按一次按钮发送一次。推测调整值只是在直升机自己的控制器中增加/减少了一个值。遥控器无法跟踪。因此,此方法的任何实现都应遵循该方案,并且仅发送偶尔的修剪左/右值,否则默认将数据包中的修剪值设为零。
我建议您使用一个扼杀开关,将油门简单地设置为零。这将导致直升机掉出天空,但在不旋转电机时会受到较小的损害。因此,如果您要坠毁或撞到某些东西,请按一下kill开关,以免剥落齿轮或损坏刀片。
原始遥控器的IR LED似乎具有大于900nm的波长,但使用〜850nm LED时我没有任何问题。
直升机的红外接收器还可以,但不是超级敏感,因此红外光源越亮越好。遥控器使用3个串联的LED,它们位于9V导轨上,而不是逻辑电路使用的5V导轨上。尚未非常精确地检查其电流消耗,但我敢打赌它是50mA。
样本数据
对于有兴趣的人,这是一堆数据包(是的,我为解码器编写了脚本;我没有手工解码所有这些内容)。通道A数据包来自与原始问题中的图形相同的捕获。
Channel A
Yaw Throttle Pitch Tr Chan Check Description
-----------------------------------------------------------
000100 10000100 000000 00 0101 000101 Left Mid + Throttle
000000 10000110 010001 00 0101 010010 Left Max + Throttle
100001 10000110 000000 00 0101 100010 Right Mid + Throttle
100100 10000100 010001 00 0101 110100 Right Max + Throttle
010001 00000000 001011 00 0101 011111 Forward Min
010001 00000000 000000 00 0101 010100 Forward Max
010001 00000000 011000 00 0101 001100 Back Min
010001 00000000 100101 00 0101 110001 Back Max
010001 00000000 010001 01 0101 010101 Left Trim
010001 00000000 010001 10 0101 100101 Right Trim
010001 00000011 010001 00 0101 000110 Throttle 01 (min)
010001 00010110 010001 00 0101 010011 Throttle 02
010001 00011111 010001 00 0101 011010 Throttle 03
010001 00101111 010001 00 0101 101010 Throttle 04
010001 00111110 010001 00 0101 111011 Throttle 05
010001 01010101 010001 00 0101 010000 Throttle 06
010001 01011111 010001 00 0101 011010 Throttle 07
010001 01101100 010001 00 0101 101001 Throttle 08
010001 01111010 010001 00 0101 111111 Throttle 09
010001 10000101 010001 00 0101 000000 Throttle 10 (max)
Channel B
Yaw Throttle Pitch Tr Chan Check Description
-----------------------------------------------------------
000000 10000110 010001 00 0010 010101 Left Max + Throttle
100100 10000110 010001 00 0010 110001 Right Max + Throttle
010001 00000000 001001 00 0010 011010 Forward Min
010001 00000000 000000 00 0010 010011 Forward Max
010001 00000000 010111 00 0010 000100 Back Min
010001 00000000 100110 00 0010 110101 Back Max
010001 00000000 010001 01 0010 010010 Left Trim
010001 00000000 010001 10 0010 100010 Right Trim
010001 00000001 010001 00 0010 000011 Throttle Min
010001 00110100 010001 00 0010 110110 Throttle Mid
010001 01100111 010001 00 0010 100101 Throttle High
010001 10001111 010001 00 0010 001101 Throttle Max
Channel C
Yaw Throttle Pitch Tr Chan Check Description
-----------------------------------------------------------
000000 10000101 010001 00 1000 011100 Left Max + Throttle
100100 10000101 010001 00 1000 111000 Right Max + Throttle
010001 00000000 001010 00 1000 010011 Forward Min
010001 00000000 000000 00 1000 011001 Forward Max
010001 00000000 010111 00 1000 001110 Back Min
010001 00000000 100110 00 1000 111111 Back Max
010001 00000000 010001 01 1000 011000 Left Trim
010001 00000000 010001 10 1000 101000 Right Trim
010001 00000001 010001 00 1000 001001 Throttle Min
010001 00110100 010001 00 1000 111100 Throttle Mid
010001 01100110 010001 00 1000 101110 Throttle High
010001 10000101 010001 00 1000 001101 Throttle Max
如上所述,已经确定了最后8位,但仅出于后人考虑,这是我最初的想法。随意完全忽略它,因为我的猜测几乎是错误的。
最后8位
数据包的最后8位仍然是个谜。
从位23到26的4位似乎完全由遥控器的通道设置确定。更改遥控器上的频道不会以任何方式改变协议或调制方式。它只会更改这4位。
但是4位是编码通道设置实际需要的两倍。只有三个通道,所以2位就足够了。因此,在上面的结构描述中,我仅将前2位标记为“通道”,而将其余2位标记为“ X”,但这是一个猜测。
以下是每个通道设置的相关位示例。
Chan. Bits 23-26
-----+-------------
A | 0 1 0 1
B | 0 0 1 0
C | 1 0 0 0
基本上,传输通道设置所需的位数比需要的多2位。也许协议保留了4位以供以后使用更多通道,或者该协议可用于完全不同的玩具中,但我只是不知道。对于较大的值,协议确实使用了可能被忽略的额外位(偏航/节气门/节距可能少了一点),但是对于微调(也具有3种状态),仅使用了2位。因此,人们可能会怀疑该通道也只有2位,但是接下来的2位却没有得到说明。
另一种可能性是,数据包的校验和是8位长,从“ X位”开始,并且-通过校验和魔术,它们恰好总是以某种方式反映了通道设置。但是,再次:我不知道。
谈到:我不知道这些校验位是如何形成的。我的意思是,它们是校验位,因为它们不与任何单个控制输入相对应,并且如果我摆弄它们,直升机似乎也没有响应。我猜这是某种类型的CRC,但我无法弄清楚。支票的长度为6-8位,具体取决于您解释“ X位”的方式,因此有很多方法可以组合在一起。