« Code Gray » : différence entre les versions

De knowledge
Aller à la navigation Aller à la recherche
mAucun résumé des modifications
(5 versions intermédiaires par le même utilisateur non affichées)
Ligne 1 : Ligne 1 :
=== La théorie ===
Le code Gray ou code binaire réfléchi est une façon de coder les nombres entiers en binaire en faisant en sorte que, d'un nombre consécutif à un autre il n'y ai jamais qu'un seul bit modifié.
Le code Gray ou code binaire réfléchi est une façon de coder les nombres entiers en binaire en faisant en sorte que, d'un nombre consécutif à un autre il n'y ai jamais qu'un seul bit modifié.
{| class="wikitable"
{| class="wikitable"
Ligne 87 : Ligne 88 :
|<code>1000</code>
|<code>1000</code>
|}
|}
Dernière subtilité quand on arrive "au bout" d'un mot binaire (ici 15) pour repasser à zéro on ne romps pas le truc, un passe de 15=<code>1000</code> à 0=<code>0000</code> donc encore un changement d'un seul bit!
Quel est l'intérêt d'un tel code me direz vous ?
Quel est l'intérêt d'un tel code me direz vous ?


Ligne 129 : Ligne 132 :
Et ca marche!
Et ca marche!


On peut également penser à une roue codeuse en code GRAY:
On remarque également que la fréquence du signal du bit "D" est divisé par deux en code Gray. On a donc besoin d'un support physique de moins bonne qualité (ou on peut augmenter le débit de 100%) en code binaire réfléchi qu'en binaire simple.
 
=== Mise en oeuvre ===
On peut réaliser une roue codeuse en code GRAY:


[[Fichier:Encoder Disc (3-Bit).svg.png|sans_cadre]]
[[Fichier:Encoder Disc (3-Bit).svg.png|sans_cadre]]
Ligne 140 : Ligne 146 :


J'ai compté 10 bits donc mieux que 0,35° de précision.
J'ai compté 10 bits donc mieux que 0,35° de précision.
Merci à http://m.joffroy.free.fr/in/Cours%20BTS%20MAI%201er%20et%202eme%20ann%C3%A9e/COURS%2009%20Les%20capteurs/Codeur%20Absolu.htm
=== Implémentation ===
On voit que le code Gray n'a que des avantages. En revanche il semble un peut complexe à coder / décoder. En fait non et démonstration ci-dessous.
==== Codage/décodage hardware ====
L'opérateur booléen utilisé est le "ou exclusif" noté ⨁.
===== Codage (binaire vers Gray) =====
On considère le bit de poids n. G<sub>n</sub> est la valeur du bit en code Gray et B<sub>n</sub> la valeur en code binaire.
G<sub>n</sub>=B<sub>n</sub> ⨁ B<sub>(n+1)</sub>.
Si on veut coder 8 bits on utilise le schéma :
[[Fichier:Codage gray.png|sans_cadre]]
===== Décodage (Gray vers binaire) =====
La formule est :
B<sub>n</sub>=G<sub>n</sub> ⨁ B<sub>(n+1)</sub>
Le schéma donne :
[[Fichier:Conversion gray vers binaire.png|sans_cadre]]
==== Exemple de code "C" ====
On va utilisera du code en "C".<syntaxhighlight lang="c">
typedef unsigned int uint;
// Cette fonction reprends le schéma ci-dessus
uint BinaryToGray(uint num)
{
    return num ^ (num >> 1); // L'operateur >> est un décalage binaire vers la droite. ^ est un ou exclusif.
}
// Toujours selon le schéma ci-dessus.
uint GrayToBinary(uint num)
{
    uint mask = num;
    while (mask) {         
        mask >>= 1;
        num  ^= mask;
    }
    return num;
}
// plus performant mais pour 32 bits. On peut l'adapter...
uint GrayToBinary32(uint num)
{
    num ^= num >> 16;
    num ^= num >>  8;
    num ^= num >>  4;
    num ^= num >>  2;
    num ^= num >>  1;
    return num;
}
</syntaxhighlight>

Version du 22 mars 2025 à 08:13

La théorie

Le code Gray ou code binaire réfléchi est une façon de coder les nombres entiers en binaire en faisant en sorte que, d'un nombre consécutif à un autre il n'y ai jamais qu'un seul bit modifié.

