ArduinoEmbedded & IoT

Arduino Leonardo: realizziamo un gamepad

Sfruttiamo le librerie arduino per generare un controller basato su Atmega32u8

Con il seguente tutorial si vuole costruire un gamepad da gioco economico dotato di pulsantiera e di Joystick. Il sistema presentato è modificabile ed espandibile a seconda delle vostre esigenze e viene riconosciuto senza problemi dai sistemi operativi Microsoft Windows 10/11, macOS e sistemi GNU/Linux senza driver aggiuntivi, perché il Leonardo si presenta come periferica USB HID standard.

Per il progetto è stato scelto di utilizzare un joystick analogico (stile Playstation) ma è gestito a livello software come un joystick a contatti (stile vecchi cabinati). Di seguito è riportato il materiale necessario alla realizzazione del gamepad.

Materiale necessario

  • Arduino Leonardo o compatibile (qualsiasi scheda basata su ATmega32U4 con USB nativa, ad esempio Arduino Micro o Pro Micro)
  • 10 Pulsanti da gamepad (numero di pulsanti variabile dalle proprie esigenze)
  • Joystick analogico 

Funzionamento

I pulsanti, normalmente aperti, se premuti porteranno uno stato logico LOW al microcontrollore. Tale stato, per esser correttamente letto, necessita dell’attivazione software delle resistenze di pull-up (si veda l’articolo sugli input digitali di Arduino). Queste ultime possono essere inserite anche fisicamente nel progetto, ma in tal caso sarà d’obbligo non attivare quelle interne del microcontrollore. Quando il microcontrollore riceverà l’informazione LOW da un pulsante, invierà un report USB HID al computer: il Leonardo, basato sul microcontrollore ATmega32U4 con USB integrata, viene infatti riconosciuto come una periferica di gioco e non comunica i tasti tramite la porta seriale. Il joystick, invece, funziona semplicemente con soglie analogiche di attivazione: su/giù e destra/sinistra sono gestiti con valori da 0 a 300 e da 700 a 1023 (intervallo restituito da analogRead(), vedi l’articolo sugli ingressi analogici di Arduino). La zona considerata centrale è compresa tra 300 e 700, estremi esclusi.

Schema elettrico

Schema elettrico (download):

Schema elettrico del gamepad con Arduino Leonardo, 10 pulsanti sui pin 0-9 e joystick analogico su A0 e A1

Libreria Joystick

Lo sketch utilizza la libreria ArduinoJoystickLibrary di Matthew Heironimus (versione 2.x), che non è inclusa nell’IDE: si scarica come archivio ZIP dal repository GitHub MHeironimus/ArduinoJoystickLibrary e si installa da Sketch > Includi libreria > Aggiungi libreria da file .ZIP. Il file da includere è Joystick.h, con la J maiuscola: su Linux e sui file system che distinguono maiuscole e minuscole la forma joystick.h non viene trovata.

Sketch

Sketch (download):

#include <Joystick.h>

//impostare il pin dove sono collegati i pulsanti
int pulsante1=0;
int pulsante2=1;
int pulsante3=2;
int pulsante4=3;
int pulsante5=4;
int pulsante6=5;
int pulsante7=6;
int pulsante8=7;
int pulsante9=8;
int pulsante10=9;

Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID, JOYSTICK_TYPE_GAMEPAD,
                   10, 0,                 // Button Count, Hat Switch Count
                   true, true, false,     // X and Y, but no Z Axis
                   false, false, false,   // No Rx, Ry, or Rz
                   false, false,          // No rudder or throttle
                   false, false, false);  // No accelerator, brake, or steering

