Arduino, OSC, iPhone e sei led – lo sketch

Come promesso ho realizzato lo sketch che caricato su Arduino ti permette di realizzare il tuo controllo via iPhone dei 6 led o 6 carichi collegati alle uscite 2,3,4,5,6 e 7.

Arduino, TouchOSC e slide digitali PWM

Solo i pin 3,5 e 6 sono di tipo PWM e quindi potranno pilotare il dimmer dei led.

Passa subito allo sketck:

#include "Ethernet.h"
#include "OSCClass.h"
#include "SPI.h"

int pinLedA=2;
int pinLedB=3;
int pinLedC=4;
int pinLedD=5;
int pinLedE=6;
int pinLedF=7;

OSCMessage recMes;

OSCClass osc(&recMes);

byte serverMac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte serverIp[]  = { 192, 168, 2, 130 };
int  serverPort  = 10000;

char *topAddress="butt";
char *subAddress[15]={ "ledA" , "ledB" , "ledC", "ledD" , "ledE" , "ledF", "ledAB" , "ledBC" , "ledAC", "ledDE" , "ledEF" , "ledDF", "fadeB" , "fadeD" , "fadeE" };

void setup() {
     Ethernet.begin(serverMac ,serverIp);
     osc.begin(serverPort);

     pinMode(pinLedA, OUTPUT);
     pinMode(pinLedB, OUTPUT);
     pinMode(pinLedC, OUTPUT);
     pinMode(pinLedD, OUTPUT);
     pinMode(pinLedE, OUTPUT);
     pinMode(pinLedF, OUTPUT);

     digitalWrite(pinLedA, LOW);  //LED OFF
     digitalWrite(pinLedB, LOW);  //LED OFF
     digitalWrite(pinLedC, LOW);  //LED OFF
     digitalWrite(pinLedD, LOW);  //LED OFF
     digitalWrite(pinLedE, LOW);  //LED OFF
     digitalWrite(pinLedF, LOW);  //LED OFF

     osc.flush();
}

void loop() {
    if ( osc.available() ) {
          if( !strcmp( recMes.getAddress(0) , topAddress ) ){
                if( !strcmp( recMes.getAddress(1) , subAddress[0] ) )  { digitalWrite(pinLedA, getIntValue(&recMes)); }
                if( !strcmp( recMes.getAddress(1) , subAddress[1] ) )  { digitalWrite(pinLedB, getIntValue(&recMes)); }
                if( !strcmp( recMes.getAddress(1) , subAddress[2] ) )  { digitalWrite(pinLedC, getIntValue(&recMes)); }
                if( !strcmp( recMes.getAddress(1) , subAddress[3] ) )  { digitalWrite(pinLedD, getIntValue(&recMes)); }
                if( !strcmp( recMes.getAddress(1) , subAddress[4] ) )  { digitalWrite(pinLedE, getIntValue(&recMes)); }
                if( !strcmp( recMes.getAddress(1) , subAddress[5] ) )  { digitalWrite(pinLedF, getIntValue(&recMes)); }

                if( !strcmp( recMes.getAddress(1) , subAddress[6] ) )  { digitalWrite(pinLedA, getIntValue(&recMes)); digitalWrite(pinLedB, getIntValue(&recMes)); }
                if( !strcmp( recMes.getAddress(1) , subAddress[7] ) )  { digitalWrite(pinLedB, getIntValue(&recMes)); digitalWrite(pinLedC, getIntValue(&recMes)); }
                if( !strcmp( recMes.getAddress(1) , subAddress[8] ) )  { digitalWrite(pinLedA, getIntValue(&recMes)); digitalWrite(pinLedC, getIntValue(&recMes)); }
                if( !strcmp( recMes.getAddress(1) , subAddress[9] ) )  { digitalWrite(pinLedD, getIntValue(&recMes)); digitalWrite(pinLedE, getIntValue(&recMes)); }
                if( !strcmp( recMes.getAddress(1) , subAddress[10] ) ) { digitalWrite(pinLedE, getIntValue(&recMes)); digitalWrite(pinLedF, getIntValue(&recMes)); }
                if( !strcmp( recMes.getAddress(1) , subAddress[11] ) ) { digitalWrite(pinLedD, getIntValue(&recMes)); digitalWrite(pinLedF, getIntValue(&recMes)); }

                if( !strcmp( recMes.getAddress(1) , subAddress[12] ) )  { analogWrite(pinLedB, getIntValue(&recMes)); }
                if( !strcmp( recMes.getAddress(1) , subAddress[13] ) )  { analogWrite(pinLedD, getIntValue(&recMes)); }
                if( !strcmp( recMes.getAddress(1) , subAddress[14] ) )  { analogWrite(pinLedE, getIntValue(&recMes)); }

        }
    }
}

// *********  utility  ***********************************

