Pour la réalisation d'un potentiomètre numérique pour un projet de table de mixage audio, j'ai besoin de connaître la position absolue du curseur numérique (encodeur).
Pour cela, j'ai besoin d'une grille rectiligne codée en code Gray qui est plus adaptée que le code binaire dans une application d'encodeur à valeur absolue qui lit la position du curseur à la différence d'un encodeur incrémental qui ne donne que des impulsions d'un mouvement (rotatif ou rectiligne). Je ne rentre pas plus ici dans la réalisation du potentiomètre qui est fait d'électronique avec des capteurs optiques (RX/TX).

Je détaille ici le programme qui permet l'impression d'une bande rectiligne codée en code Gray de 2 à 10 bits suivant les besoins de chacun. Le programme n'est pas très ergonomique mais, suivant les paramètres modifiables indiqués en début permettront de s'adapter au mode d'impression choisi.
exemple en 8 bits:

La base du décodage de décimale à binaire puis de binaire vers le code Gray est le suivant :
Code : Tout sélectionner
; ---------------------------------------------------
; 8 bits Decimal to Binary to Gray Code translation
; Philippe Mijon - mai 2023
; PureBasic 6.01
; ---------------------------------------------------
Debug "Décimale Code Binaire Code Gray"
For decimale = 0 To 255 ; 8 bits (0 à 7)
binaire$ = RSet(Bin(decimale), 8, "0")
B0 = Val(Mid(binaire$, 8, 1))
B1 = Val(Mid(binaire$, 7, 1))
B2 = Val(Mid(binaire$, 6, 1))
B3 = Val(Mid(binaire$, 5, 1))
B4 = Val(Mid(binaire$, 4, 1))
B5 = Val(Mid(binaire$, 3, 1))
B6 = Val(Mid(binaire$, 2, 1))
B7 = Val(Mid(binaire$, 1, 1))
; Formules XOR (!) pour la conversion Bin to Gray
G7 = B7
G6 = B7 ! B6
G5 = B6 ! B5
G4 = B5 ! B4
G3 = B4 ! B3
G2 = B3 ! B2
G1 = B2 ! B1
G0 = B1 ! B0
Gray$ = Str(G7) + Str(G6) + Str(G5) + Str(G4) + Str(G3) + Str(G2) + Str(G1) + Str(G0)
Debug " " + Str(decimale) + " " + binaire$ + " " + Gray$
Next
End
Nota : bien que fonctionnant parfaitement pour l'application visée, je ne suis pas certain que ma procédure BINtoGRAY soit optimisée suivant le nombre de bits choisi. Il aurait peut-être pu être amélioré au travers de l'utilisation d'une procédure de récursivité...
Code : Tout sélectionner
; -------------------------------------------------------------------------------------------------------
; Graphique rectiligne coder en code Gray de 2 à 10 bits
; Philippe Mjon - mai 2023 PureBasic 6.01 LTS (x64)
; -------------------------------------------------------------------------------------------------------
; l'image enregistrée est au format jpg ou png et placer sur le bureau
; à la fin du traitement, elle s'ouvre automatiquement avec votre lecteur d'images jpg/png
; -------------------------------------------------------------------------------------------------------
;
; Paramétres modifiables
; -------------------------------------------------------------------------------------------------------
Nbits = 8 ; valeur comprise entre 2 et 10 bits de données
Echelle = 1 ; échelle de l'image enregistrée (valeur supérieure ou égale à 1)
Box_x = 20 ; dimension en x du "carré" de chaque bit en pixels (par défaut 20)
Box_y = 20 ; dimension en y du "carré" de chaque bit en pixels (par défaut 20)
ecart = 1 ; épaisseur de la grille séparant les bits (0 sans grille visible)
formatIMAGE = 1 ; format de l'image enregistrée : 0=png ou 1=jpg (qualité 10)
; -------------------------------------------------------------------------------------------------------
Global B0, B1, B2, B3, B4, B5, B6, B7, B8, B9
Global Gray$
Global BIN$
Declare BINtoGRAY (Nbits)
; dimensions adaptées de l'image enregistrée suivant le Nb de bits (pixels)
If Nbits = 2
xx= 75 : yy = 82
ElseIf Nbits = 3
xx= 100 : yy = 165
ElseIf Nbits = 4
xx= 120 : yy = 335
ElseIf Nbits = 5
xx= 145 : yy = 670
ElseIf Nbits = 6
xx= 170 : yy = 1345
ElseIf Nbits = 7
xx= 195 : yy = 2690
ElseIf Nbits = 8
xx= 215 : yy = 5375
ElseIf Nbits = 9
xx= 240 : yy = 10750
ElseIf Nbits = 10
xx= 265 : yy = 21500
EndIf
UsePNGImageEncoder()
UseJPEGImageEncoder()
; -------------------------------------------------------------------------------------------------------
If Nbits <11 And Nbits >1 ; graphique Gray possible de 2 à 10 bits
If OpenWindow(0, 10, 10, 250, 350, "Code Gray rectiligne de " + Nbits + " bits", #PB_Window_SystemMenu)
If CreateImage(0, xx, yy) And StartDrawing(ImageOutput(0))
Nbdec = Pow(2,Nbits)-1
y = 0 : x = 0
For g = 0 To Nbdec
BIN$ = RSet(Bin(g), Nbits, "0") ; DEC to BIN
BINtoGRAY (Nbits) ; BIN to GRAY (XOR)
For i = 1 To Nbits
If Mid(Gray$, i, 1) = "1"
coul = 0
Else
coul = 255
EndIf
Box(x, y, Box_x, Box_y, RGB(coul, coul, coul))
x + Box_y + ecart
Next
DrawText(x+20, y, Str(g), RGB(200, 200, 200))
x = 0
y + Box_y + ecart
Next
StopDrawing()
ImageGadget(0, 0, 0, xx, yy, ImageID(0))
ResizeImage(0, xx*Echelle, yy*Echelle)
If formatIMAGE = 0
; Image enregistrée au format png
SaveImage(0, GetUserDirectory(#PB_Directory_Desktop) + "Gray " + Nbits + "_" + Nbdec + ".png", #PB_ImagePlugin_PNG)
RunProgram(GetUserDirectory(#PB_Directory_Desktop) + "Gray " + Nbits + "_" + Nbdec + ".png")
ElseIf formatIMAGE = 1
; Image enregistrée au format jpg en qualité 10
SaveImage(0, GetUserDirectory(#PB_Directory_Desktop) + "Gray " + Nbits + "_" + Nbdec + ".jpg", #PB_ImagePlugin_JPEG, 10)
RunProgram(GetUserDirectory(#PB_Directory_Desktop) + "Gray " + Nbits + "_" + Nbdec + ".jpg")
EndIf
EndIf
Repeat
Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
EndIf
Else
MessageRequester("Erreur", "Le nombre de bits doit être compris entre 2 et 10 !", #PB_MessageRequester_Warning)
End
EndIf
End
; -------------------------------------------------------------------------------------------------------
Procedure BINtoGRAY (Nbits) ; Traitements adaptés XOR (!) pour la conversion Bin to Gray
B0 = Val(Mid(BIN$, Nbits, 1))
B1 = Val(Mid(BIN$, Nbits-1, 1))
B2 = Val(Mid(BIN$, Nbits-2, 1))
B3 = Val(Mid(BIN$, Nbits-3, 1))
B4 = Val(Mid(BIN$, Nbits-4, 1))
B5 = Val(Mid(BIN$, Nbits-5, 1))
B6 = Val(Mid(BIN$, Nbits-6, 1))
B7 = Val(Mid(BIN$, Nbits-7, 1))
B8 = Val(Mid(BIN$, Nbits-8, 1))
B9 = Val(Mid(BIN$, Nbits-9, 1))
If Nbits = 2
G1 = B1
G0 = B1 ! B0
Gray$ = Str(G1) + Str(G0)
ElseIf Nbits = 3
G2 = B2
G1 = B2 ! B1
G0 = B1 ! B0
Gray$ = Str(G2) + Str(G1) + Str(G0)
ElseIf Nbits = 4
G3 = B3
G2 = B3 ! B2
G1 = B2 ! B1
G0 = B1 ! B0
Gray$ = Str(G3) + Str(G2) + Str(G1) + Str(G0)
ElseIf Nbits = 5
G4 = B4
G3 = B4 ! B3
G2 = B3 ! B2
G1 = B2 ! B1
G0 = B1 ! B0
Gray$ = Str(G4) + Str(G3) + Str(G2) + Str(G1) + Str(G0)
ElseIf Nbits = 6
G5 = B5
G4 = B5 ! B4
G3 = B4 ! B3
G2 = B3 ! B2
G1 = B2 ! B1
G0 = B1 ! B0
Gray$ = Str(G5) + Str(G4) + Str(G3) + Str(G2) + Str(G1) + Str(G0)
ElseIf Nbits = 7
G6 = B6
G5 = B6 ! B5
G4 = B5 ! B4
G3 = B4 ! B3
G2 = B3 ! B2
G1 = B2 ! B1
G0 = B1 ! B0
Gray$ = Str(G6) + Str(G5) + Str(G4) + Str(G3) + Str(G2) + Str(G1) + Str(G0)
ElseIf Nbits = 8
G7 = B7
G6 = B7 ! B6
G5 = B6 ! B5
G4 = B5 ! B4
G3 = B4 ! B3
G2 = B3 ! B2
G1 = B2 ! B1
G0 = B1 ! B0
Gray$ = Str(G7) + Str(G6) + Str(G5) + Str(G4) + Str(G3) + Str(G2) + Str(G1) + Str(G0)
ElseIf Nbits = 9
G8 = B8
G7 = B8 ! B7
G6 = B7 ! B6
G5 = B6 ! B5
G4 = B5 ! B4
G3 = B4 ! B3
G2 = B3 ! B2
G1 = B2 ! B1
G0 = B1 ! B0
Gray$ = Str(G8) + Str(G7) + Str(G6) + Str(G5) + Str(G4) + Str(G3) + Str(G2) + Str(G1) + Str(G0)
ElseIf Nbits = 10
G9 = B9
G8 = B9 ! B8
G7 = B8 ! B7
G6 = B7 ! B6
G5 = B6 ! B5
G4 = B5 ! B4
G3 = B4 ! B3
G2 = B3 ! B2
G1 = B2 ! B1
G0 = B1 ! B0
Gray$ = Str(G9) + Str(G8) + Str(G7) + Str(G6) + Str(G5) + Str(G4) + Str(G3) + Str(G2) + Str(G1) + Str(G0)
EndIf
EndProcedure