Il y a quelque temps, j'ai acheté un petit hélicoptère jouet à commande infrarouge simple et bon marché (le même que celui-ci - il s'appelle "Diamond Gyro" ou "Diamond Force"). Pour le plaisir, j'ai cherché à le contrôler via un Arduino.
Mise à jour: Compris le protocole; voir la réponse
D'autres ont déjà partagé leurs résultats sur le piratage d'un autre hélicoptère jouet IR et le décodage de son protocole IR. Vraiment cool, mais malheureusement mon hélicoptère utilise un protocole différent. Un que je n'arrive pas à comprendre. (Je dois ajouter que l'électronique est purement un passe-temps pour moi, donc j'ai peut-être oublié quelque chose d'évident).
Tout comme dans le deuxième lien ci-dessus, j'ai démonté le contrôleur, localisé la broche IC contrôlant les LED (les marquages de l'IC ont été effacés, soit dit en passant) et branché un analyseur logique.
J'ai beaucoup de bonnes données, mais je n'arrive toujours pas à comprendre le protocole. Ce site est une excellente ressource, mais aucun des protocoles répertoriés ne semble convenir. Et rien d'autre que j'ai trouvé ne semble correspondre au signal que j'ai capturé non plus. Je dois imaginer, cependant, que c'est un protocole simple et standard, uniquement parce que c'est un petit jouet bon marché.
J'apprécierais donc toutes vos idées. Peut-être que je le regarde mal.
(Plus d'informations sous l'image)
Caractéristiques du signal / protocole
J'ai capturé cela à 16 MHz avec le contrôleur réglé sur le canal A; doit être précis et chronologique. (Il y a 3 canaux IR parmi lesquels vous pouvez choisir, mais l'utilisation des deux autres canaux ne change pas les caractéristiques, seulement des parties du paquet lui-même.) Les synchronisations sont très cohérentes (+/- 10µs max). Les paquets sont répétés à des intervalles variables, mais au minimum, ils sont distants d'environ 100 ms.
Porteuse: 38 kHz à 50% de rapport cyclique
Bas:
- Court: 285µs
- Long: 795µs
Hauts:
- Court: 275µs
- Long: 855µs
Toujours 17 sommets par paquet.
Commandes / entrées
Les hélicoptères ont 3 commandes: "Throttle" (c'est-à-dire la vitesse de levage / rotor), le tangage (avant / arrière) et le lacet (rotation autour de l'axe du rotor) tous contrôlés avec 2 baguettes. Ils ont tous une sorte de plage (pas seulement marche / arrêt) et sont, pour autant que je sache, tous transmis en un seul paquet. Les entrées gauche / droite ne sont envoyées que si quelque chose d'autre est envoyé, j'ai donc appliqué l'accélération maximale lors de l'échantillonnage. L'entrée des gaz et de la hauteur sur ses propres paquets de déclenchement est envoyée, dès que vous poussez les manettes au-delà d'un certain seuil / bande morte (dans le graphique ci-dessous, l'étiquette "min" correspond au premier paquet envoyé lorsque vous poussez lentement un contrôle au-delà de sa bande morte).
Il a également des boutons pour couper à gauche et à droite, car l'hélicoptère n'est pas un instrument de précision ( du tout ) et a tendance à tourner lentement sinon. Les boutons de trim gauche / droite ne semblent malheureusement pas envoyer un signal qui incrémente / décrémente quelque chose à chaque pression (ce qui serait pratique pour comprendre le protocole); il semble que ce soit une commande unique, indiquant à l'hélicoptère de compenser gauche / droite, puis il en garde la trace.
la source
Réponses:
Je prends la liberté de répondre à ma propre question car j'ai compris l'essentiel et c'est un bon moyen de partager mes résultats. Mes remerciements à Olin Lathrop pour m'avoir donné un point de départ et quelques idées à essayer, mais en fin de compte, le protocole s'est avéré assez différent de la supposition d'Olin, donc j'ai posté cette réponse.
Mise à jour: J'ai posté une question de suivi concernant les 8 derniers bits, que je ne comprenais pas complètement, et Dave Tweed l'a compris . Je vais inclure les détails ici, donc cette réponse peut fonctionner comme une spécification de protocole complète, mais allez vérifier la réponse de Dave.
J'ai dû essayer différentes choses pour comprendre cela, mais je suis assez confiant de l'avoir compris. Curieusement, je n'ai rien trouvé de semblable à ce protocole ailleurs, mais il pourrait très bien s'agir d'un protocole commun que je ne connais tout simplement pas.
Quoi qu'il en soit, voici ce que j'ai trouvé:
Protocole / encodage
Les impulsions et les espaces intermédiaires sont utilisés pour coder les données. Une impulsion / espace long est un binaire (1), et une impulsion / espace court est un zéro binaire (0). Les impulsions sont envoyées en utilisant une modulation infrarouge standard grand public de 38 kHz à un rapport cyclique de 50%.
Les temps d'impulsion / espace sont dans la question d'origine, mais je vais les répéter ici pour être complet:
Tous ± 10µs max., ± 5µs typ. Ceci est basé sur des échantillons capturés avec un analyseur logique à 16 MHz; Je n'ai pas d'oscilloscope, donc je ne connais pas le profil exact (c'est-à-dire les temps de montée / descente).
Les paquets sont répétés tant que les entrées de contrôle sont appliquées et semblent espacées d'au moins 100 ms.
La transmission des paquets commence par un préambule "impulsion 1", qui est fixe et ne fait pas partie des données. L'espace suivant code le premier bit de données du paquet et la dernière impulsion code le dernier bit.
Chaque paquet a une longueur de 32 bits et contient toutes les entrées que la télécommande peut fournir. Les valeurs sont lues comme peu endiennes, c'est-à-dire MSB en premier.
Structure de données
Vous trouverez ci-dessous la structure de base des paquets individuels. Les 8 derniers bits m'ont confondu, mais cela a été compris maintenant (voir ci-dessous).
Remarque: les plages sont basées sur les lectures les plus élevées que j'ai obtenues. Le protocole est capable de plus grandes gammes - jusqu'à 255 pour les gaz, 63 pour le tangage / lacet - mais plafonne à environ la moitié.
La valeur de hauteur semble avoir une zone morte de 14 à 21 (inclus); seules les valeurs supérieures ou inférieures font réellement réagir l'hélicoptère. Je ne sais pas si c'est la même chose pour le lacet (difficile à dire, car l'hélicoptère est instable de toute façon, et peut juste tourner légèrement tout seul).
Ici, c'est en termes graphiques (comparer avec le graphique de la question d'origine)
Les 6 bits de contrôle sont calculés en XOR 'toutes les valeurs précédentes. Chaque valeur est traitée comme 6 bits. Cela signifie que les 2 MSB de la valeur de limitation à 8 bits sont simplement ignorés. C'est à dire
Notes pratiques
Les timings et la modulation du signal n'ont pas besoin d'être super précis. Même le timing pas du tout précis de mon Arduino fonctionne très bien malgré une modulation douteuse et un peu de coups et échecs sur les durées d'impulsion / espace par rapport à la vraie télécommande.
Je crois - mais je n'ai pas testé - que l'hélicoptère se verrouillera simplement sur le canal du premier signal qu'il trouvera. S'il est laissé sans signal trop longtemps (quelques secondes), il semble revenir à son mode "recherche", jusqu'à ce qu'il acquière à nouveau un signal.
L'hélicoptère ignorera les valeurs de tangage et de lacet si la manette des gaz est nulle.
Les commandes de trim ne sont envoyées qu'une seule fois par pression sur un bouton de la télécommande. On peut supposer que la valeur de trim augmente / diminue simplement une valeur dans le propre contrôleur de l'hélicoptère; ce n'est pas quelque chose que la télécommande garde en mémoire. Donc, toute implémentation de ceci devrait probablement s'en tenir à ce schéma, et envoyer uniquement la valeur de trim occasionnelle gauche / droite, mais sinon, la valeur par défaut est zéro dans les paquets.
Je recommande d'avoir un kill switch qui met simplement l'accélérateur à zéro. Cela entraînera la chute de l'hélicoptère du ciel, mais il subira moins de dommages lorsqu'il ne fait pas tourner ses moteurs. Donc, si vous êtes sur le point de vous écraser ou de heurter quelque chose, appuyez sur le bouton d'arrêt pour éviter de démonter les engrenages ou de casser les lames.
Les LED IR de la télécommande d'origine semblent avoir une longueur d'onde> 900 nm, mais je n'ai aucun problème à utiliser une LED ~ 850 nm.
Le récepteur IR de l'hélicoptère est correct, mais pas super sensible, donc plus votre source IR est lumineuse, mieux c'est. La télécommande utilise 3 LED en série, reposant sur le rail 9V au lieu du rail 5V utilisé par la logique. Je n'ai pas vérifié leur tirage actuel très précisément, mais je parierais que c'est 50mA.
Exemples de données
Voici un tas de paquets, pour toute personne intéressée (oui, j'ai écrit un décodeur; je n'ai pas décodé tout cela à la main). Les paquets du canal A proviennent des mêmes captures que les graphiques de la question d'origine.
Comme mentionné ci-dessus, les 8 derniers bits ont été compris, mais juste pour la postérité, voici mes pensées originales. N'hésitez pas à l'ignorer complètement, car j'avais à peu près tort dans mes suppositions.
Les 8 derniers bits
Les 8 derniers bits du paquet sont encore un peu mystérieux.
Les 4 bits du bit 23 à 26 semblent tous être entièrement déterminés par le réglage du canal de la télécommande. Changer le canal sur la télécommande ne modifie en rien le protocole ou la modulation; cela ne change que ces 4 bits.
Mais 4 bits est le double de ce qui est réellement nécessaire pour coder le paramètre de canal; il n'y a que trois canaux, donc 2 bits suffisent. Par conséquent, dans la description de la structure ci-dessus, je n'ai étiqueté que les 2 premiers bits comme "Canal", et laissé les deux autres étiquetés "X", mais c'est une supposition.
Vous trouverez ci-dessous un échantillon des bits pertinents pour chaque paramètre de canal.
Fondamentalement, il y a 2 bits de plus que nécessaire pour transmettre le paramètre de canal. Peut-être que le protocole a 4 bits mis de côté pour permettre plus de canaux plus tard, ou alors le protocole peut être utilisé dans des jouets entièrement différents, mais je ne sais tout simplement pas. Pour les valeurs plus grandes, le protocole utilise des bits supplémentaires qui pourraient être laissés de côté (lacet / accélération / tangage pourraient se débrouiller avec un peu moins chacun), mais pour le trim - qui a également 3 états - seuls 2 bits sont utilisés. Donc, on pourrait soupçonner que le canal n'est également que de 2 bits, mais cela laisse les 2 suivants disparus.
L'autre possibilité est que la somme de contrôle du paquet soit de 8 bits, en commençant par les "X bits", et - grâce à la magie de la somme de contrôle - ils se trouvent toujours refléter le réglage du canal. Mais encore une fois: je ne sais pas.
Et en parlant de: je n'ai aucune idée de la façon dont ces bits de contrôle sont formés. Je veux dire, ce sont des bits de contrôle, car ils ne correspondent à aucune entrée de commande unique, et l'hélicoptère ne semble pas répondre si je les tripote. Je suppose que c'est une sorte de CRC, mais je n'ai pas pu le comprendre. La vérification est longue de 6 à 8 bits, selon la façon dont vous interprétez les «X bits», il existe donc de nombreuses façons de les assembler.
la source
Ça n'a pas l'air si mal. Remarquez tout d'abord que tous les messages contiennent exactement 17 impulsions. Cela nous donne immédiatement un indice fort que les espaces courts dans un message ne sont pas pertinents. Il semble que les données soient codées par des impulsions courtes ou longues, et qu'une certaine plage d'espacement entre ces impulsions est acceptable.
De toute évidence, chaque message commence par une longue impulsion comme bit de départ. Cela laisse 16 bits de données. Quelques-uns des premiers bits sont probablement un opcode, éventuellement de longueur variable. Si je faisais cela, quelques-uns des bits de fin seraient une somme de contrôle. Imaginez que les ingénieurs qui ont écrit le micrologiciel voulaient garder les choses simples pour eux-mêmes, vous pouvez donc commencer par supposer qu'il y a 8 bits de données quelque part. Maintenant, voyez si l'un des messages a du sens.
Appelons un long 1 et un court 0. Cela pourrait être l'inverse, mais nous devons commencer quelque part. Dépouillant le bit de départ laisse:
Quelques choses ressortent tout de suite. De toute évidence, le bit 0 est un bit de parité. Sinon, il semble y avoir un champ de 3 bits <15:13>, une valeur de données de 8 bits <12: 5> et un autre champ de 4 bits <4: 1>.
Il semble que la valeur des données soit envoyée par ordre de bits faible à élevé, il est donc probablement plus logique d'interpréter les 16 bits entiers à partir de ce que je montre.
Je n'ai pas envie de passer plus de temps là-dessus, mais j'espère que cela vous a donné un bon départ. Je procéderais en réécrivant la liste ci-dessus avec le bit de parité retiré, le nombre entier retourné LSB en MSB, et chaque champ supposé montré séparément avec un espace entre lui et le champ contigu. Cela pourrait permettre à davantage de vous sortir. Gardez également à l'esprit que nous pouvons avoir le sens 1/0 de chaque bit en arrière. Peut-être écrivez le nouveau tableau dans chaque sens et voyez si quelque chose a plus de sens dans un sens.
la source