Nota

Ciao, benvenuto nella Community SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasts su Facebook! Approfondisci Raspberry Pi, Arduino ed ESP32 con altri appassionati.

Perché unirsi?

  • Supporto esperto: Risolvi problemi post-vendita e sfide tecniche con l’aiuto della community e del nostro team.

  • Impara e condividi: Scambia consigli e tutorial per migliorare le tue competenze.

  • Anteprime esclusive: Accedi in anteprima ai nuovi annunci di prodotti e alle anteprime speciali.

  • Sconti speciali: Godi di sconti esclusivi sui nostri prodotti più recenti.

  • Promozioni e giveaway festivi: Partecipa a concorsi e promozioni durante le festività.

👉 Pronto a esplorare e creare con noi? Clicca [Qui] e unisciti oggi stesso!

2.1.6 Joystick (MCP3008)

Nota

../_images/mcp3008_and_adc0834.jpg

A seconda della versione del kit, identifica se hai ADC0834 o MCP3008 e procedi con la sezione corrispondente.

Introduzione

In questo progetto impareremo come funziona un joystick. Muoveremo il joystick e visualizzeremo i risultati sullo schermo.

Componenti richiesti

In questo progetto sono necessari i seguenti componenti.

../_images/image317-copy.png

Principio

Joystick

L’idea di base di un joystick è convertire il movimento di una leva in informazioni elettroniche che un computer può elaborare.

Per comunicare l’intera gamma di movimento al computer, un joystick deve misurare la posizione della leva su due assi — l’asse X (sinistra-destra) e l’asse Y (alto-basso). Come nella geometria di base, le coordinate X-Y individuano esattamente la posizione della leva.

Per determinare la posizione della leva, il sistema di controllo del joystick monitora semplicemente la posizione di ciascun asse. Il design convenzionale di un joystick analogico lo fa con due potenziometri, o resistenze variabili.

Il joystick ha anche un ingresso digitale che viene attivato quando il joystick viene premuto verso il basso.

../_images/image318.png

Schema elettrico

Quando si leggono i dati del joystick, ci sono alcune differenze tra gli assi: i dati degli assi X e Y sono analogici e richiedono l’uso dell’MCP3008 per convertire il valore analogico in digitale. I dati dell’asse Z sono digitali, quindi è possibile leggerli direttamente tramite GPIO, oppure si può comunque usare l’ADC.

../_images/schematic_2.1.9_joystick_mcp3008.png

Procedura sperimentale

Passo 1: Montare il circuito.

../_images/july24_2.1.9_joystick_mcp3008.png

Passo 2: Accedere alla cartella del codice.

cd ~/davinci-kit-for-raspberry-pi/c/2.1.6-2/

Passo 3: Compilare il codice.

gcc 2.1.6_Joystick.c -o joystick -lwiringPi

Passo 4: Eseguire il file compilato.

./joystick

Dopo l’esecuzione del codice, muovere il joystick: i valori corrispondenti di x, y e Btn verranno visualizzati sullo schermo.

Nota

Se non funziona dopo l’esecuzione, o compare l’errore: "wiringPi.h: No such file or directory", fare riferimento a Installazione e verifica di WiringPi.

Codice

#include <wiringPi.h>
#include <wiringPiSPI.h>
#include <stdio.h>

#define SPI_CHANNEL 0
#define SPI_SPEED   1000000  // 1 MHz
#define BtnPin      3        // WiringPi 3 = BCM GPIO22

// Legge dal canale MCP3008 (0–7)
int read_ADC(int channel) {
    if (channel < 0 || channel > 7) return -1;

    unsigned char buffer[3];
    buffer[0] = 1;                            // Bit di avvio
    buffer[1] = (8 + channel) << 4;           // Configurazione canale
    buffer[2] = 0;

    wiringPiSPIDataRW(SPI_CHANNEL, buffer, 3);

    int result = ((buffer[1] & 0x03) << 8) | buffer[2];
    return result;
}

int main(void) {
    if (wiringPiSetup() == -1) {
        printf("Inizializzazione WiringPi fallita!\n");
        return 1;
    }

    if (wiringPiSPISetup(SPI_CHANNEL, SPI_SPEED) == -1) {
        printf("Inizializzazione SPI fallita!\n");
        return 1;
    }

    pinMode(BtnPin, INPUT);
    pullUpDnControl(BtnPin, PUD_UP);

    while (1) {
        int x_val = read_ADC(0);     // VRX su CH0
        int y_val = read_ADC(1);     // VRY su CH1
        int btn_val = digitalRead(BtnPin);  // Pulsante SW

        printf("x = %d, y = %d, btn = %d\n", x_val, y_val, btn_val);
        delay(100);
    }

    return 0;
}

Spiegazione del codice

  1. Questa sezione inizializza le librerie necessarie per la comunicazione GPIO e SPI.

    #include <wiringPi.h>
    #include <wiringPiSPI.h>
    #include <stdio.h>
    
    #define SPI_CHANNEL 0
    #define SPI_SPEED   1000000  // 1 MHz
    #define BtnPin      3        // WiringPi 3 = BCM GPIO22
    
  2. Definisce la funzione read_ADC() per leggere dati analogici dal MCP3008. Comunica tramite SPI per richiedere i dati da un determinato canale (0–7) e poi elabora la risposta per ottenere un risultato ADC a 10 bit.

    int read_ADC(int channel) {
        if (channel < 0 || channel > 7) return -1;
    
        unsigned char buffer[3];
        buffer[0] = 1;
        buffer[1] = (8 + channel) << 4;
        buffer[2] = 0;
    
        wiringPiSPIDataRW(SPI_CHANNEL, buffer, 3);
    
        int result = ((buffer[1] & 0x03) << 8) | buffer[2];
        return result;
    }
    
  3. La funzione main inizializza le interfacce WiringPi e SPI, configura il pin del pulsante del joystick e legge continuamente i valori del joystick, stampandoli a schermo.

    int main(void) {
        if (wiringPiSetup() == -1) {
            printf("Inizializzazione WiringPi fallita!\n");
            return 1;
        }
    
        if (wiringPiSPISetup(SPI_CHANNEL, SPI_SPEED) == -1) {
            printf("Inizializzazione SPI fallita!\n");
            return 1;
        }
    
        pinMode(BtnPin, INPUT);
        pullUpDnControl(BtnPin, PUD_UP);
    
        while (1) {
            int x_val = read_ADC(0);     // VRX su CH0
            int y_val = read_ADC(1);     // VRY su CH1
            int btn_val = digitalRead(BtnPin);  // SW su GPIO22
    
            printf("x = %d, y = %d, btn = %d\n", x_val, y_val, btn_val);
            delay(100);
        }
    
        return 0;
    }
    
  4. In questo programma:

    • VRX del joystick è collegato al CH0 dell’MCP3008.

    • VRY è collegato al CH1.

    • Il pulsante (SW) è collegato al GPIO22 (pin 3 di WiringPi).

    • La funzione read_ADC() viene usata per leggere i valori analogici di VRX e VRY.

    • Il valore digitale del pulsante viene letto con digitalRead().

    • Tutti i valori vengono stampati continuamente ogni 100 millisecondi.