Exemple avec un mot de 4 bits
Nombre Hexa Binaire Code Gray
0 0 0000 0000
1 1 0001 0001
2 2 0010 0011
3 3 0011 0010
4 4 0100 0110
5 5 0101 0111
6 6 0110 0101
7 7 0111 0100
8 8 1000 1100
9 9 1001 1101
10 A 1010 1111
11 B 1011 1110
12 C 1100 1010
13 D 1101 1011
14 E 1110 1001
15 F 1111 1000

Dernière subtilité quand on arrive "au bout" d'un mot binaire (ici 15) pour repasser à zéro on ne romps pas le truc, un passe de 15=1000 à 0=0000 donc encore un changement d'un seul bit!

Quel est l'intérêt d'un tel code me direz vous ?

Cela sert a faire des compteurs numériques de façon mécaniques par exemple. Imaginons que l'on ai un signal binaire qui s'excrément au fur et a mesure d'un process quelconque.

Fichier:Signal Binaire 4 bits.png

Si les 4 lignes (A,B,D et D) sont parfaitement synchrones et qu'on lise le signe parfaitement au milieu de chaque état cela nous donne:

Fichier:Signal Binaire 4 bits a lecture synchrone.png

Jusque là tout va bien. Imaginons que les lignes A,B,C et B ne soient pas bien en phase.

Fichier:Signal asynchones.png

On voit bien que le 7 qui doit être 0100 est 11xx avec x où sait pas bien si c'est un 0 ou un 1.

Comment pourrait on faire un système de décompte binaire qui sont insensible a ces problèmes? Avec le code binaire réfléchi ou code Gray!

Si on change le signal binaire par un signal en code gray:

Fichier:Gray code.png

On lit la valeur au début:

Fichier:0 en binaire reflechi.png

Ok on commence à zéro. La "ruse" est qu'il suffit d'attendre que l'un des bits changes de valeur, sachant que jamais deux ne peuvent changer en même temps.

Fichier:Gray à 1.png

Premier changement c'est la ligne D et on lit 0001 qui en code gray donne 1 . Après 0 on a bien un 1. Jusqu'ici tout va bien!

On attends le prochain changement :

Fichier:Gray 2.png

La ligne C a changé et on a donc 0011 qui code un 2 en gray. Apres 1 on a bien 2.... on continue:

Fichier:Gray.png

Et ca marche!

On remarque également que la fréquence du signal du bit "D" est divisé par deux en code Gray. On a donc besoin d'un support physique de moins bonne qualité (ou on peut augmenter le débit de 100%) en code binaire réfléchi qu'en binaire simple.

Mise en oeuvre

On peut réaliser une roue codeuse en code GRAY:

Encoder Disc (3-Bit).svg.png

Si on la lit avec 3 photodiodes on a un encodeur d'angle précis à 45°. Et c'est la même méthode, on attends qu'un bit change pour lire la nouvelle valeur.

J'ai même trouvé:

Gray code precis.gif

J'ai compté 10 bits donc mieux que 0,35° de précision.

Merci à http://m.joffroy.free.fr/in/Cours%20BTS%20MAI%201er%20et%202eme%20ann%C3%A9e/COURS%2009%20Les%20capteurs/Codeur%20Absolu.htm

Implémentation

On voit que le code Gray n'a que des avantages. En revanche il semble un peut complexe à coder / décoder. En fait non et démonstration ci-dessous.

Codage/décodage hardware

L'opérateur booléen utilisé est le "ou exclusif" noté ⨁.

Codage (binaire vers Gray)

On considère le bit de poids n. Gn est la valeur du bit en code Gray et Bn la valeur en code binaire.

Gn=Bn ⨁ B(n+1).

Si on veut coder 8 bits on utilise le schéma :

Codage gray.png

Décodage (Gray vers binaire)

La formule est :

Bn=Gn ⨁ B(n+1)

Le schéma donne :

Conversion gray vers binaire.png

Exemple de code "C"

On va utilisera du code en "C".

typedef unsigned int uint;

// Cette fonction reprends le schéma ci-dessus
uint BinaryToGray(uint num)
{
    return num ^ (num >> 1); // L'operateur >> est un décalage binaire vers la droite. ^ est un ou exclusif.
}

// Toujours selon le schéma ci-dessus.
uint GrayToBinary(uint num)
{
    uint mask = num;
    while (mask) {           
        mask >>= 1;
        num   ^= mask;
    }
    return num;
}

// plus performant mais pour 32 bits. On peut l'adapter...

uint GrayToBinary32(uint num)
{
    num ^= num >> 16;
    num ^= num >>  8;
    num ^= num >>  4;
    num ^= num >>  2;
    num ^= num >>  1;
    return num;
}