Estou tendo a liberdade de responder à minha própria pergunta, conforme descobri a maior parte e essa é uma boa maneira de compartilhar minhas descobertas. Meus agradecimentos a Olin Lathrop por me dar um lugar para começar e algumas idéias para experimentar, mas, em última análise, o protocolo ficou bem diferente do palpite de Olin, por isso, eu postando esta resposta.
Atualização: postei uma pergunta de acompanhamento referente aos últimos 8 bits, que não entendi completamente, e Dave Tweed descobriu . Vou incluir os detalhes aqui, para que esta resposta possa funcionar como a especificação completa do protocolo, mas consulte a resposta de Dave.
Eu tive que tentar algumas coisas diferentes para descobrir isso, mas estou bastante confiante de que entendi. Estranhamente, não encontrei nada parecido com este protocolo em outro lugar, mas pode muito bem ser um protocolo comum que simplesmente não conheço.
Enfim, aqui está o que eu encontrei:
Protocolo / codificação
Os pulsos e os espaços intermediários são usados para codificar os dados. Um pulso / espaço longo é um binário (1) e um pulso / espaço curto é zero binário (0). Os pulsos são enviados usando a modulação infravermelha padrão do consumidor de 38kHz a 50% do ciclo de trabalho.
Os tempos de pulso / espaço estão na pergunta original, mas vou repeti-los aqui para completar:
Bit Pulse Space
-----+---------+---------
0 | 275µs | 285µs
1 | 855µs | 795µs
Todos os ± 10µs máx., ± 5µs tip .. Isso é baseado em amostras capturadas com um analisador lógico em 16MHz; Não tenho um osciloscópio, portanto não conheço o perfil exato (ou seja, os tempos de subida / descida).
Os pacotes são repetidos desde que as entradas de controle sejam aplicadas e pareçam espaçadas a um mínimo de 100ms.
A transmissão de pacotes começa com um preâmbulo "pulso 1", que é fixo e não faz parte dos dados. O espaço a seguir codifica o primeiro bit de dados do pacote e o último pulso codifica o último bit.
Cada pacote tem 32 bits e contém todas as entradas que o controle remoto pode fornecer. Os valores são lidos como pouco endian, ou seja, MSB primeiro.
Estrutura de dados
Abaixo está a estrutura básica dos pacotes individuais. Os últimos 8 bits me confundiram, mas isso já foi descoberto (veja abaixo).
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
Nota: As faixas são baseadas nas leituras mais altas que obtive. O protocolo é capaz de faixas maiores - até 255 para acelerador, 63 para afinação / guinada -, mas alcança cerca de metade disso.
O valor do pitch parece ter uma faixa morta de 14 a 21 (inclusive); somente valores acima ou abaixo fazem o helicóptero reagir. Não sei se é o mesmo para a guinada (difícil dizer, já que o helicóptero é instável de qualquer maneira e pode girar um pouco por conta própria).
Aqui está em termos gráficos (compare com o gráfico na pergunta original)
Os 6 bits de verificação são calculados com XOR em todos os valores anteriores. Cada valor é tratado como 6 bits. Isso significa que os 2 MSBs do valor do acelerador de 8 bits são simplesmente ignorados. Ou seja,
check = yaw ^ (throttle & 0x3F) ^ pitch ^ trim ^ channel
Notas práticas
Os tempos e a modulação do sinal não precisam ser super precisos. Até o tempo não exato de meu Arduino funciona bem, apesar da modulação desonesta e de um pouco de acerto e falha nas durações de pulso / espaço em comparação com o controle remoto real.
Acredito - mas ainda não testei - que o helicóptero simplesmente trava no canal do primeiro sinal encontrado. Se ficar sem sinal por muito tempo (alguns segundos), ele parece voltar ao modo "pesquisa", até adquirir um sinal novamente.
O helicóptero ignorará os valores de inclinação e guinada se o acelerador for zero.
Os comandos de corte são enviados apenas uma vez por pressionar o botão no controle remoto. Presumivelmente, o valor de compensação simplesmente aumenta / diminui um valor no próprio controlador do helicóptero; não é algo que o controle remoto controla. Portanto, qualquer implementação disso provavelmente deve se ater a esse esquema e enviar apenas o valor ocasional de ajuste esquerdo / direito, mas, por outro lado, é padrão para um valor de ajuste zero nos pacotes.
Eu recomendo ter um interruptor de interrupção que simplesmente ajuste o acelerador para zero. Isso fará com que o helicóptero caia do céu, mas sofrerá menos danos quando não estiver girando seus motores. Portanto, se você estiver prestes a bater ou bater em alguma coisa, pressione o botão de matar para evitar arrancar as engrenagens ou quebrar as lâminas.
Os LEDs IR do controle remoto original parecem ter um comprimento de onda> 900nm, mas não tenho problemas ao usar um LED ~ 850nm.
O receptor de infravermelho do helicóptero está ok, mas não é super sensível, portanto, quanto mais brilhante sua fonte de infravermelho, melhor. O controle remoto usa 3 LEDs em série, posicionados no trilho de 9V em vez do trilho de 5V usado pela lógica. Ainda não checamos o draw atual com muita precisão, mas aposto que é 50mA.
Dados de amostra
Aqui estão alguns pacotes para qualquer pessoa interessada (sim, escrevi um decodificador; não decodifiquei tudo isso à mão). Os pacotes do canal A são provenientes das mesmas capturas que os gráficos da pergunta original.
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
Como mencionado acima, os últimos 8 bits foram descobertos, mas apenas para a posteridade, aqui estão os meus pensamentos originais. Sinta-se livre para ignorá-lo completamente, pois eu estava quase errado em minhas suposições.
Os últimos 8 bits
Os últimos 8 bits do pacote ainda são um pouco misteriosos.
Todos os 4 bits do bit 23 a 26 parecem ser inteiramente determinados pela configuração do canal do controle remoto. Alterar o canal no controle remoto não altera o protocolo ou modulação de forma alguma; apenas altera esses 4 bits.
Mas 4 bits é o dobro do que é realmente necessário para codificar a configuração do canal; existem apenas três canais, então 2 bits é suficiente. Portanto, na descrição da estrutura acima, eu apenas rotulei os 2 primeiros bits como "Canal" e deixei os outros dois rotulados como "X", mas isso é um palpite.
Abaixo está uma amostra dos bits relevantes para cada configuração de canal.
Chan. Bits 23-26
-----+-------------
A | 0 1 0 1
B | 0 0 1 0
C | 1 0 0 0
Basicamente, existem 2 bits a mais do que o necessário para transmitir a configuração do canal. Talvez o protocolo tenha 4 bits reservados para permitir mais canais posteriormente, ou então o protocolo possa ser usado em brinquedos completamente diferentes, mas eu simplesmente não sei. Para valores maiores, o protocolo usa bits extras que podem ser deixados de fora (guinada / acelerador / afinação podem passar um pouco menos cada), mas para trim - que também tem 3 estados - apenas 2 bits são usados. Portanto, pode-se suspeitar que o canal também tenha apenas 2 bits, mas isso deixa os 2 próximos não contabilizados.
A outra possibilidade é que a soma de verificação do pacote tenha 8 bits de comprimento, começando com os "X bits" e - através da mágica da soma de verificação - eles apenas refletem de alguma forma sempre a configuração do canal. Mas novamente: eu não sei.
E por falar em: não tenho idéia de como esses bits de verificação são formados. Quero dizer, são bits de verificação, pois não correspondem a nenhuma entrada de controle e o helicóptero não parece responder se eu mexer com eles. Acho que é algum tipo de CRC, mas não consegui descobrir. A verificação tem duração de 6 a 8 bits, dependendo de como você interpreta os "bits X", portanto, existem várias maneiras que podem ser reunidas.