Ingénierie inverse

Fil des billets - Fil des commentaires

Jeudi, mai 19 2011

Hacking d'un écran à Led de DealExtreme

Led matrix

Je reviens à la charge avec un joujou récupéré sur le site http://www.dealextreme.com/ avec, cette fois ci, non pas un régulateur à découpage pas chèr mais un afficheur à led pas chér (~ 8€) vendu sous l'appelation « Programmable Scrolling LED Name/Message/Advertising Tag Card Badge », intéressant, la description de l'article nous apprend également qu'il possède une connection USB, chouette, je le vois parfaitement bien sur la face avant de mon serveur pour indiquer des infos comme la charge du système, l'espace disque restant, etc...

Omar m'a hacker

Malheureusement, déception : la connectique USB est propriétaire et bien évidemment, le cable n'est pas fourni, l'envie m'est alors rapidement venue d'ouvrir la bête pour y souder un connecteur standard et là, ce fût la seconde mauvaise surprise, la prise n'est reliée à ... rien. Alors, bien évidemment, on peut programmer cet écran à l'aide des boutons situés sur son dos mais ce n'est franchement pas pratique pour en faire quelque chose d'automatisé...

L'écran est piloté par un unique micro-controleur d'Atmel, un AtMega88, de la même famille que les Arduino, il est donc assez aisé de développer un micro-logiciel libre.

J'ai donc fait une petite séance de reverse engineering, ingénierie inverse en bon français afin de comprendre comment fonctionnait cet écran et j'ai ensuite développer un micro-logiciel de remplacement permettant de piloter l'écran facilement directement avec une interface série.

Dans la vidéo ci-dessous, l'écran est simplement relié à l'ordi par le biais d'un convertisseur série / USB 3V, on y voit un des 2 modes de pilotage de l'écran en action qui permet à l'aide de menu de venir le paramétrer simplement, un autre mode est aussi disponible et est parfaitement adapté à la commande automatisée par le biais de script bash ou autre...

Vous trouverez TOUT en détail sur le fonctionnement de cet écran sur le lien suivant LedMatrix hacking sur le wiki, voici le sommaire de cette page :

LedMatrix hacking
    Introduction
    Ouverture du boitier
    Comment ça marche ?
        Vue globale
        Le coeur
        Interface de programmation
        L'interface USB
        La gestion des boutons
        La matrice de LED
        Accès à la mémoire EEPROM externe
    Ajoutons une connection série
        Vous voulez piloter le montage directement depuis un module USB          
        Si vous possédez déjà une connection série RS232
    Le micro-logiciel libre
        Mode interactif
        Mode non interactif

Cet article est également paru sur :

Logo Made in fr

Mercredi, avril 6 2011

Etiquette électronique, partie 1

Aujourd’hui nous allons nous pencher sur un petit bidule électronique qui ne demande qu’à se faire ouvrir en deux pour révéler ses entrailles. Voici le client:C’est un « pricer », une étiquette électronique comme on trouve partout désormais. Pour vous en procurer un: démerdez-vous, je ne vais pas vous faire un dessin non plus! N’allez pas en piquer dans un magasin non plus, mais si on réfléchit c’est assez facile d’en trouver un…

Première partie: comment ça fonctionne. Tout ce qui suit est basé sur des documents glanés ici et là sur le site du fabricant (tapez « pricer » sur google), mais en gros ces étiquettes électroniques sont contrôlées par IR, à distance donc. D’après ce que j’ai compris de la démo du commercial neurasthénique de chez Pricer, une interface Web couplée à une grappe d’émetteurs IR permet de mettre à jour les étiquettes à distance, instantanément et de façon groupée à partir d’un unique poste de contrôle. C’est réellement intéressant comme système!

Au niveau de l’aspect extérieur, nous avons en façade un écran LCD, un capteur IR sur la droite. Derrière on aperçoit 3 piles 2023 3V…ca peut toujours servir!

Maintenant, les entrailles. Ca y est, vous avez votre Pricer? Alors le TP d’aujourd’hui va consister à ouvrir le boîtier pour vois comment hacker le tout. Perso j’y suis allé au Dremel, car je n’ai pas l’impression qu’il soit possible d’ouvrir le boîtier sans y aller comme une brute. Allez-y doucement, c’est pas fait pour être ouvert alors ca risque d’être un peu tendu!

Une fois ouvert, voici ce qui reste:


Rien ne vous choque à cet instant?

non?

