Joypad OSC ESP8266 ti permette di leggere come realizzare il tuo joypad paresonalizzato con la feather huzzah esp8622 dell’adafruit.
Se hai già letto i miei precedenti articoli dedicati a questo micro controllore sai già che unendo la feather huzzah al joywing puoi ottenere un joypad:
ciò che per la prima volta descrivo in questo articolo è la possibilità di trasferire via WiFi i dati al computer.
Userai quindi l’ESP8266 wifi per collegarti alla tua rete di casa ed inviare le informazioni raccolte dal joypad.
Come protocollo di comunicazione userai l’OSC ( Open Sound Control ) un protocollo molto inteerssante che ho usato in passato con l’iPhone ed i led;
Joypad OSC ESP8266 come funzona
Il protocollo OSC è, innanzitutto, open ed anche se nato per il controllo in ambito musicale mediante rete, network, è stato adottato anche in altri ambiti di controllo.
Lascio che tu possa approfondire le conoscenze su questo protocollo sui siti dedicati.
Per adesso è importante che tu sappia che si tratta di un protocollo di tipo “pattern matching” fondato su UDP.
L’UDP per sua natura non prevede la possibilità di conoscere se il “messaggio” sia andato a buon fine, diciamo che l’invio del messaggio è tale da potersi perdere.
Questo comportamento dovrai considerarlo attentamente quando realizzerai il sistema controllato in modo da evitare errori di manovra.
Lo sketch Joypad OSC ESP8266
Ho diviso il progetto in due articoli per rendere più chiara e semplice la trattazione.
Puoi trovare lo sketch sul mio gitHub insieme a molte immagini e disegni 3D per realizzare questo progetto.
In questa prima parte ci concentriamo sulla parte che carichi sul micro controllore Joypad OSC ESP8266 feather huzzah:
#include <ESP8266WiFi.h> #include <WiFiUdp.h> #include <OSCBundle.h> #include "Adafruit_seesaw.h" Adafruit_seesaw ss; #define BUTTON_RIGHT 6 #define BUTTON_DOWN 7 #define BUTTON_LEFT 9 #define BUTTON_UP 10 #define BUTTON_SEL 14 uint32_t button_mask = (1 << BUTTON_RIGHT) | (1 << BUTTON_DOWN) | (1 << BUTTON_LEFT) | (1 << BUTTON_UP) | (1 << BUTTON_SEL); #define IRQ_PIN 2 char ssid[] = "il tuo SSID"; // your network SSID (name) char pass[] = "la tua Password"; // your network password WiFiUDP Udp; const IPAddress outIp(192,168,2,19); // remote IP of your computer const unsigned int outPort = 9001; // remote port to receive OSC const unsigned int localPort = 8001; // local port to listen OSC int last_x = 0, last_y = 0; void setup() { Serial.begin(115200); // Connect to WiFi network Serial.println(); Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); WiFi.begin(ssid, pass); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); Serial.println("Starting UDP"); Udp.begin(localPort); Serial.print("Local port: "); Serial.println(Udp.localPort()); if(!ss.begin(0x49)){ Serial.println("ERROR!"); while(1); } else{ Serial.println("seesaw started"); Serial.print("version: "); Serial.println(ss.getVersion(), HEX); } ss.pinModeBulk(button_mask, INPUT_PULLUP); ss.setGPIOInterrupts(button_mask, 1); pinMode(IRQ_PIN, INPUT); } void loop() { int x = ss.analogRead(2); int y = ss.analogRead(3); if ( (abs(x - last_x) > 3) || (abs(y - last_y) > 3)) { Serial.print(x); Serial.print(" "); Serial.print(y); Serial.print(" "); last_x = x; last_y = y; } else { Serial.print(last_x); Serial.print(" "); Serial.print(last_y); Serial.print(" "); } uint32_t buttons = ss.digitalReadBulk(button_mask); uint16_t bTop = 0; uint16_t bDown = 0; uint16_t bRight = 0; uint16_t bLeft = 0; uint16_t bSelect = 0; if (! (buttons & (1 << BUTTON_RIGHT))) { bRight = 1023; } Serial.print( bRight ); Serial.print(" "); if (! (buttons & (1 << BUTTON_DOWN))) { bDown = 1023; } Serial.print( bDown ); Serial.print(" "); if (! (buttons & (1 << BUTTON_LEFT))) { bLeft = 1023; } Serial.print( bLeft ); Serial.print(" "); if (! (buttons & (1 << BUTTON_UP))) { bTop = 1023; } Serial.print( bTop ); Serial.print(" "); if (! (buttons & (1 << BUTTON_SEL))) { bSelect = 1023; } Serial.print( bSelect ); Serial.println(" "); OSCBundle bndl; bndl.add("/analog/0").add((int32_t)last_x); bndl.add("/analog/1").add((int32_t)last_y); bndl.add("/button/top").add((uint16_t)bTop); bndl.add("/button/down").add((uint16_t)bDown); bndl.add("/button/right").add((uint16_t)bRight); bndl.add("/button/left").add((uint16_t)bLeft); bndl.add("/button/select").add((uint16_t)bSelect); Udp.beginPacket(outIp, outPort); bndl.send(Udp); Udp.endPacket(); bndl.empty(); delay(10); }
la linea 001: includi la libreria di gestione della connessione WiFi per la ESP8266;
linee 002-003: includi le librerie che servono a semplificare la comunicazione OSC e l’utilizzo di questo protocollo;
linea 004: includi la libreria Adafruit seesaw con cui ti interfacci al joywing;
linea 006: istanzia l’oggetto “ss” della libreria Adafruit_seesaw;
linee 008-014: imposta i define per leggere i pulsanti della joywing;
linea 016: definisci il pin che usi come interrupt tra la ESP8266 huzzah e la Joy-Featherwing:
linee 018-019: imposta i parametri SSID e password di connessione alla tua wifi;
linea 021: inizializza l’istanza Udp della classe WiFiUDP con cui potrai utilizzare la comunicazione Udp;
linee 022-024: definisci l’Ip a cui dovrai inviare le comunicazioni OSC e le porte di comunicazione in output ed in input;
linea 025: imposta a 0 i due valori relativi alle coordinate x ed y raccolte;
linee 031-045: imposta la connessione WiFi e scrive sul monitor seriale i dati raccolti durante la connessione WiFi;
linee 047-050: imposta la comunicazione UDP sulla porta “localport” e controlla, scrivendo sul monitor seriale, il valore della porta su cui è in ascolto localmente;
linee 052-060: imposta la comunicazione con il joywing sull’indirizzo I2C 0x49, default;
linea 061: imposta il PULL_UP per la maschera di lettura dei bottoni;
linea 062: imposta il GPIO interrupt;
linea 063: imposta il pinMode INPUT per il pin di interrupt;
linee 067-068: leggi i valori per X ed Y dalla seesaw mediante l’istanza ss;
linea 070: valuta se la differenza tra la lettura della posizione di X o di Y e la precedente lettura è superiore a 3, in tal caso esegui le linee successive 071-074, in alternativa esegui le linee 076-077;
linee 071-074: scrivi sul monitor seriale i valori di X ed Y e imposta i rispettive last_ con i valori correnti per la valutazione dell’if alla linea 070 al prossimo ciclo di loop();
linee 076-077: scrivi sul monitor seriale solo i valori last_x o last_y presenti;
linea 080: leggi i valori dei pulsanti della Joypad OSC ESP8266 joywing;
linee 081-085: imposta a 0 cinque variabili relative ai cinque pulsanti presenti sul joypad;
linea 087: se il pulsante right è stato premuto imposta la variabile bRight a 1023;
linea 088: scrivi sul monitor seriale il valore della variabile bRight seguito da uno spazio;
linee 090-100: esegui le stesse verifiche per tutti i pulsanti restanti: bDown, bLeft, bTop e bSelect;
linea 102: imposta l’istanza della classe OSC definendola come bndl;
linea 103: usando il metodo add della libraria OSC aggiungi al path “/analog/0” il valore di last_x;
linee 104-110: aggiungi all’oggetto bndl i valori per i restanti pulsanti e coordinate;
linea 112: imposta un pacchetto Udp verso l’IP remoto e la porta remota, su cui avrai in ascolto processing;
linea 113: usando il metodo send della libreria bndl puoi inviare i valori impostati via OSC ed Udp;
linea 114: concludi la trasmissione UDP con il metodo end;
linea 115: svuota l’oggetto bndl per prepararlo a raccogliere i dati del prossimo ciclo di loop();
linea 117: attendi 10 millisecondi prima di concludere il ciclo di loop corrente.
Eseguzione del codice
Trasferisci il codice alla Joypad OSC ESP8266 alla feather huzzah ed apri il monitor seriale, vedrai prima la parte di connessione WiFi:
e successivamente scorrer i valori relativi alle coordinate del joystick e dei pulsanti che restano a 0 se non premuti:
Nei prossimi articoli ci concentreremo sull’interfaccia in processing lato Pc/Mac per ricevere e visualizzare i dati trasmessi nella forma che vedi nella finestra nera.