Post

Décoder les signaux analogiques d'un mini-joystick avec l'ADC de ma carte FPGA DE0-nano

Décoder les signaux analogiques d'un mini-joystick avec l'ADC de ma carte FPGA DE0-nano

La carte FPGA DE0-nano intègre un ADC (Analog Digital Converter) ou convertisseur analogique-numérique. La puce ADC128S022 comprend 8 entrées analogiques reliées à un port GPIO 2x13 E/S sur le dessous de la carte.

ADC Cyclone IV Extrait User Manual DE0-nano

Il s’agit d’un convertisseur 12 bits avec une tension de référence 3,3V prise sur la carte. On communique avec la puce avec le protocole SPI (Serial Peripheral Interface) avec une fréquence d’horloge qui peut aller jusqu’à 3,2MHz (soit 200 ksps).

Comme un c@#, j’avais rédigé un tutoriel Communication SPI avec un convertisseur Analogique-Numérique, simulation fonctionnelle et analyse des signaux avant de me rendre compte que la bibliothèque d’IP cores (Intellectual Property) dans Quartus Prime comprenait déjà un contrôleur pour ce convertisseur A/N ;-)

IP catalog Catalogue des IP cores dans Quartus Prime

Mise en œuvre du contrôleur de l’ADC

Et le composant analogique que je vais utiliser pour tester l’ADC est un mini-joystick HW-504. Le joystick est monté sur un mécanisme articulé avec deux potentiomètres rotatifs à axes perpendiculaires X et Y. Le mouvement gauche-droite entraîne la rotation du potentiomètre autour de l’axe X. Le mouvement avant-arrière entraîne la rotation de l’autre potentiomètre autour de l’axe Y. Et toute autre direction prise par le joystick affectera la rotation des deux potentiomètres. Ansi, les valeurs retournées par les rotations des deux potentiomètres donneront une image de la direction dans le plan X,Y donnée au joystick.

Joystick HW-504 le Joystick HW-504 relié à deux entrées analogiques de la cartes FPGA

Pour un premier test, je ne vais relever que le mouvement avant-arrière du joystick et n’actionner qu’un seul potentiomètre câblé sur l’entrée analogique n°0 :

vue RTL contrôleur ADC

L’horloge CLOCKà l’entrée du contrôleur de l’ADC est réduite à 3,2MHz (200 échantillons par seconde en théorie). Le contrôleur se charge de la communication avec l’ADC selon le protocole série SPI (signaux ADC_xxx). Je devine que le contrôleur va chercher à échantillonner chacune des huits entrées analogiques tour à tour (mode free running). L’ADC présente le résultat 12 bits issu de la conversion A/N sur sa sortie série ADC_DOUT. Le contrôleur se charge alors de présenter le résultat entre 0 et 4095 sur un bus parallèle 12 bits CHx[11..0]pour exploitation.

Ici, je dirige la sortie CH0[11..0] vers un autre contrôleur qui pilotera le ruban de 8 Leds en surface de la carte FPGA :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
module adc_led_display (
    input logic clk,              // Horloge principale
    input logic [11:0] adc_data,  // Résultat de la conversion A/N sur l'entrée analogique CH0
    output logic [7:0] led_out    // Affichage sur Ledsx8
);

    logic [11:0] neutral_min = 1850;  // valeur neutre constatée : env. 1970
    logic [11:0] neutral_max = 2100;
    
    always_ff @(posedge clk) begin
        // Position neutre
        if ((adc_data >= neutral_min) && (adc_data <= neutral_max)) begin
            led_out <= 8'b00011000; // Allume LED[3] et LED[4] en position neutre
        end else begin
            // Descente du joystick (valeur ADC monte vers 4095)
            led_out[5] <= (adc_data >= 2500);  
            led_out[6] <= (adc_data >= 3000);  
            led_out[7] <= (adc_data >= 3500);  

            // Montée du joystick (valeur ADC descend vers 0)
            led_out[2] <= (adc_data <= 1500);  
            led_out[1] <= (adc_data <= 1000);  
            led_out[0] <= (adc_data <= 500);  
        end
    end

endmodule

Lorsque le joystick est rappelé en position neutre, le convertisseur A/N devrait théoriquement retourner la valeur 4096 / 2 = 2048. En pratique, je suis plutôt autour de 1980. La précision de la mécanique étant ce qu’elle est, j’ai recadré la valeur neutre entre 1850 et 2100, mais cela dépend de votre joystick.

En postion neutre, les deux leds centrales 3 et 4 sont allumées. Un ruban de leds allumées se forme à gauche ou à droite selon la direction avant ou arrière du joystick.

Essai concluant, le ruban se forme progressivement lorsque je pousse ou tire doucement le joystick…

Lien vers le dépôt du projet : fpga-adc-joystick-1

Mais avec un joystick, et un écran VGA, on peut faire beaucoup mieux. À suivre ;-)

Cet article est sous licence CC BY 4.0 par l'auteur.