Code GRAY

Python est le langage de prédilection du Raspberry Pi

Modérateurs : Francois, Manfraid

Artemus24
Raspinaute
Messages : 1077
Enregistré le : ven. 15 sept. 2017 19:15

Re: Code GRAY

Message par Artemus24 » ven. 29 juil. 2022 08:05

Salut MSG.

Pour moi, L'exercice du code de Gray, consiste juste à trouver la solution optimale de la conversion et de la fonction inverse.
Je l'ai donné en 'c' car je maitrise mieux de langage que j'aime au lieu du langage python.
Transposer le code 'c' en python ne doit poser aucun problème à celui qui maitrise ce langage.
Je n'ai aucun usage de ces deux fonctions dans les programmes que je fais avec mes Raspberry.
C'était juste amusant à le faire, rien de plus.

Il est inutile de passer par des tableaux pour créer une relation entre le binaire et le code de Gray.
Si tu as besoin de gérer le code de Gray au niveau du bit, on peut toujours créer une fonction qui donnera en retour 1 ou 0 selon le rang que tu recherches. Comme par exemple positionner tes disques.

Cordialement.
Artemus24.
@+
Modifié en dernier par Artemus24 le ven. 29 juil. 2022 12:41, modifié 1 fois.
RPI4B/8GB + Argon FanHAt
Rpi3A+, Rpi3B+
RPi 2B + Joy-It I2C Serial 20x4 2004 LCD Module
RPi 2B + PIM273 Unicorn HAT HD 16x16 Leds RGB
RPi0v1.3, RPi0W + LibreElec/Kodi, Rpi0WH + Tuner TV HAT
NodeMCU ESP32

MSG
Raspinaute
Messages : 119
Enregistré le : ven. 26 déc. 2014 18:31

Re: Code GRAY

Message par MSG » ven. 29 juil. 2022 12:10

Bonjour ,

C'est facile , une fois qu'on a compris et qu'on sait faire .
Pour ma part , je suis parti de très loin (formation électricien) , et tous les profs ne se valent pas .
Le code Gray , je l'ai vu dans la construction du tableau de Karnaugh , un vrai supplice sur papier et stylo .

Après ça été débrouille pour coder les explications d'encodage Gray de l'époque , à savoir une comparaison sérielle bit à bit XOR , alors que la comparaison XOR parallèle de deux mots est plus rapide à coder . Le décodage , ça été laborieux car je n'avais aucune base sur quoi m'appuyer , j'ai donc chercher une logique sérielle là aussi .

Chacun choisi , selon ses savoirs , le langage de codage le mieux adapté .
J'ai débuté en BASIC , suivit d'un peu de TurboC , et logiquement j'arrive sur le Python .
D'ailleurs , on est dans la rubrique python . ;)

On peut toujours optimiser un code , mais il faut d'abord avoir une base de programme fonctionnelle et maitriser les conversions .

Une application du code Gray , c'est le positionnement linéaire ou circulaire d'un objet . Perso j'ai bossé pour faire un girouette à 16 points cardinaux , soit 4 bits à décoder pour donner un ordre logique aux points cardinaux , soit faire un tableau de conversion / correspondance du code Gray , un vrai galère si on ne sait pas décoder le Gray .
Pour info , la construction du code Gray , du point de vue humain , se fait souvent par représentation graphique et non logique .

Code : Tout sélectionner

Bit 0 = 0110011001100110  1x"0" + 2x"1" + 2x"0" + etc ... et fini par 2x"1" et 1x"0"
Bit 1 = 0011110000111100  2x"0" + 4x"1" + 4x"0" etc ... et fini pas 4x"1" et 2x"0"
bit n = 2 puissance n fois "0" + 2 fois 2 puissance n fois "1" alterné d'autant de "0"
Bit 2 = 0000111111110000  l'avant dernier , les bits "1" aux centre
Bit 3 = 0000000011111111  le dernier bit , tous les bits "1" à droite 
Puis on tourne pour avoir le dessin en vertical :

Code : Tout sélectionner

Bit 3 2 1 0
    0 0 0 0
    0 0 0 1
    0 0 1 1
    0 0 1 0
    0 1 1 0
    0 1 1 1
    0 1 0 1
    0 1 0 0
    1 1 0 0
    1 1 0 1
    1 1 1 1
    1 1 1 0
    1 0 1 0
    1 0 1 1
    1 0 0 1
    1 0 0 0
    

Artemus24
Raspinaute
Messages : 1077
Enregistré le : ven. 15 sept. 2017 19:15

Re: Code GRAY

Message par Artemus24 » ven. 29 juil. 2022 12:45

Salut MSG.

Qu'essayes-tu de faire avec tes tableaux de Karnaugh ?
J'ai vu ça, il y a fort longtemps à l'école. C''est une méthode pour trouver une fonction logique à partir d'une table de vérité.

