Du coup, j'ai voulu aller plus loin en pilotant ces trucs moi aussi, avec un ordinateur par exemple. Dans la page qui suivra, je décrirai le reverse-engineering de ces choses et la construction d'un emetteur contrôlable par logiciel (Win32 et Linux).
La première chose a faire a été de pouvoir capturer des trames pour les analyser. Le faire directement sur la télécommande en sortie du chip codeur était possible, mais j'ai préféré 'sacrifier' une des prises pour l'utiliser en TBT, et obtenir une sortie contact sec normalement ouvert ou normalement fermée ou sur impulsion. De toutes façon elle n'est pas si sacrifiée que ça puisque maintenant, elle est utilisée, en 12V, a commander la machine a fumée ;p
A propos, le chip en question (HX2262) a une datasheet pourrie rédigée en chinois, et les notes d'applications y sont bourrés d'erreurs. Il y avait surement des équivalents US ou europeens avec le même codage, mais dans le doute... N'empêche que ces prises sont dotés d'une alimentation a base de condensateur comme impédance chûtrice de tension, ce qui a pour effet de ne pas (trop) consommer de puissance active. J'ai vu des prises télécommandées qui n'avaient même pas ce condensateur, donc c'est pas si mal que ça et c'est ça l'important.
Après l'avoir alimenté a travers un transformateur d'isolation pour faire des mesures, le PCB a été découpé pour rentrer dans un boitier, des composants déplacés, d'autres enlevés (relais 24 volts, gros condensateur X2, plein de diodes) et certains rajoutés (convertisseur DC-DC, régulateurs, transistors, relais 5V). Un petit bout de schéma avait été relevé surtout pour voir comment ils filtrent les pulses du bruit ambiant, mais ça porte aussi certaines de mes modifs, et je garantis pas que ça soit utile a quoi que ce soit.
Le circuit imprimé d'une prise télécommandée transformé en récepteur 433MHz
La fenêtre dans le boitier en plastique est utilisée pour avoir accès aux dip-switches.
Une fois ce truc relié a l'entrée de la carte son, on peut essayer de capturer des trames. Dans l'exemple suivant, on allume le canal A avec une télécommande dont les dip-dwitches du code de zone sont configurés en ON-OFF-ON-OFF-OFF.
Une trame émise, reçue, et enfin visualisée par le merveilleux petit programme d'oscillo sur carte son WinOscillo
(Le signal montré est un peu tordu parce que les pulses induisent une certaine tension continue qu'un transformateur d'isolation galvanique entre mes différents équipements audio ne laisse pas trop passer)
J'ai aussi réutilisé un bout de code C que j'avais écrit il y a longtemps - pour récupérer les trames d'un tv-b-gone - qui analyse un ficher wave, repére les fronts et extrait leur timmings... Premier essai : reproduire le signal avec un pic... ça marche ! Il n'a pas été trop difficile de comprendre comment les informations sont codées, et d'écrire une routine qui va bien ! Le code transmit est trinaire : soit 1, soit 0, soit ce que j'ai appelé F (quand la pin correspondante du chip est laissée flottante), et donc chaque 'trit' demande deux impulsions pour être transmit. Du coup comme j'utilise des chaines pour stocker les codes, ça utilise 8 bits là où il n'en faut que 1 et demi, mais c'est pas grave.
void generatecode(unsigned int *out, const char *str_data, unsigned int int_block){ // 0 : |-|___|-|___ // 1 : |---|_|---|_ // F : |-|___|---|_ // |-|___________ (fin de trame) // une unité de temps (- ou _) = 462,5/2µs unsigned int i = 0, o = 0; while(str_data[i]){ switch (str_data[i]){ case '0': out[o++] = 1*int_block; out[o++] = 3*int_block; out[o++] = 1*int_block; out[o++] = 3*int_block; break; case '1': out[o++] = 3*int_block; out[o++] = 1*int_block; out[o++] = 3*int_block; out[o++] = 1*int_block; break; case 'f': case 'F': out[o++] = 1*int_block; out[o++] = 3*int_block; out[o++] = 3*int_block; out[o++] = 1*int_block; } i++; } out[o++] = 1*int_block; out[o++] = 11*int_block; out[o] = 0; } | int assemblehighlevelcode(char *data, char *zone, char device, bool power, char* devicecode=NULL){ // $ remote --device A --on // 0F0FF 0FFFF 0F [len=12] // \___/ \___/ \/ // addr dev off/on strcpy(data, zone); //zone if (devicecode){ strcat(data, devicecode); } else if (device >= 1 && device <= 5) { for (int i = 1; i<=5; i++){ strcat(data, (i==device)?"0":"F"); } } else { return 1; } // nah! if (power) { strcat(data, "0F"); } // on else { strcat(data, "F0"); } // off // On remarque que en fait sur les prises, seul le // dernier de ces deux caracteres a l'air d'avoir // de l'importance ! return 0; } |
Un emetteur 433MHz, un max232 et un buzzer montés sur une platine de developpement pic, pour écrire le firmware et s'assurer que tout fonctionne !
La prochaine étape a été de fabriquer un protocole (fiable) pour le port série, d'écrire le logiciel pour piloter l'émetteur, et de comprendre pourquoi ça marche sous windows et pas sous linux... Une heure pour comprendre que mon convertisseur USB-série était pourri et mal géré sous nux. Et après en avoir changé, au moins une autre - en fait surtout attendre d'avoir accès a un scope numérique pro et voir facilement ce qu'il se passe sur les fils - pour comprendre que par défaut, mon linux traitait ce que j'envoyais comme du texte et pas comme du binaire et sabotait mes données en rajoutant des retours chariot devant ce qu'il pensait être des sauts de ligne. Problème rapidement réglé, mais il fallait le savoir.
La trace M1 était la version Linux, M2 la version Windows fonctionnelle. Rhhhaa sale bug a la con !
En parallèle, la construction du machin définitif s'est faite en récupérant le boitier d'un adaptateur MAU vers Ethernet et doté d'une prise BNC 50 ohms parfaite pour faire sortir le signal RF ! Le connecteur DA-15 a été remplacé par un connecteur DE-9 femelle pour un port série classique (ouais, l'USB aurait été un choix pratique, mais j'ai préféré un port série si un jour je voudrais connecter ce truc sur autre chose qu'un PC).
Le circuit imprimé définitif avec les composants installés. Tout rentre dans la boite de la photo suivante...
Le boitier est tellement peu épais que j'ai du monter un connecteur un peu trop grand sur une carte rabaissée, mais tout est rentré. Bien sûr, faut bien copier les dimensions et le placement du trou de fixation, des leds, de la prise, faire une découpe pour le connecteur 6P6C et le bornier d'alimentation... et ça rend bien, je trouve ! Et dans le laps de temps où ce truc a été mis en fonctionnement et l'écriture de cette page (c'est a dire plus d'un an, au moins !), ça n'a jamais encore disfonctionné.
Le boitier une fois refermé, une antenne connectée sur la prise BNC. Les leds ont été détournées :
PWR flashe une fois par seconde en idle,
RX, TX et COL indiquent l'état du port série,
SQE est éclairé lorsque la porteuse est émise.
Je me dois de rappeler qu'il faut éviter absolument d'émettre en continu sur cette bande, parce que c'est mal, qu'elle est déjà suffisamment encombrée, que ça fait chier tout les voisins, et que la norme se conforme a la décision 2008/432/CE qui interdit une utilisation de plus de 6 minutes par tranche d'une heure si on dépasse 1mW de PAR, ce qui est le cas ici puisque c'est un module de 10mW et une antenne dipole toute simple !