void setup() {
//dichiaro input ed imposto resistenza interna di pull-up
  pinMode(pulsante1, INPUT_PULLUP);
  pinMode(pulsante2, INPUT_PULLUP);
  pinMode(pulsante3, INPUT_PULLUP);
  pinMode(pulsante4, INPUT_PULLUP);
  pinMode(pulsante5, INPUT_PULLUP);
  pinMode(pulsante6, INPUT_PULLUP);
  pinMode(pulsante7, INPUT_PULLUP);
  pinMode(pulsante8, INPUT_PULLUP);
  pinMode(pulsante9, INPUT_PULLUP);
  pinMode(pulsante10, INPUT_PULLUP);

  Joystick.begin(false); // false: i report USB vengono inviati solo con Joystick.sendState() a fine loop
  Joystick.setXAxisRange(-1, 1);
  Joystick.setYAxisRange(-1, 1);
}


void loop() {

 //imposto soglia sensibilità nel caso in cui il joystick sia analogico anzichè a contatto
 //la soglia di attivazione è: 0-300   700-1023   mentre 301-699 rappresenta la posizione centrale
 //ogni asse viene letto una sola volta per ciclo
 //il segno (+1/-1) dipende dall'orientamento del modulo joystick:
 //se un asse risulta invertito, scambiare 1 e -1 nel relativo blocco if
    int asseX = analogRead(A1);
    int asseY = analogRead(A0);

    if (asseX <= 300) {
      Joystick.setXAxis(1);
    } else if (asseX >= 700) {
      Joystick.setXAxis(-1);
    } else {
      Joystick.setXAxis(0);
    }

    if (asseY <= 300) {
      Joystick.setYAxis(1);
    } else if (asseY >= 700) {
      Joystick.setYAxis(-1);
    } else {
      Joystick.setYAxis(0);
    }


//se premuti, i pulsanti mandano a LOW gli ingressi i quali restituiscono stato logico HIGH sul comando gamepad

if(digitalRead(pulsante1) == LOW){Joystick.setButton(0, HIGH);}else{Joystick.setButton(0, LOW);}
 if(digitalRead(pulsante2) == LOW){Joystick.setButton(1, HIGH);}else{Joystick.setButton(1, LOW);}
if(digitalRead(pulsante3) == LOW){Joystick.setButton(2, HIGH);}else{Joystick.setButton(2, LOW);}
if(digitalRead(pulsante4) == LOW){Joystick.setButton(3, HIGH);}else{Joystick.setButton(3, LOW);}
if(digitalRead(pulsante5) == LOW){Joystick.setButton(4, HIGH);}else{Joystick.setButton(4, LOW);}
if(digitalRead(pulsante6) == LOW){Joystick.setButton(5, HIGH);}else{Joystick.setButton(5, LOW);}
if(digitalRead(pulsante7) == LOW){Joystick.setButton(6, HIGH);}else{Joystick.setButton(6, LOW);}
if(digitalRead(pulsante8) == LOW){Joystick.setButton(7, HIGH);}else{Joystick.setButton(7, LOW);}
if(digitalRead(pulsante9) == LOW){Joystick.setButton(8, HIGH);}else{Joystick.setButton(8, LOW);}
if(digitalRead(pulsante10) == LOW){Joystick.setButton(9, HIGH);}else{Joystick.setButton(9, LOW);}

Joystick.sendState(); //invia un unico report con lo stato di assi e pulsanti
delay(10);
}

Realizzato il cablaggio e caricato lo sketch con l’apposito IDE Arduino saremo pronti ad utilizzare il nostro gamepad con i nostri giochi. Se un pulsante genera pressioni multiple indesiderate si può intervenire con le tecniche descritte nell’articolo sui circuiti di debouncing.

Admin | MST-Tutorial

Appassionato di elettronica, elettrotecnica e programmazione. Fondatore di MST-Tutorial, condivido con entusiasmo conoscenze, esperienze e progetti legati all’innovazione tecnologica, con l’obiettivo di rendere accessibili concetti tecnici complessi attraverso tutorial chiari e pratici.

Articoli Correlati

Check Also
Chiudi
Pulsante per tornare all'inizio