Il Joypad OSC Processing è la componente del progetto joypad che ti permette di ricevere i messaggio OSC e visualizzarli su processing.
La realizzazione di un joypad con la feather huzzah esp8266 è iniziato alcuni mesi fa e, tra i vari progetti che sto realizzando, è di discreta complessità.
Lo scorso articolo hai letto come programmare la parte di micro controllore perché invii i valori del joystick e dei pulsanti della joywing via Udp e OSC in bundle.
L’invio dei messaggi puoi visualizzarlo in diversi modi tra cui Processing.
Processing ti permette di realizzare una interfaccia grafica con cui visualizzare non solo i valori inviati per ciascun canale ma la rappresentazione del joypad sullo schermo:
Il Joypad OSC Processing
Il Joypad OSC Processing, come vedi nella figura sopra, riproduce le sembianze della joyfeathering adafruit graficamente in una finestra 700 x 300 pixel circa.
Nella parte inferiore del joypad virtuale trovi anche i valori che il joypad reale ti trasferisce e che ti servono per verificare la corrispondenza con quanto visualizzato, sopratutto nelle fasi iniziali del processo.
Nel paragrafo dedicato allo sketch processing leggi come sia possibile realizzare una interfaccia come quella che stai vedendo.
Il funzionamento della componente processing è molto semplice:
- all’avvio dello sketch si mette in ascolto sulla porta 9001, impostata come remota per la parte di trasmissione lato Arduino IDE ( vedi articolo di lunedì );
- crea quindi la rappresentazione grafica che hai visto in figura;
- attende i dati dal client OSC per visualizzarli;
quando muovi il joystick si sposta il quadratino bianco nella sua area e quando premi uno dei pulsanti a scelta tra:
- SELECT
- RIGHT
- TOP
- LEFT
- DOWN
il corrispondente pallino passa da rosso a bianco.
Warning!
Se premi il pulsante RESET della joywing ottieni il reset fisico del client, della feather huzzah esp8266, e dovrai attendere che riparta ed esegua nuovamente la connessione 🙂
Lo sketch in processing
Come descritto sopra lo sketch non è complesso ma richiede non solo conoscenze di programmazione standard, per la parte OSC, anche un minimo di competenze di disegno da utilizzare con le funzioni draw per la costruzione dell’interfaccia stessa:
/* Receives and visualizes OSCBundles sent over UDP Use with /examples/UDPSendBundle or with /examples/SerialSendBundle in conjunction with /Applicaitons/Processing/SLIPSerialToUDP */ import oscP5.*; import netP5.*; OscP5 oscP5; int mouseStepX = 516; int mouseStepY = 525; int buttonTop = 0; int buttonLeft = 0; int buttonRight = 0; int buttonDown = 0; int buttonSelect = 0; int buttonReset = 0; void setup() { size(700,300); frameRate(30); //set this to the receiving port oscP5 = new OscP5(this,9001); } void draw() { background(0); /************* Text ************************************************/ textSize(12); text("analog0:", 50, 270); text(mouseStepX, 150, 270); text("analog1:", 50, 280); text(mouseStepY, 150, 280); text("Select:", 275, 260); text(buttonSelect, 350, 260); text("Reset: ", 275, 270); text(buttonReset, 350, 270); text("ButtonTop:", 500, 260); text(buttonTop, 600, 260); text("ButtonLeft:", 500, 270); text(buttonLeft, 600, 270); text("ButtonRigh:", 500, 280); text(buttonRight, 600, 280); text("ButtonDown:", 500, 290); text(buttonDown, 600, 290); /************* Graph ***********************************************/ noFill(); stroke(255); rect(50, 20, 200, 200); fill(255); float mouseXPos = map(mouseStepX, 0, 1023, 50, 230); float mouseYPos = map(mouseStepY, 0, 1023, 20, 200); rect(mouseXPos, mouseYPos, 20, 20); /************* Button Right ****************************************/ if ( buttonTop == 0 ) fill(255,0,0); else fill(255); ellipse(600, 75, 30, 30); if ( buttonRight == 0 ) fill(255,0,0); else fill(255); ellipse(650, 125, 30, 30); if ( buttonLeft == 0 ) fill(255,0,0); else fill(255); ellipse(550, 125, 30, 30); if ( buttonDown == 0 ) fill(255,0,0); else fill(255); ellipse(600, 175, 30, 30); /************* Button Left ****************************************/ if ( buttonSelect == 0 ) fill(255,0,0); else fill(255); ellipse(350, 50, 30, 30); if ( buttonReset == 0 ) fill(255,0,0); else fill(255); ellipse(350, 135, 30, 30); fill(255); } // incoming osc message are forwarded to the oscEvent method. void oscEvent(OscMessage theOscMessage) { //println(theOscMessage.addrPattern()); if (theOscMessage.addrPattern().equals("/analog/1")){ mouseStepX = theOscMessage.get(0).intValue(); } else if(theOscMessage.addrPattern().equals("/analog/0")){ mouseStepY = theOscMessage.get(0).intValue(); } else if(theOscMessage.addrPattern().equals("/button/top")){ buttonTop = theOscMessage.get(0).intValue(); } else if(theOscMessage.addrPattern().equals("/button/left")){ buttonLeft = theOscMessage.get(0).intValue(); } else if(theOscMessage.addrPattern().equals("/button/right")){ buttonRight = theOscMessage.get(0).intValue(); } else if(theOscMessage.addrPattern().equals("/button/down")){ buttonDown = theOscMessage.get(0).intValue(); } else if(theOscMessage.addrPattern().equals("/button/select")){ buttonSelect = theOscMessage.get(0).intValue(); } else if(theOscMessage.addrPattern().equals("/button/reset")){ buttonReset = theOscMessage.get(0).intValue(); } }
Descrizione dello sketch processing
Le linee 10-11: includono le due librerie per la parte di comunicazione osc e network ( udp );
linea 13: inizializza l’istanza oscP5 con cui gestirai i messaggi provenienti su tale protocollo;
linee 15-24: imposta i valori di default per il joystick e per i bottoni dell’interfaccia;
linea 27: crea il box 700 x 300 pixel dell’interfaccia;
linea 28: imposta il framerate di refresh a 30;
linea 30: avvia l’interfaccia di comunicazione sulla rete locale e porta 9001;
linea 34: ad ogni loop(), che in processing è scandito dalla funzione draw(), imposta il background nero per l’interfaccia;
linea 37: imposta il font ad una dimensione di 12;
linee 38-47: scrivi per ciascuna linea la label da visualizzare, ad esempio “analog0” ed il corrispondente valore “mouseStepX” nelle posizioni in basso all’interfaccia joypad;
linee 50-52: crea il rettangolo 200 x 200 partendo dall’angolo 50,50, vuoto e con la cornice bianca;
linea 54: imposta il riempimento bianco;
linea 55: imposta ed assegna la variabile mouseXPos mappandone il valore da mouseStepX nel range 0,1023 su 50,230;
linea 56: imposta anche la variabile mouseYPos come per la X ma su mouseStepY e valori 20,200;
linea 57: crea un rettangolo nella posizione mouseXPos, mouseYPos della dimensione 20x20pixel;
linee 60-73: per ciascun pulsante ( top, right, left, down, select, reset ) disegna il corrispondente cerchio rosso: fill(255,0,0) se il valore è “0” e bianco: fill(255) se il valore è diverso da “0”;
linea 75: prima di chiudere il draw reimposta a 255 il valore di fill: riempimento;
linea 79: la funzione oscEvent verrà invocata ogni volta che un nuovo messaggio arriva via OSC;
linea 81: se il messaggio contiene “/analog/1” procede ad impostare il valore di mouseStepX usando il metodo get sulla posizione 0 del messaggio;
linee 83-97: eseguono l’aggiornamento dei valori corrispondenti alla coordinata Y ed ai pulsanti;
In questo modo il joypad virtuale è in grado di visualizzarti tutti gli stadi del joystick e dei corrispondenti pulsanti;
Avrai notato che tra i pulsnati di cui si attende il valore c’è anche il reset, il motivo è che quando ho disegnato l’interfaccia ero all’oscuro del fatto che il pulsante di reset sulla joywing fosse connesso al RESET del micro controllore.
Nell’interfaccia l’ho lasciato anche dopo il test perché potrei utilizzarlo in un futuro per implementare un controllo di reset con un pulsante esterno, connesso ad uno dei pin digitali della feather huzzah esp8266.
Come sai tutto il progetto è condiviso sul mio gitHub/Mauroalfieri/joy-featherwing.
Il video del test del Joypad OSC Processing
Il video che ho ripreso durante il primo test del joypad OSC processing:
ti mostra come sia alquanto fedele la riproduzione dei movimenti sulla Joypad OSC Processing feather joywing.