Fishino Joypad By Gaspare Santaera & Mattia Poggiani

Il numero 200 di Elettronica In presentava, in copertina, un progetto che a prima vista ci è sembrato banale ma che dopo averlo provato si è mostrato in tutte le sue potenzialità. Stiamo parlando del progetto “Retropie”, una vera e propria carrellata amarcord per chi, come noi era lì agli albori delle prime console domestiche nonché al tramonto delle ultime sale giochi.
A prima vista, appunto, il progetto Retropie sembrerebbe il solito emulatore, ma dopo averlo provato all’ultima maker faire di Roma lo scorso ottobre, abbiamo deciso di riprodurlo a casa sulle nostre raspberry e da lì non abbiamo più smesso di giocarci. Infatti, Retropie oltre ad offrire la possibilità di ritrovare i giochi classici che hanno accompagnato le nostre e chissà quante altre infanzie si distingue anche per la varietà di console e giochi emulabili, arrivando fino alle console più recenti di qualche anno fa.
Per questo motivo, spinti dal contest, organizzato dalla rivista, abbiamo deciso di aggiungere qualcosa in più al progetto iniziale, sfruttando le potenzialità standard di un micro-controllore, unite all’espandibilità wifi, che caratterizza Fishino, realizzando così un joypad wireless.
In questo articolo, infatti, vedremo come realizzare un joypad per la nostra raspberry, non si tratterà soltanto del classico joypad (modello super nintendo) ma oltre ad offrire le connettività wireless il device presentato potrebbe essere la base di futuri progetti più complessi capaci di espandere e migliorare l’esperienza di gioco, usando per esempio sensori di forza, accelerometri, sensori ad infrarossi ect…
Nel nostro caso come detto ci occuperemo dell’interfaccia classica, pertanto Fishino si occuperà di gestire dieci tasti (4 frecce, start, select, A,B,X,Y) un piccolo display Nokia che riporta alcune informazioni di sistema e della gestione della ricarica della batteria LIPO.
Il joypad è stato interamente stampato in 3D, in questo articolo vi forniremo tutti i CAD necessari per la sua stampa, ma ancora una volta così come per l’espansione del device, confidiamo nell’inventiva dei lettori per il miglioramento della forma e delle funzionalità

 

Hardware
L’Hardware del nostro progetto, ovviamente è incentrato su Fishino, sul quale in questa sede spenderemo soltanto qualche parola rimandando la curiosità dei lettori ai molti articoli precedentemente pubblicati, a questo va connessa una scheda che ha le dimensioni e le connessioni di uno shield stardard di Arduino.

Tale shield si occupa della  connessione tra un display lcd Nokia e Fishino, di gestire tutti i pulsanti presenti nel joypad e di gestire la ricarica della batteria del joypad.