int getIntValue(OSCMessage *mes){
    switch( mes->getTypeTag(0) ){
        case 'i': { return mes->getArgInt(0); }
        break;

        case 'f':  { return int(mes->getArgFloat(0)); }
        break;
      }
}

Nelle prime righe includi le classi che utilizzerai per la comunicazione Ethernet e la gestione del protocollo OSC, l’utilizzo delle classi in Arduino ti permette di concentrarti sopratutto sulle funzionalità non preoccupandoti degli aspetti complessi come ad esempio di un protocollo.

le linee 05-10: definisci i pin a cui colleghi i led, ricorda che i pin 10,11,12 e 13 sono dedicati alla comunicazione con la Ethernet Shield;

linea 12: imposta la costante recMes in cui sono memorizzati tutti i messaggio di tipo OSC inviati dallo smartphone;

linea 14: inizalizza un oggetto osc come istanza della classe omonima;

linee 16-18: sono oramai linee note, imposta i parametri per la shield ethernet;

linea 20: imposta una variabile di tipo char il cui valore è la radice del messagio OSC, come avrai letto nei precedenti articoli le etichette OSC sono composte da percorsi simili ad un path o url internet, sono composti da livelli il cui primo è “/” ( root o radice ), i messaggio che hai impostato nell’interfaccia OSC sono del tipo /butt/ledA in cui butt è l’indirizzo più alto del messagio e ledA il sotto-indirizzo;

linea 21: imposta i sotto-indirizzi che ti aspetti: ledA,ledB,ledC …

linea 24: inizializza la classe Ethernet con Mac e IP definiti alle linee 16-18;

linea 25: crea un server di ripo OSC che risopnde sulla porta definita alla linea 18;

linee 27-32: definisci la modalità di OUTPUT per i 6 pin a cui sono connessi i led;

linee 34-39: imposta a LOW il valore di ciscun pin in modo che all’accensione tutti i led siano spenti;

linea 41: pulisci il buffer dei messaggi dell’istanza osc usando il metodo flush della classe OSC;

linea 45: verifica che ad ogni loop() di arduino esista un messaggio di tipo osc, questo tipo di comando è molto simile a quello utilizato nella comunicazione seriale di arduino;

linea 46: leggi il valore contenuto a livello puù alto di recMes utilizzando il metodo getAddress(0) dove 0 è il primo livello, confronta questo valore con il valore definito in topAddress alla linea 20 e se corrisponde vuol dire che il messagio è quello atteso, potresti definire più tipi di messaggi e gestirli in modo differente lato sketch, ho preferito usare sempre lo stesso indirizzo primario per rendere lo sketch più semplice;

linee 47-52: sono tutte simili ad eccezione del test eseguito, prendi in esame la linea 47 confronta il valore al livello 1 del recMes con il valore dell’array subAddress alla posizione 0, questo indica che la condizione è verificata quando l’indirizzo o etichetta proveniente dal tuo smartphone è /butt/ledA, in questo caso assegna il valore ricevuto: 0 o 1 in funzione della pressione o meno del bottone; l’assegnazione del valore la fai con il comando digitalWrite di Arduino ed il vaore lo recuperi con la funzione getIntValue dichiarata alle linee 71-79;

linee 54-59: identiche alle precedenti a meno del fatto che gestiscono i pulsanti in verde ( vedi articolo sull’interfaccia OSC ) i quali sono combinazioni di led, per cui ogni comando accende insieme 2 led, le combinazioni sono un esempio e puoi variarle come vuoi ottenendo combinazioni ben più complesse.

linee 61-63: ti servono per gestire i messaggi di tipo fade o slide, quelli applicati ai pin 3,5 e 6 per pilotare in dissolvenza i led, in linea di principio non sono differenti dalle precedenti a meno del valore di confronto nella condizione di IF e del comando utilizzato per accendere i led in dissolvenza analogWrite al posto del digitalWrite;

linee 71-79: definisci una funzione di servizio o utility accessoria allo sketch, in pratica i valori provenienti dai messaggi OSC possono essere di tipo integer ( intero ) o float ( con la virgola ) nel primo caso vanno recuperati con il metodo getArgInt() nel secondo con il metodo getArgFloat(). Tuttavia nello sketch sono attesi e gestiti slo valori di tipo intero, per cui questa funzione verifica il tipo di valore ricevuto, lo recupera con il metodo corretto ed in caso di float lo trasforma in intero restituendo sempre un valore intero allo sketch.

Ed ecco un video del progetto in funzione:

Buon divertimento.

Prima di inserire un commento, per favore, leggi il regolamento

Permanent link to this article: https://www.mauroalfieri.it/elettronica/arduino-osc-iphone-e-sei-led-lo-sketch.html

Lascia un commento

Your email address will not be published.

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.