Pourtant l’écran est toujours allumé, alors que les piles ont été enlevées! Intéressant, non? Ca s’explique simplement par le fait que cet écran est en fait un e-paper, ses pixels sont en fait de petites billes blanches d’un côté, noires de l’autre, que l’on fait pivoter électriquement. De ce fait, les pixels gardent leur étant même lorsqu’on coupe le jus. Excellent choix, avec 3 piles bouton on peut du coup obtenir une longévité hors du commun, car cet écran ne consomme de l’énergie que lorsque l’on change l’affichage!

Passons à la suite, examinons le circuit:

Ahah, voilà qui est intéressant! Trois puces, dont une noyée dans la résine. Rien à faire pour celle-là, concentrons-nous sur les deux autres. Si vous dégainez votre loupe, vous verrez que la première est un ATMEL ATMEGA16L, la seconde un ATMEL952 25128AN.

Deux recherches sur google et deux datasheets plus tard (ici et ici), voici ce qu’on peut apprendre:
- la première (le 16L) est un micro-contrôleur, de la même famille que ceux présents sur les Arduinos
- la seconde (la 25128) est une EEPROM de 128k contrôlable par SPI.

Que du bonheur tout ca! Et si nous allions voir ce qu’elle contient cette EEPROM? Jetons un coup d’oeil à la datasheet:

Notre puce est un 8-lead SOIC (8-lead pour 8 pattes, SOIC pour Small Outline Integrated Circuit). Maintenant le détail des pattes:
- /CS: Chip Select. Si cette entrée est à 0, alors la puce est sélectionnée. Ceci permet d’utiliser plusieurs puces de mémoire. Pour de plus amples explications: Wikipedia, page sur le SPI.
- SO: Serial Out, là où vont sortir les données
- /WP: Write Protect, pour mettre la puce en lecture-seule
- GND: la masse
- SI: Serial Input, là où l’on va injecter les données
- SCK: l’horloge du SPI. Là encore -> Wikipedia.
- /HOLD: pour suspendre les communications.
- VCC: +5V.

Maintenant, dégainez votre meilleur ami, l’Arduino.

Après quelques recherches, j’ai trouvé cette page où est expliqué en détail comment communiquer avec une EEPROM SPI et, suprême coup de bol, tout est expliqué en détail, même le code à envoyer à l’arduino. On gagne du temps! Pour plus de détails, rendez-vous à la page 11 de la datasheet où se trouvent les datagrammes permettant de lire/écrire la mémoire. En gros on bascule /CS, on envoie l’instruction (READ ou WRITE), l’adresse, puis on lis/écrit les données. Pratique, la puce continue à envoyer des données (en mode LECTURE) ou à attendre de nouvelles données tant qu’on n’a pas rebasculé /CS. Même pas besoin d’incrémenter l’adresse!

Enfin bon, c’est beau tout ca, mais va falloir y accéder à la puce, non?!

C’est là qu’on dégaine notre deuxième meilleur pote, le fer à souder. Je recommande vivement la troisième main, sans quoi vous allez vous arracher les cheveux. Utilisez aussi du fil mono-brin, c’est beaucoup plus facile à mettre en place.

On connecte le tout à l’arduino:

Et hop, il n’y à plus qu’à prier!

J’ai un peu modifié le code donné sur le site Arduino pour:
- ne pas écrire par dessus les données qu’on veut lire, bordel de merde!
- mettre les données lues en forme

Ca donne ca:

#define DATAOUT 11//MOSI
#define DATAIN  12//MISO
#define SPICLOCK  13//sck
#define SLAVESELECT 10//ss

//opcodes
#define WREN  6
#define WRDI  4
#define RDSR  5
#define WRSR  1
#define READ  3
#define WRITE 2

byte eeprom_output_data;
byte eeprom_input_data=0;
byte clr;
int address=0;