Per quanto riguarda il display, abbiamo deciso di riutilizzare un display lcd Nokia 5110, in bianco e nero con una risoluzione di 84×48 pixel. In questo caso lo shield si occupa soltanto di creare le connessioni fisiche tra Fishino e il display. Il display si interfaccia facilmente con un Arduino/Fishino tramite un connettore ad otto poli, mentre per la sua gestione basta usare l’apposita libreria (http://playground.arduino.cc/Code/PCD8544).
All’indirizzo specificato troverete tutte le informazioni riguardanti le connessioni nonché la creazione e la gestione dei grafici sul display.

Fig. 1 Schematico del Circuito

Fig. 1 Schematico del Circuito

Come accennato, la presenza di un display ci permette di avere un riscontro visivo sulle operazioni compiute (es. indicare i tasti premuti) e di ottenere informazioni sul sistema (es. livello batteria, indirizzo ip della raspberry, ect..), vedremo nel dettaglio questi aspetti quando tratteremo la parte relativa al firmware, per il momento torniamo sull’hardware passando alla gestione dei tasti.
Nel nostro progetto abbiamo deciso di emulare il classico joypad del super nintendo che contiene dieci tasti; quattro frecce per le direzioni, un tasto di start, uno di select e poi quattro tasti di gioco, la cui funzione varia al variare del gioco.
Per la realizzazione dei tasti, ovviamente abbiamo utilizzato dei classici button per la cui gestione ci siamo affidati a cinque ingressi analogici di Fishino ed a due ingressi digitali. Per il controllo dello stato dei tasti, la soluzione ideale è data dall’utilizzo di dieci ingressi digitali, in modo da sfruttare al massimo la velocità di commutazione di quest’ultimi e di evitare i tempi di conversione dell’ADC presente sugli ingressi analogici. Tuttavia in questo caso specifico la mancanza di dieci pin liberi ci ha spinto ad usare gli ingressi analogici ed una combinazione di partitori resistivi in modo da ridurre quanto più possibile l’utilizzo dei pin.

Fig. 2 Modello di Joypad Riprodotto

Fig. 2 Modello di Joypad Riprodotto

Infatti, come accennato nel nostro progetto usiamo soltanto sette pin totali, a fronte dei dieci tasti, ovvero vengono usati quattro ingressi analogici (A1, A2, A3, A4) per la gestione dei tasti di gioco, due ingressi digitali (D8, D9) per i tasti Start e Select, ed un solo ingresso analogico (A0) per la gestione dei tasti freccia.
Quest’ultimi vengono discriminati mediante ben sedici differenti partitori resistivi, formati da un’unica resistenza del valore di 10 Kohm tra Vcc e il pin A0 e quattro diverse resistenze, ognuna delle quali ha un valore di circa il doppio rispetto alla precedente (1, 2, 4.3, 9.1 Kohm) connesse in serie tra i tasti e ground. In questo modo ad ognuna delle possibili combinazioni di tasti (16 in tutto), corrisponde un partitore, ovvero un solo valore di tensione equivalente, il che permette in modo piuttosto accurato di fare una mappatura di tutte le combinazioni e poi tramite uno switch all’interno del firmware riuscire a capire il tasto/i premuti.
Ad esempio , riferendoci allo schematico mostrato nella figura 1, il pulsante S1 (tasto freccia su) è connesso alla resistenza R4 di 2 Kohm, mentre il pulsante S2 (tasto freccia sinistra) è connesso alla resistenza R1 di 1 Kohm, pertanto se un utente preme S1 sul partitore ci sarà una tensione pari a (2/12)*5V =  0.83 V, mentre se preme contemporaneamente S1 ed S2 sul partitore ci sarà una tensione pari a ((2//1)/(2//1 + 10))*5V = 0.31V e così via nei restanti quattordici casi.
L’ultimo compito della scheda è quello di gestire l’alimentazione, il nostro progetto viene alimentato tramite una batteria LiPo a due celle (7.4V), che va gestita e ricaricata.
Il joypad viene acceso e spento tramite due strategie diverse,  per l’accensione viene utilizzato un apposito tasto (S11), questo quando viene premuto connette direttamente il polo positivo della batteria con il pin Vin di Fishino, dando così alimentazione alla scheda.

Fig. 3 CAD della scheda

Fig. 3 CAD della scheda

A questo punto entra in gioco il firmware, infatti, appena riceve l’alimentazione dalla scheda, Fishino si avvia immediatamente abilitando tre distinti optoisolatori. Due di questi (OK1 e OK4) connettono il pin Vin di Fishino al polo positivo della batteria, mentre il terzo (OK3) connette il pin A5 di Fishino al pin che si trova tra la serie delle due celle che compongono la batteria. Successivamente Fishino, fa una lettura su A5, se legge una tensione superiore ai 3.6V allora la batteria è carica e Fishino provvede a lasciare accesi i due optoisolatori connessi alla batteria. Questi infatti, fungono da interruttori digitali, attivandosi e fornendo l’alimentazione a Fishino dalla batteria. Per lo spegnimento del joypad abbiamo invece previsto una procedura totalmente affidata al firmware in cui nel caso di pressione contemporanea dei quattro tasti freccia, Fishino provvede a disattivare i tre optoisolatori descritti, interdicendo di conseguenza la sua stessa alimentazione. Per preservare la batteria è previsto anche uno spegnimento automatico nel caso in cui Fishino veda sul pin A5 una tensione troppo bassa.
Considerazioni un po’ diverse vanno fatte nel caso in cui si voglia ricaricare la batteria; in caso di alimentazione esterna, infatti, abbiamo escluso la possibilità di accendere o spegnere il joypad, ovvero questo resta sempre acceso, in modo da avere un principio di funzionamento un po’ più lineare che permette a Fishino di tener sempre sotto controllo la batteria.

L’alimentazione esterna, infatti, è collegata direttamente al pin Vin di Fishino. Tramite un amplificatore operazionale (IC2A) in configurazione buffer la cui uscita è connessa al pin D2, Fishino è in grado di capire se viene alimentato dalla batteria o da un’alimentazione esterna e può, se necessario, spegnere i tre optoisolatori precedentemente descritti, al fine di evitare flussi di corrente tra la batteria e l’alimentazione esterna, rimanendo comunque acceso in quanto alimentato da una sorgente esterna.

Nel loop Fishino si occupa di controllare lo stato di carica della batteria, leggendo la tensione sul pin A5 e nel caso in cui fosse necessario abilita l’optoisolatore OK2 collegando l’alimentazione esterna alla batteria al fine di ricaricarla; in tal caso quando su A5 legge una tensione superiore ad una certa soglia ritiene la batteria carica e torna ad isolarla dal resto del circuito spegnendo OK2.

Per quanto riguarda la ricarica della batteria, trattandosi di batteria LiPo, ci sembra doveroso spendere due parole sul processo di ricarica. Le Lipo, infatti, sono batterie che se non trattate bene, possono diventare pericolose o nei peggiori dei casi esplodere. La strategia migliore per ricaricare una LiPo evitando di danneggiarla è quella di  fornirle una corrente di ricarica via via più bassa man mano che si ricarica, e quando quest’ultima scende al di sotto del 5% della carica nominale della batteria, concludere la ricarica. Normalmente a questo scopo viene utilizzata una resistenza detta di shunt in serie alla batteria e viene misurata la tensione ai capi di quest’ultima in modo da misurare l’attuale corrente di ricarica. In questo progetto, viste le basse correnti in gioco, abbiamo deciso di utilizzare una strategia di ricarica leggermente differente, introducendo una resistenza tra l’optoisolatore e la batteria, utilizzandola come una sorta di limitatore di corrente. In questo modo avremo una corrente di ricarica molto bassa e quindi un tempo di ricarica un po’ più lungo ma potremmo controllare lo stato della batteria direttamente sul pin A5 oltre a correre meno rischi durante la ricarica ed aumentare la vita media della batteria.

Nello schematico tale resistenza (R18) è un trimmer del valore massimo di 100 ohm, abbiamo utilizzato un trimmer in modo da permettere all’utente una taratura più fine delle correnti desiderate oltre a compensare un po’ la resistenza equivalente dell’optoisolatore. Nel nostro caso ad esempio abbiamo utilizzato una batteria di 240 mAh e volendo fissare una corrente massima di ricarica di 70 mA abbiamo utilizzato una resistenza di circa 50 ohm; considerando una resistenza interna dell’optoisolatore di 16 circa ohm, abbiamo pertanto impostato il trimmer a circa 30 ohm.


Firmware

Come detto, Fishino si occupa della gestione della rete, dei tasti, del display e della batteria, pertanto nel firmware troveremo tutte le librerie e le variabili utili a questo scopo. Nel setup, una volta avviato, Fishino si occupa di fare tutti controlli sulle alimentazioni e nel caso in cui la batteria è carica o è presente un’alimentazione esterna, connette Fishino alla rete, inizializzando infine il display.

Successivamente Fishino entra nel loop, dove di volta in volta vengono dapprima effettuati tutti i controlli sulle alimentazioni, poi i controlli sui tasti ed infine inviati, ove necessario, i dati alla raspberry e stampate le informazioni sul display.

Per quanto riguarda il controllo delle alimentazioni, Fishino controlla la presenza di alimentazioni esterne (value_ext), poi lo stato della batteria (value_bat) e di conseguenza decide se spegnere o meno il dispositivo, se è necessario ricaricare la batteria o cessare l’eventuale ricarica in corso di quest’ultima tramite opportuni flag (flag_ext, flag_bat).

La procedura di check per la verifica dei tasti premuti è molto semplice, di volta in volta Fishino controlla i pin connessi ai tasti fisici e nel caso di pressione di questi assegna ad una variabile (j_key) dei valori in funzione del tasto premuto mentre con un’altra variabile (key_num) conta quanti tasti sono stati premuti.

Successivamente invia alla raspberry dei pacchetti, uno per ogni tasto, in accordo alla convezione stabilita all’interno del fishino server su raspberry.
Infine Fishino gestisce il display, indicando su quest’ultimo il livello di carica della batteria e i tasti eventualmente premuti dall’utente.

Software
Oltre agli aspetti hardware, è stato necessario implementare un software scritto in C su Raspberry, che va eseguito in background, parallelamente alla console Retropie, al fine di far comunicare Fishino con la Raspberry.
Il programma non è nient’altro che un mini-server che riceve gli eventi legati alla pressione di un tasto sul joypad e li reindirizza verso la console. Il concetto base del server è quello di stabilire un collegamento wireless (tramite la connessione ad una rete comune) con il joypad e di replicare sulla console gli stessi eventi software che vengono normalmente generati quando si preme un qualsiasi tasto su una tastiera connessa alla raspberry, ovvero, come se si disponesse di una tastiera virtuale wireless. Riassumendo i passaggi principali e le funzioni chiave del software sono:

  1. Viene creato un socket, ovvero una porta per una connessione verso l’esterno, per una comunicazione dati di tipo UDP, meno affidabile di una connessione TCP dal punto di vista della perdita dei pacchetti di dati, ma più veloce e più indicata per applicazioni di questo genere, nelle quali è richiesta una prontezza di risposta elevata. Server e Client sono due strutture dati di tipo sockaddr_in definite nelle librerie standard di UNIX.
    int socket_desc = socket(AF_INET , SOCK_DGRAM , 0);
    struct sockaddr_in server , client;
  2. In seguito alla creazione del socket, è necessario aprire una porta software (noi abbiamo scelto convenzionalmente la 8888), sulla quale arriveranno i pacchetti dati dal joypad, e fare il binding di questa sul socket.
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons( 8888 ); 
    int yes = 1;
    setsockopt(socket_desc, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
    setsockopt(socket_desc, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(int)); 
    bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0);
  3. A questo punto, il server si deve mettere in attesa di una connessione da parte del joypad e nel momento in cui gli arriva una richiesta, la deve accettare e creare un nuovo dispositivo di tastiera virtuale.
    listen(socket_desc , 1);
    int client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c);
    setup_uinput_device();
  4. Fino a quando il joypad è connesso, il server resta in attesa di ricevere e gestire tutte le richieste di pressione dei tasti. La ricezione del pacchetto dati è svolta dalla funzione recv(), che memorizza il tasto ricevuto nella stringa client_message, mentre la funzione send_key() riconosce il tasto e genera gli eventi tastiera corrispondenti.
    while (connected && (read_size = recv(client_sock, client_message, 2, MSG_WAITALL) > 0)){ send_key(&client_message);}
  5. Funzione setup_uinput_device(): la funzione crea un dispositivo virtuale che, come ogni altro dispositivo sui sistemi UNIX, è identificato da un file di sistema. Anche il joypad sarà legato ad un file (‘/dev/uinput’ per la nostra applicazione) e diviene accessibile nel software tramite il descrittore di file uinp_fd. Dopo la creazione del file, che avviene tramite l’istruzione
    uinp_fd = open("/dev/uinput", O_WRONLY | O_NDELAY);

    vengono associati al joypad un nome e le proprietà di gestione degli eventi di tipo tastiera, in modo che la Raspberry sia in grado di emulare correttamente un dispositivo di input.

     

    strncpy(uinp.name, "Fishino Joystick", UINPUT_MAX_NAME_SIZE);
    uinp.id.version = 4;
    uinp.id.bustype = BUS_USB; 
    // Setup the uinput device
    ioctl(uinp_fd, UI_SET_EVBIT, EV_MSC);
    ioctl(uinp_fd, UI_SET_EVBIT, EV_KEY);
    ioctl(uinp_fd, UI_SET_EVBIT, EV_REL);
    ioctl(uinp_fd, UI_SET_EVBIT, EV_REP);
    for (i=0; i < 256; i++) { ioctl(uinp_fd, UI_SET_KEYBIT, i); }
    ioctl(uinp_fd, UI_SET_MSCBIT, MSC_SCAN);

    Conseguentemente, queste proprietà vengono scritte sul descrittore e viene istanziato il dispositivo.

    write(uinp_fd, &uinp, sizeof(uinp));
    ioctl(uinp_fd, UI_DEV_CREATE);
  6. Funzione send_key(): la funzione genera gli eventi di input per Retropie ed i giochi. Ogni tasto premuto sul joypad Fishino viene mappato in un carattere diverso (come descritto sul firmware); a seconda del carattere riconosciuto, il server genera gli eventi di pressione, pressione prolungata e rilascio del tasto, scrivendo sul descrittore di file del dispositivo virtuale creato il tipo di evento, la codifica che identifica ciascun tasto e il valore che identifica l’azione associata.

    event.type = EV_KEY;
    event.code = code;
    event.value = 1;
    write(uinp_fd, &event, sizeof(event));
    

    La struttura event è di tipo input_event, EV_KEY indica che il tipo di evento è legato ad un tasto della tastiera, il codice è proprio del tasto (es. KEY_A per il tasto ‘A’) e il campo value identifica l’azione associata (0 – rilascio del tasto, 1 – pressione del tasto, 2 – pressione prolungata).

Configurazione e utilizzo
Di seguito, si forniscono le istruzioni per compilare ed eseguire il server sul sistema Raspberry ed i passi da seguire per utilizzare il joypad Fishino.

  1.  Avviare la Raspberry con una tastiera USB e digitare F4 per uscire dalla console
  2. Caricare il file server_fishino.c s una cartella qualsiasi (es.in ‘/home/pi’) e compilare su Raspberry:
    – cd
    – gcc server_fishino.c –o server
  3. Aggiungere il programma server all’elenco delle attività da eseguire allo startup del sistema:
    –  sudo nano /etc/rc.local
    – aggiungere alla fine del file la seguente riga:
    sudo /home/pi/server &
    – uscire dall’editor di testo, digitando CTRL+X e Y per salvare le modifiche
  4. Digitare sul terminale ‘emulationstation’ per far ripartire l’emulatore, dopodiché collegarsi ad una rete wifi a disposizione e prendere nota dell’indirizzo IP assegnato alla Raspberry.
  5. Riavviare la Raspberry (ancora F4, poi digitare ‘sudo reboot’). Al riavvio il server del joypad partirà in automatico.
  6. Configurare il joypad, programmando Fishino con le informazioni relative alla rete wifi e l’ip acquisito da Retropie, in modo che questo si connetta al server presente sulla Raspberry.
  7. Una volta avviata la console Retropie (e solo allora) accendere il joypad Fishino, che si connetterà automaticamente alla rete WiFi e quindi al server di Retropie.
  8. Al primo utilizzo potrebbe essere necessaria una configurazione dei tasti. E’ possibile, utilizzando una tastiera reale, avviare l’utility preposta su Retropie, navigando sul menu e scegliendo l’opzione ‘Configure Input’. Da questo menù è possibile assegnare ogni tasto del joypad.
  9. Una volta terminata la configurazione, il joypad è pronto per l’utilizzo e l’utente può quindi utilizzarlo per navigare nei menù e giocare.

 

CAD
Come accennato, ad eccezione delle parti elettroniche, tutti i componenti del joypad sono stati stampati in 3D, nello specifico ci siamo occupati di dimensionare il case esterno (composto da un top ed un bottom) e di creare i relativi tasti, che nel caso specifico sono stati accomunati in cinque pezzi diversi (uno per le frecce, uno per i tasti di start-select, due per i tasti funzione ed uno per il tasto di accensione), nella figura viene mostrato il modello 3D del joypad completo

Fig. 4 CAD del Joypad

Fig. 4 CAD del Joypad

Conclusioni
In conclusione, grazie a Fishino siamo riusciti ad aggiungere un prezioso device ad un progetto che a nostro parere merita di essere provato e costruito. In questa sede ci siamo occupati di replicare un semplice joypad ma si capisce benissimo che la potenza e la semplicità d’utilizzo di Fishino permette ad un qualsiasi utente di sbizzarrirsi creando joypad via via più complicati o più performanti per determinati giochi. Ad esempio si potrebbero inserire sul joypad degli accelerometri ed associare i tasti ai movimenti del joypad, si potrebbero inserire dei sensori di forza in modo da calibrare determinati comandi di gioco in funzione della forza che l’utente esercita sul tasto, si potrebbe usare un microfono in modo da aggiungere comandi vocali ect.. Insomma chi più ne ha più ne metta, l’hardware ha tutte le potenzialità, ora tocca all’utente metterci la fantasia.

Fig. 5 Dispositivo Realizzato

Fig. 5 Dispositivo Realizzato

Download
Clicca qui per scaricare il software e il firmware del progetto

5 Commenti

  1. Il 50° voto, onorato. un valido ed insostituibile aiuto per le sere fredde e piovose. Retropie, Fishino Joypad, 10 litri di frizzantella e una cassetta dei rush a tutto volume. e si va a comandare.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.

Main Menu