Cordialement.
Artemus24.
@+
RPI4B/8GB + Argon FanHAt
Rpi3A+, Rpi3B+
RPi 2B + Joy-It I2C Serial 20x4 2004 LCD Module
RPi 2B + PIM273 Unicorn HAT HD 16x16 Leds RGB
RPi0v1.3, RPi0W + LibreElec/Kodi, Rpi0WH + Tuner TV HAT
NodeMCU ESP32

MSG
Raspinaute
Messages : 119
Enregistré le : ven. 26 déc. 2014 18:31

Re: Code GRAY

Message par MSG » ven. 29 juil. 2022 12:49

Exactement , soit tu passes par un tableau de conversion , soit par une équation mathématique booléenne .
C'est le cas des afficheurs LED 7 segments . pour afficher des nombres ou autre (des lettres) , juste à partir d'une valeur décimale .
Il existe des composants spécifiques de conversion , mais on peut s'en passer , si on sait faire , juste avec un simple registre à décalage 8 bits .

Artemus24
Raspinaute
Messages : 1077
Enregistré le : ven. 15 sept. 2017 19:15

Re: Code GRAY

Message par Artemus24 » sam. 30 juil. 2022 08:15

Salut MSG.

Oui, mais ca ne me dit pas ce que tu essayes de faire avec tes tableaux karnaugh.
Est-ce que tu recherches une fonction logique qui pourrait convertir un nombre binaire vers ton affichage à sept segments ?

Cordialement.
Artemus24.
@+
RPI4B/8GB + Argon FanHAt
Rpi3A+, Rpi3B+
RPi 2B + Joy-It I2C Serial 20x4 2004 LCD Module
RPi 2B + PIM273 Unicorn HAT HD 16x16 Leds RGB
RPi0v1.3, RPi0W + LibreElec/Kodi, Rpi0WH + Tuner TV HAT
NodeMCU ESP32

MSG
Raspinaute
Messages : 119
Enregistré le : ven. 26 déc. 2014 18:31

Re: Code GRAY

Message par MSG » sam. 30 juil. 2022 10:17

L'afficheur 7 seg c'est un exemple .

La plupart des codes que j'ai vu à ce sujet , énumèrent une partie de la table de vérité ou passent par des tableaux / listes .
En passant par le tableau de Karnaugh , on n'a plus que des équations , mais c'est plus difficile à travailler / modifier .
Ça sert aussi dans d'autres domaines , électricité et automatisme .

Artemus24
Raspinaute
Messages : 1077
Enregistré le : ven. 15 sept. 2017 19:15

Re: Code GRAY

Message par Artemus24 » sam. 30 juil. 2022 14:38

Salut MSG.

Quand j'ai géré mon afficheur à quatre digits de sept segments, je suis passé par un tableau. C'est plus facile à gérer.
Je pense que si j'avais une fonction logique, elle serait trop compliqué à mettre en oeuvre.

Si c'est pour faire mumuse, je veux bien car il m'arrive aussi de tordre dans tous les sens des problèmes, juste pour le plaisir.
Je prends le cas où j'ai voulu trouver le cube magique de 3.
Ou encore améliorer le temps d'exécution sur le problème du voyageur de commerce.

Cordialement.
Artemus24.
@+
RPI4B/8GB + Argon FanHAt
Rpi3A+, Rpi3B+
RPi 2B + Joy-It I2C Serial 20x4 2004 LCD Module
RPi 2B + PIM273 Unicorn HAT HD 16x16 Leds RGB
RPi0v1.3, RPi0W + LibreElec/Kodi, Rpi0WH + Tuner TV HAT
NodeMCU ESP32

MSG
Raspinaute
Messages : 119
Enregistré le : ven. 26 déc. 2014 18:31

Re: Code GRAY

Message par MSG » sam. 30 juil. 2022 21:24

Salut ,

Je viens de coder mes segments , et comme une évidence (en utilisant le tableau de karnaugh) , je retombe sur mon choix inital , à savoir sélectionner la liste des cases ayant le plus petit nombre de "0" ou de "1" .

Je n'ai pas passé tous les segments , mais rien que le premier seghex_a n'a que 4 valeurs à "0" et c'est celle que j'ai choisi pour créer la table de vérité .

Code : Tout sélectionner

# decimal
segdec_a = []
segdec_b = []
segdec_c = []
segdec_d = []
segdec_e = []
segdec_f = []
segdec_g = []
for i in range(10):
   segdec_a.append(int(bool(i==1 or i==4)^1))                  # eteint
   segdec_b.append(int(bool(i==5 or i==6)^1))                  # eteint
   segdec_c.append(int(bool(i==2)^1))                          # eteint
   segdec_d.append(int(bool(i==1 or i==4 or i==7)^1))          # eteint
   segdec_e.append(int(bool(i==0 or i==2 or i==6 or i==8)))    # allumé
   segdec_f.append(int(bool(i==1 or i==2 or i==3 or i==7)^1))  # eteint
   segdec_g.append(int(bool(i==0 or i==1 or i==7)^1))          # eteint

Code : Tout sélectionner