char spi_transfer(volatile char data) {
 SPDR = data;                    // Start the transmission
 while (!(SPSR & (1< return SPDR;   // return the received byte
}

void setup() {
 Serial.begin(9600);

 pinMode(DATAOUT, OUTPUT);
 pinMode(DATAIN, INPUT);
 pinMode(SPICLOCK,OUTPUT);
 pinMode(SLAVESELECT,OUTPUT);
 digitalWrite(SLAVESELECT,HIGH); //disable device
}

byte read_eeprom(int EEPROM_address) {
 //READ EEPROM
 int data;
 digitalWrite(SLAVESELECT,LOW);
 spi_transfer(READ); //transmit read opcode
 spi_transfer((char)(EEPROM_address>>8));   //send MSByte address first
 spi_transfer((char)(EEPROM_address));      //send LSByte address
 data = spi_transfer(0xFF); //get data byte
 digitalWrite(SLAVESELECT,HIGH); //release chip, signal end transfer
 return data;
}

void loop() {
 eeprom_output_data = read_eeprom(address);
 //Serial.print("At 0x");
 //Serial.print(address, HEX);
 //Serial.print(" = ");
 Serial.print("0x");
 Serial.print(eeprom_output_data,HEX);
 address++;
 //when finished dump, enter infinite loop
 if (address == 0x4000) {
 Serial.println("};");
 while(1);
 }
 Serial.print(", ");
 if (!(address%20)) Serial.println("");
 //delay(50); //pause for readability
}

Si tout fonctionne bien:
Petite précision: la valeur 0×4000 correspond à la taille de notre EEPROM, soit 128ko.

Voilà, c’est terminé pour cette première partie. Dans la suivante si tout se passe bien (comprendre: « si j’y arrive! »), nous verrons comment est structuré le contenu de cette petite ROM, comment le modifier etc…

Mardi, décembre 15 2009

Capteur température/humidité 433MHz

Histoire de continuer dans la domotique j'ai acheté des capteurs de température/humidité sans fils. Normalement ces capteur sont fait pour fonctionner avec une station météo base qui affiche les températures des différents capteurs. La station de base coute assez chère mais les capteur coute dans les 10 euros pièce ce qui est assez raisonnable. L'objectif est donc de comprendre le protocole qu'ils utilisent pour pouvoir recevoir leur signaux et par exemple commander les radiateurs.

Après avoir relativement facilement compris le protocole utilisé pas les prises télécommandés je ne m'attendait pas a passer plus de 8 heures a me gratter la tête pour décoder 2 valeurs (température et humidité). Pas facile du tout !

Voici la tête d'une trame (10ms/div):

Le problème c'est que j'ai cru que c'était du Manchester ou du Manchester différentiel mais j'ai fini par essayer le code Biphase qui s'est avéré plus concluant.

Ensuite le problème a été de retrouver les données dans les trames. La plupart des capteur sans fil (comme les Oregon) ont l'air d'utiliser un codage BCD pour coder les valeurs mais ce n'est pas le cas de ces capteurs.

Pour l'humidité relative la valeur est simplement codée en binaire sur 8bits (pas trop compliqué).

Pour la température j'ai eu plus de mal car la valeur est codée sur 12 bits Soit x l'entier correspondant aux 8 premier bits et y l'entier correspondant au 4 derniers. La valeur de la température est T = x - 50 + y / 16 J'ai bien galéré pour en arriver la !!! mais ça se vérifie bien aussi bien pour les températures positives que négatives.

Au final voila ou j'en suis:

  • 0..4 : Les 4 premiers bits on l'air d'être toujours 1100, probablement un préambule identifiant le type de capteur.
  • 4..8 : Code maison (valeur réglable entre 1 et 15 sur chaque capteur, le 0 a l'air inutilisé)
  • 8..10 : Code canal (valeur entre 1 et 4 réglable sur chaque capteur)
  • 10..12 : ???
  • 12..20 : Humidité. Entier sur 8 bits (poids fort en premier)
  • 20..32 : Température (voir plus haut pour le codage)
  • 32..36 : ???

Dans les inconnu il y a peut être qqch sur les unités de mesure (°C ou °F) et/ou sur le niveau de la batteries...

Au total donc 36 bits par trame à 2 ms par bit donc 72 ms par trame. A chaque fois que le capteur transmet les donnée 3 trames sont envoyées avec une pause de 70ms environ.

Voila pour aujourd'hui !

Capteur température/humidité 433MHz

Histoire de continuer dans la domotique j'ai acheté des capteurs de température/humidité sans fils. Normalement ces capteur sont fait pour fonctionner avec une station météo base qui affiche les températures des différents capteurs. La station de base coute assez chère mais les capteur coute dans les 10 euros pièce ce qui est assez raisonnable. L'objectif est donc de comprendre le protocole qu'ils utilisent pour pouvoir recevoir leur signaux et par exemple commander les radiateurs.

Après avoir relativement facilement compris le protocole utilisé pas les prises télécommandés je ne m'attendait pas a passer plus de 8 heures a me gratter la tête pour décoder 2 valeurs (température et humidité). Pas facile du tout !

Voici la tête d'une trame (10ms/div):

Le problème c'est que j'ai cru que c'était du Manchester ou du Manchester différentiel mais j'ai fini par essayer le code Biphase qui s'est avéré plus concluant.

Ensuite le problème a été de retrouver les données dans les trames. La plupart des capteur sans fil (comme les Oregon) ont l'air d'utiliser un codage BCD pour coder les valeurs mais ce n'est pas le cas de ces capteurs.

Pour l'humidité relative la valeur est simplement codée en binaire sur 8bits (pas trop compliqué).

Pour la température j'ai eu plus de mal car la valeur est codée sur 12 bits Soit x l'entier correspondant aux 8 premier bits et y l'entier correspondant au 4 derniers. La valeur de la température est T = x - 50 + y / 16 J'ai bien galéré pour en arriver la !!! mais ça se vérifie bien aussi bien pour les températures positives que négatives.

Au final voila ou j'en suis:

  • 0..4 : Les 4 premiers bits on l'air d'être toujours 1100, probablement un préambule identifiant le type de capteur.
  • 4..8 : Code maison (valeur réglable entre 1 et 15 sur chaque capteur, le 0 a l'air inutilisé)
  • 8..10 : Code canal (valeur entre 1 et 4 réglable sur chaque capteur)
  • 10..12 : ???
  • 12..20 : Humidité. Entier sur 8 bits (poids fort en premier)
  • 20..32 : Température (voir plus haut pour le codage)
  • 32..36 : ???

Dans les inconnu il y a peut être qqch sur les unités de mesure (°C ou °F) et/ou sur le niveau de la batteries...

Au total donc 36 bits par trame à 2 ms par bit donc 72 ms par trame. A chaque fois que le capteur transmet les donnée 3 trames sont envoyées avec une pause de 70ms environ.

Voila pour aujourd'hui !

Dimanche, décembre 13 2009

Un peu de domotique

Comme il n'y a pas d'interrupteur dans notre appartement j'ai acheté des interrupteur sans fils et des prises (et dimmeurs) télécommandé:

Ça marche bien mais quand on en ai la on a envie de faire un peu plus, comme par exemple de commander/monitorer les equipements a partir d'un PC. La technologie utiliser est par radio a 433MHz (comme plein d'autre équipements). Ca tombe bien j'avait justement un recepteur 433MHz dans un tiroir:

Il ne reste plus qu'a étudier le signal transmis pas les interrupteurs et la télécommande, excellente occasion de de tester mon nouvel oscilloscope :-).

Les équipements que j'utilise (marque Waveman) propose 16 "code maison" et 16 canaux differents ce qui fait un total de 256 (16x16) canaux différents. Lorsque l'on active un interrupteur il émet un message qui contient le code maison, le canal et la commande (on ou off). Les récepteurs réglé sur ce canal recoivent le message et réagissent en conséquence.

Voici un message complet capturé a l'oscilloscope:

Il semble que chaque message est composé d'un "start" suivi de 12 bits, voici le début d'un message qui montre comment les 0 et 1 sont codés:

Et voici une capture avec une meilleur résolution pour détermine les durée:

Après avoir essayé et capturer différent interrupteurs réglés sur différents canaux il semble de le protocole soit le suivant:

  • Chaque trame commence par un "start": haut (0.42ms), bas (1.30ms)
  • 4 bits correspondant au "code maison" (0x0 à 0xF pour code de A à P) en transmettant les bits de poids faible d'abord.
  • 4 bits correspondant au "code canal" (0x0 à 0xF pour canal de 1 à 16) en transmettant les bits de poids faible d'abord.
  • 4 bits correspondant a la commande. 0x0 pour OFF et 0xE pour ON toujours avec les bits de poids faible d'abord.

Chaque bit est codé par deux impulsions:

  • 0 : haut (0.42ms), bas (1.30ms), haut (0.42ms), bas (1.30ms)
  • 1 : haut (1.30ms), bas (0.42ms), haut (0.42ms), bas (1.30ms)

Par conséquence la transmission de chaque bit prend 3.44 ms (ce qui fait un débit de 290 bps, pas vraiment rapide:-). Pour une trame complète ("start" + 12bits) on retrouve bien 43ms.

Voila qui semble pas mal, reste maintenant a sortir un microcontroleur et tenter de développer un émetteur/récepteur compatible. Très satisfait de l'oscilloscope en tout cas !