le varianti di arduino che montano l’atmega32u4 (leonardo, micro e yún) possono emulare mouse e tastiera. oggi ho scoperto che possono emulare anche il joystick.

però, a differenza dell’emulazione di testiera e mouse, non basta importare le librerie giuste e scrivere qualche riga di codice: in questo caso bisogna modificare un paio di files tra i sorgenti di arduino. ho trovato questo post sul blog di [connor] con istruzioni e informazioni dettagliate. quasi dettagliate, perché le modifiche, che risalgono al 2012, si basano su una vecchia versione di arduino, diversa dalla mia 1.6.0. la soluzione è tra i commenti e l’ha trovata [reinaldo ramos]

commento ramos

in pratica [connor] ha scoperto quali files devono essere sostituiti, [reinaldo ramos] ha aggiornato le modifice per farli funzionare con le ultime versioni di arduino. i files modificati e aggiornati, USBAPI.h e HID.cpp, possono essere scaricati da qui o direttamente dal link di [reinaldo ramos].

i due files vanno copiati nella directory hardware\arduino\avr\cores\arduino che si trova nella directory dell’eseguibile di arduino (in windows è C:\Program Files (x86)\Arduino; in mac bisogna visualizzare il contenuto di Arduino.app e procedere in Contents\Java) sostituendoli agli originali (di cui forse è meglio farsi una copia, prima).

lo sketch di prova di [connor] funziona bene ed è corredato di commenti e spiegazioni, può essere scaricato anche da qui. non è molto utile, ma serve a provare se tutto funziona bene.

il mio sketch invece usa quattro pulsanti per emulare il funzionamento di un joystick digitale, un quinto pulsante come grilletto del joystick e un potenziometro come throttle. eccolo:

byte uBtn = 2; // up     y = 0
byte dBtn = 3; // down   y = 255
byte lBtn = 4; // left   x = 0
byte rBtn = 5; // right  x = 255
byte jBtn = 6; // trigger

byte ledPin = 13;

JoyState_t joySt;

void setup() {

  pinMode(uBtn, INPUT_PULLUP);
  pinMode(dBtn, INPUT_PULLUP);
  pinMode(lBtn, INPUT_PULLUP);
  pinMode(rBtn, INPUT_PULLUP);
  pinMode(jBtn, INPUT_PULLUP);

  pinMode(ledPin, OUTPUT);
  
  joySt.xAxis = 0;
  joySt.yAxis = 0;
  joySt.zAxis = 0;
  joySt.xRotAxis = 0;
  joySt.yRotAxis = 0;
  joySt.zRotAxis = 0;
  joySt.throttle = 0;
  joySt.rudder = 0;
  joySt.hatSw1 = 0;
  joySt.hatSw2 = 0;
  joySt.buttons = 0;

}


void loop() {
  
  if (digitalRead(uBtn) == LOW) {
    digitalWrite(ledPin, HIGH);
    joySt.yAxis = 0;
  } else if (digitalRead(dBtn) == LOW) {
    digitalWrite(ledPin, HIGH);
    joySt.yAxis = 255;
  } else {
    digitalWrite(ledPin, LOW);
    joySt.yAxis = 128;
  }
  
  if ( (digitalRead(uBtn) == LOW) && (digitalRead(dBtn) == LOW) ) {
    digitalWrite(ledPin, HIGH);
    joySt.yAxis = 128;
  }
  
  if (digitalRead(lBtn) == LOW) {
    digitalWrite(ledPin, HIGH);
    joySt.xAxis = 0;
  } else if (digitalRead(rBtn) == LOW) {
    digitalWrite(ledPin, HIGH);
    joySt.xAxis = 255;
  } else {
    digitalWrite(ledPin, LOW);
    joySt.xAxis = 128;
  }

  if ( (digitalRead(lBtn) == LOW) && (digitalRead(rBtn) == LOW) ) {
    digitalWrite(ledPin, HIGH);
    joySt.xAxis = 128;
  }
    
  joySt.buttons = (digitalRead(jBtn) == LOW) ? 1 : 0;

  joySt.throttle = map(analogRead(A0), 0, 1024, 0, 255);

  Joystick.setState(&joySt);

}

ed ecco come si comporta una volta collegato:

arduino joystick