# hexadécimal
seghex_a = [] + segdec_a
seghex_b = [] + segdec_b
seghex_c = [] + segdec_c
seghex_d = [] + segdec_d
seghex_e = [] + segdec_e
seghex_f = [] + segdec_f
seghex_g = [] + segdec_g
for i in range(10,16):
   seghex_a.append(int(bool(i==0xb or i==0xd)^1))              # eteint
   seghex_b.append(int(bool(i==0xa or i==0xd)))                # allumé
   seghex_c.append(int(bool(i==0xc or i==0xe or i==0xf)^1))    # eteint
   seghex_d.append(int(bool(i==0xa or i==0xf)^1))              # eteint
   seghex_e.append(int(bool(1)))                               # allumé
   seghex_f.append(int(bool(i==0xd)^1))                        # eteint
   seghex_g.append(int(bool(i==0xc)^1))                        # eteint
OU écrit autrement :

Code : Tout sélectionner

allume = 1
eteint = allume ^ 1

# decimal
segdec_a = []
segdec_b = []
segdec_c = []
segdec_d = []
segdec_e = []
segdec_f = []
segdec_g = []
for i in range(10):
   segdec_a.append( int( eteint == (i in [1,4] )))
   segdec_b.append( int( eteint == (i in [5,6] )))
   segdec_c.append( int( eteint == (i in [2] )))
   segdec_d.append( int( eteint == (i in [1,4,7] )))
   segdec_e.append( int( allume == (i in [0,2,6,8] )))
   segdec_f.append( int( eteint == (i in [1,2,3,7] )))
   segdec_g.append( int( eteint == (i in [0,1,7] )))

Code : Tout sélectionner

# hexadécimal
seghex_a = [] + segdec_a
seghex_b = [] + segdec_b
seghex_c = [] + segdec_c
seghex_d = [] + segdec_d
seghex_e = [] + segdec_e
seghex_f = [] + segdec_f
seghex_g = [] + segdec_g
for i in range(10,16):
   seghex_a.append( int( eteint == (i in [0xb,0xd] )))
   seghex_b.append( int( allume == (i in [0xa,0xd] )))
   seghex_c.append( int( eteint == (i in [0xc,0xe,0xf] )))
   seghex_d.append( int( eteint == (i in [0xa,0xf] )))
   seghex_e.append( int( allume ))
   seghex_f.append( int( eteint == (i in [0xd] )))
   seghex_g.append( int( eteint == (i in [0xc] )))
Le code d'affichage

Code : Tout sélectionner

aff=""
for i in range(16):
   aff += " %3s  " %(seghex_a[i] and "###" or "   ")

aff+="\n"
for j in range(3):
   for i in range(16):
      aff+= "%1s   %1s " %((seghex_f[i] and "#" or " "), (seghex_b[i] and '#' or " "))
   aff+="\n"

for i in range(16):
   aff+=" %3s  " %(seghex_g[i] and "###" or "   ")

aff+="\n"
for i in range(3):
   for i in range(16):
      aff+="%1s   %1s " %((seghex_e[i] and "#" or " "), (seghex_c[i] and '#' or " "))
   aff+="\n"

for i in range(16):
   aff+=" %3s  " %(seghex_d[i] and "###" or "   ")

aff+="\n"
print (aff)
J'obiens le résultat suivant :

Code : Tout sélectionner

>>> print (aff)
 ###         ###   ###         ###   ###   ###   ###   ###   ###         ###         ###   ###  
#   #     #     #     # #   # #     #         # #   # #   # #   # #     #         # #     #     
#   #     #     #     # #   # #     #         # #   # #   # #   # #     #         # #     #     
#   #     #     #     # #   # #     #         # #   # #   # #   # #     #         # #     #     
             ###   ###   ###   ###   ###         ###   ###   ###   ###         ###   ###   ###  
#   #     # #         #     #     # #   #     # #   #     # #   # #   # #     #   # #     #     
#   #     # #         #     #     # #   #     # #   #     # #   # #   # #     #   # #     #     
#   #     # #         #     #     # #   #     # #   #     # #   # #   # #     #   # #     #     
 ###         ###   ###         ###   ###         ###   ###         ###   ###   ###   ###        

>>>
Le résultat du Karnaugh en affichant que les "0" , on que 4 valeurs 1,4,11 et 13 .

Code : Tout sélectionner

>>> karnaugh(seghex_a, s=0)

Table : [1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1]

Total à 1 : 12
Total à 0 : 4

   . . .C.C.
 . . .A.A. .
 . . .0. .0.
 .B. . . . .
D.B. .0. . .
D. . . .0. .

  0   1   5   4 
  2   3   7   6 
 10  11  15  14 
  8   9  13  12 


>>>
Si on choisi les 1 , on va avoir une liste à rallonge .

Code : Tout sélectionner

>>> karnaugh(seghex_a, s=1)

Table : [1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1]

Total à 1 : 12
Total à 0 : 4

   . . .C.C.
 . . .A.A. .
 . .1. .1. .
 .B.1.1.1.1.
D.B.1. .1.1.
D. .1.1. .1.

  0   1   5   4 
  2   3   7   6 
 10  11  15  14 
  8   9  13  12 

>>>

Répondre

Retourner vers « Python »