Aiuto per lettura valori RGB

Salve ragazzi,

ho realizzato un piccolissimo progetto con arduino, in pratica ho preso Processing e TouchOSC per far accendere e spegnere un led RGB con 4 pin.

Ho fatto in modo che alla pressione del tasto rosso si accende la luce rossa, e così anche per verde e blu.

Ora però vorrei anche regolare l'intensità, delle varie luci e lato processing ho fatto in questo modo

arduinoPort.write(11,intensitaLedRed[1]);

ra però non so come fare per prendere da arudino questi valori.

void loop(){
    if (Serial.available() > 0) { //  Check if there is a new message
      message = Serial.read();    //  Put the serial input into the message
   
   if (message == 'R'){  //  If a capitol R is received...
     redLED = 255;       //  Set redLED to 255 (on)
     analogWrite(redLEDPin, redLED);
   }else if (message == 'r'){  //  If a lowercase r is received...
     redLED = 0;         //  Set redLED to 0 (off)
     analogWrite(redLEDPin, redLED);
   }else if (message == 'G'){  //  If a lowercase r is received...
     greenLED = 255;         //  Set redLED to 0 (off)
     analogWrite(greenLEDPin, greenLED);
   }else if (message == 'g'){  //  If a lowercase r is received...
     greenLED = 0;         //  Set redLED to 0 (off)
     analogWrite(greenLEDPin, greenLED);
   }else if (message == 'B'){  //  If a lowercase r is received...
     blueLED = 255;         //  Set redLED to 0 (off)
     analogWrite(blueLEDPin, blueLED);
   }else if (message == 'b'){  //  If a lowercase r is received...
     blueLED = 0;         //  Set redLED to 0 (off)
     analogWrite(blueLEDPin, blueLED);
   }

io per leggere i valori faccio così

message = Serial.read();

però non so come prendere i due valori.

Attenfo vostre notizie

grazie.

in che senso non capisci come prendere i valori? la variabile message contiene i valori che vuoi.
poi fa la relativa logica sul messaggio letto.
allora fai Serial.println(message); lo leggi da processing con il serial read nativo e poi vari l'intensità del led scelto con la tua funzione :wink:

No allora forse non mi sono spiegato io. Anzi sicuramente è così.

Io ho un led rgb con 4 connettori. Attraverso uno schetc scritto in Processing invio dei comandi ad Arduino.

Come è possibile vedere lato arduino, se arriva una "G" spengo il led di colore verdo, se arriva una "g" accendo il led verde. Così anche per gli altri,

io però oltre a questo vorrei dirgli accendi il led verde però con intensità che va da 0 a 255 per esempio 100.

Ora resta da fare

Come faccio a dire tramite processing manda ad arduino di accendere il led verde con intensità 100???

Incollo il codice di Processing

import oscP5.*;        //  Load OSC P5 library
import netP5.*;        //  Load net P5 library
import processing.serial.*;    //  Load serial library
Serial arduinoPort;        //  Set arduinoPort as serial connection
OscP5 oscP5;            //  Set oscP5 as OSC connection

int led = 0;        //  redLED lets us know if the LED is on or off
int redLed=0;
int greenLed=0;
int blueLed=0;
int [] ledRed = new int [2];    //  Array allows us to add more toggle buttons in TouchOSC
int [] ledGreen = new int [2];
int [] ledBlue = new int [2];

int [] intensitaLedRed = new int [2];
void setup() {
  size(100,100);        // Processing screen size
  noStroke();            //  We don’t want an outline or Stroke on our graphics
    oscP5 = new OscP5(this,8000);  // Start oscP5, listening for incoming messages at port 8000
   arduinoPort = new Serial(this, Serial.list()[1], 9600);    // Set arduino to 9600 baud
}

void oscEvent(OscMessage theOscMessage) {   //  This runs whenever there is a new OSC message
    String addr = theOscMessage.addrPattern();  //  Creates a string out of the OSC message
    if(addr.indexOf("/1/toggle1") !=-1){   // Filters out any toggle buttons
      int i = int((addr.charAt(9) )) - 0x30;   // returns the ASCII number so convert into a real number by subtracting 0x30
       System.out.println(theOscMessage.get(0).floatValue());
      ledRed[1]  = int(theOscMessage.get(0).floatValue());     //  Puts button value into led[i] 
      redLed=1;
      greenLed=0;
      blueLed=0;
    }else if(addr.indexOf("/1/toggle2") !=-1){   // Filters out any toggle buttons
      int i = int((addr.charAt(9) )) - 0x30;   // returns the ASCII number so convert into a real number by subtracting 0x30
      System.out.println(theOscMessage.get(0).floatValue());
      ledGreen[1]  = int(theOscMessage.get(0).floatValue());     //  Puts button value into led[i] 
      redLed=0;
      greenLed=1;
      blueLed=0;
    }else if(addr.indexOf("/1/toggle3") !=-1){   // Filters out any toggle buttons
      int i = int((addr.charAt(9) )) - 0x30;   // returns the ASCII number so convert into a real number by subtracting 0x30
      System.out.println(theOscMessage.get(0).floatValue());
      ledBlue[1]  = int(theOscMessage.get(0).floatValue());     //  Puts button value into led[i] 
       redLed=0;
      greenLed=0;
      blueLed=1;
    }else if(addr.indexOf("/1/fader2") !=-1){   // Filters out any toggle buttons
      System.out.println("slider rosso premuto");
       int val = (int)theOscMessage.get(0).floatValue();
      System.out.println(val);
      intensitaLedRed[1]=val;

    }
}

void draw() {
 background(50);        // Sets the background to a dark grey, can be 0-255
   if(ledRed[1] == 0 && redLed==1){        //  If led button 1 if off do....
   // arduinoPort.write("r");    // Sends the character “r” to Arduino
    led = 0;        // Sets redLED color to 0, can be 0-255
  }else if(ledRed[1] == 1 && redLed==1){        // If led button 1 is ON do...
 //   arduinoPort.write("R");    // Send the character “R” to Arduino
    led = 255;        // Sets redLED color to 255, can be 0-255
  }else if(ledGreen[1] == 0 && greenLed==1){        //  If led button 1 if off do....
 //   arduinoPort.write("g");    // Sends the character “r” to Arduino
    led = 0;        // Sets redLED color to 0, can be 0-255
  }else if(ledGreen[1] == 1 && greenLed==1){        // If led button 1 is ON do...
//    arduinoPort.write("G");    // Send the character “R” to Arduino
    led = 255;        // Sets redLED color to 255, can be 0-255
  }else if(ledBlue[1] == 0 && blueLed==1){        //  If led button 1 if off do....
//    arduinoPort.write("b");    // Sends the character “r” to Arduino
    led = 0;        // Sets redLED color to 0, can be 0-255
  }else if(ledBlue[1] == 1 && blueLed==1){        // If led button 1 is ON do...
//    arduinoPort.write("B");    // Send the character “R” to Arduino
    led = 255;        // Sets redLED color to 255, can be 0-255
  }else if(intensitaLedRed[1] != 0){
    System.out.println(intensitaLedRed[1]);
    
  }
fill(led,0,0);            // Fill rectangle with redLED amount
   ellipse(50, 50, 50, 50);    // Created an ellipse at 50 pixels from the left...
                // 50 pixels from the top and a width of 50 and height of 50 pixels
}

Diciamo che quando arrivo qui

else if(addr.indexOf("/1/fader2") !=-1){ // Filters out any toggle buttons
System.out.println("slider rosso premuto");
int val = (int)theOscMessage.get(0).floatValue();
System.out.println(val);
intensitaLedRed[1]=val;

}

dovrei dirgli di accendere il pin 11 di aruino e di dargli una intensita x

come faccio?

Spero di essere stato chiaro

scusami avevo capito male io:
ti linko questo bellissimo tut che ho seguito agli inizi:

quindi da come avrai capito va modificatosia il codice processing che quello arduino
dovrai quindi inviare da procesing R + 100(l'intensità) e arduino dovrà fare un analogWrite(ledPin, ledVal);
prova a stendere una sorta di pseudo-codice(non so come te la cavi in programmazione) nel caso cerco di darti una mano io :wink:

Ciao allora il link che mi hai passato tu lo avevo visto .

Però quello che per il momento vorrei fare è inviare tramite processing appnto come dici tu R + un unmero......

Per non so poi lato arduino come fare per lavorare castare le stringhe ecc ecc

secondo me invece di mettere una variabile all'ascolto metti un vettore, e poi leggi finchè c'è qualcosa da leggere, dopo il if (Serial.available() > 0) ci metti un while(Serial.available() > 0) e ti leggi tutto quello che c'è da leggere quindi ad esempio 'R' lo metti nel primo slot del vettore e il numero nei successivi in quanto si legge una lettera/numero alla volta...così riesci a recuperare tutte le informazioni
per fare un esempio pratico questo è quello che avrai alla fine della lettura
vet[0] = 'R'
vet[1] = 2
vet[2] = 5
vet[3] = 5
se vuoi un aiuto su come ricostruire il numero dalle varie cifre guarda questo post di qualche settimana fa

Ciao ho provato a fare un pò come hai detto tu... posto un p di codice

while(Serial.available()>0){
        //ho riempito il vettore
        message = Serial.read();
        vet[cont] = message;
        cont++;
        delay(60);
      }
     if(cont>0){
      //so che il primo valore è una lettera che mi dice
      //quale led accendere
        message=vet[0];
        Serial.print("Lettera ");
        Serial.println(message);
        //ora bisogna costruire il valore.....
        for(int c=1; c<cont; c++){
          Serial.print("valore ");
          Serial.println(vet[c]);
          intensita= intensita+vet[c];
        }
        Serial.print("intensita ");
        Serial.println(intensita);
      }

allora innanzitutto ho visto e questo è ance giusto che se gli mando la lettera r ad arduino gli arriva il numero 114 credo sia il codice ASCII o qualcosa del genere.

nel ciclo for invece accade questo supponiamo che io gli mando la stringa r10 a lui arriva questo

r = 114
1 = valore 49
0 = valore 48
intensita= 339

ovviamente io sbaglio. come posso correggere?

si 114 è r in codice ascii

ti dico le cose che vedo così a un primo sguardo
il for secondo me non va bene perchè fa sempre lo stesso numero di cicli...visto che tu invii 1, 10 , 100 non deve fare sempre 3 cicli, andrebbe bene se tu inviassi 001, 010 ecc. chiaro?
quindi sostituirei il for con un while tipo

while(vet[c] != -2)

-2 è un valore che per certo non puoi aver letto in quanto tu leggi solo valori da 0 a 9 positivi con la serial.read, l'importante è che inizializzi il vettore con tutti gli slot a -2 chiaro?

poi non mi convince come hai calcolato l'intensità cioè secondo me dovrebbe essere

intensità = intensità * 10 + (vet[c]-48)

il -48 perchè devi trasformare da ascii a decimale
tutto chiaro???

se ho un attimo di tempo provo il tuo codice e vedo se riesco a correggerlo

Allora posto il mio codice rivisitato

int message = 0;     //  This will hold one byte of the serial message
int redLEDPin = 11;   //  What pin is the red LED connected to?
int greenLEDPin = 10; 
int blueLEDPin = 9; 
int numeroPin=0;
int cont=0;
long vet[9] = {-2, -2, -2, -2}; 
int intensita=0;
void setup() {  
  Serial.begin(9600);  //set serial to 9600 baud rate

}

void loop(){
    if (Serial.available() > 0) { //  Check if there is a new message
      cont=0;
      intensita=0;
      while(Serial.available()>0){
        //ho riempito il vettore
        message = Serial.read();
        if(cont==0){
          vet[cont] = message;
        }else{
          vet[cont] = message-48;
        }
        cont++;
        delay(60);
      }
     if(cont>0){
      //so che il primo valore è una lettera che mi dice
      //quale led accendere
        message=vet[0];
        Serial.print("Lettera ");
        Serial.println(message);
        //ora bisogna costruire il valore.....
        
        if(vet[2] ==-2 && vet[3] == -2){
          //dopo la lettera esiste solo un numero
          intensita = vet[1];
        }else if (vet[3] == -2){
          //ho un numero da 10 a 99
          intensita = vet[1] * 10 + vet[2];
        }else{
          intensita = vet[1] * 100 + vet[2]* 10+ vet[3]; 
        }
        Serial.print("intensita ");
        Serial.println(intensita);
      }
      
     // message = Serial.read();    //  Put the serial input into the message

   if (message == 'R'){  //  If a capitol R is received...
     Serial.println("rosso");
     analogWrite(redLEDPin, intensita);
   }/*else if (message == 'r'){  //  If a lowercase r is received...
     redLED = 0;         //  Set redLED to 0 (off)
     Serial.println("ci sono");
     analogWrite(redLEDPin, redLED);
   }*/else if (message == 'G'){  //  If a lowercase r is received...
   Serial.println("verde");
     analogWrite(greenLEDPin, intensita);
   }/*else if (message == 'g'){  //  If a lowercase r is received...
     greenLED = 0;         //  Set redLED to 0 (off)
     analogWrite(greenLEDPin, greenLED);
   }*/else if (message == 'B'){  //  If a lowercase r is received...
   Serial.println("blue");
     analogWrite(blueLEDPin, intensita);
   }/*else if (message == 'b'){  //  If a lowercase r is received...
     blueLED = 0;         //  Set redLED to 0 (off)
     analogWrite(blueLEDPin, blueLED);
   }*/
   
   
  //  analogWrite(redLED, valuer);
   

 }   
}

apposto ti funziona???
dato che ormai l'ho fatto ti posto anche il mio vedi se ti può servire per migliorare qualcosa

int vet[] = {-2, -2, -2, -2};
int cont = 0;
char message = ' ';
int intensita = 0;

void setup() {
  Serial.begin(9600);

}

void loop() { 
  while(Serial.available()>0){
        //ho riempito il vettore
        vet[cont] = Serial.read();
        cont++;
        delay(60);
      }
     if(cont>0){
      //so che il primo valore è una lettera che mi dice
      //quale led accendere
        message=vet[0];
        Serial.print("Lettera ");
        Serial.println(message);
        //ora bisogna costruire il valore.....
        int c=1;
        while((vet[c] != -2) && (c <= 3))
        {
          Serial.print("valore ");
          Serial.println(vet[c] - 48);
          intensita = intensita * 10 + (vet[c]-48);
          c++;
        }
        Serial.print("intensita ");
        Serial.println(intensita);
        for(int i = 0; i < c; i++) //riporta il vettore allo stato iniziale
        {
        vet[i] = -2;
        }
        cont = 0;
        intensita = 0;
      }
      
}

allora nel momento in cui eseguo un upload su arduino ed avvio da tool Serial Monitor e provo a scrivere tipo

R100
B230
B0

funziona perfettamente.

Ora però arriva la parte di Processing che fino a prima della modifica funzionava perfettamente ora non so perchè no.

Diciamo che ho premuto il tasto e da processing viene eseguita questa riga di codice

arduinoPort.write("R100");

dovrebbe accendere la luce rossa con intensità 100.

Però non accade nulla, se avvio processing però la consolle di arduino mi da questo errore

processing.app.SerialException: Serial port 'COM4' already in use. Try quiting any programs that may be using it.

Come si può avviare la consolle in contemporanea con Processing?

Ciao Riguardando un pò il codice credo che l'errore risiede nel fatto che forse con il metodo arduinoPort.write() si può inviare un solo valore per volta. Come faccio per inviargli la stringa R200 x esempio??

Ho provato anche a fare una cosa di questo tipo

arduinoPort.write("R"); // Send the character “R” to Arduino
arduinoPort.write("2");
arduinoPort.write("5");
arduinoPort.write("5");

ma niente.

Vi do un paio di suggerimenti perché ho letto delle cose che non mi piacciono:

  1. cercate sul forum perché la questione di spedire e manipolare dati sulla seriale esce come minimo 2 volte a settimana e nell'ultimo mese se ne sarà parlato 10 volte, con un paio di discussioni in cui ci sono esempi "funzionanti" di codice.
  2. perché spedire 4 byte, usando addirittura degli array, quando il massimo valore che si può spedire ad un pin PWM è 255, che è quindi contenibile in un singolo byte? Perché spedire 'R'-'1'-'0'-'0' per far accendere il led con rosso a 100 quando basta spedire il byte che rappresenta la R ed il byte di valore 100? Siccome la seriale lavora con byte, avendo come tetto massimo di valori sul PWM 255, spedite direttamente un byte contenente il valore: in questo modo non dovete fare conversioni lato Arduino ma potete subito scrivere sull'uscita PWM il valore appena letto. Esempio:
if (Serial.read() == 'R') {
  analogWrite(PIN_RED, Serial.read());
}

E così per gli altri componenti RGB.

Ciao,
scusa ma essendo agli inizi anche le ricerche semplici risultano difficoltose in quanto non uso le parole chiavi corrette. Chiedo scusa quindi per aver aperto questo post.

Allora dalla tua risposta alcune cose mi sono più chiare ma non del tutto.

Da quello che dici tu il problema lo dovrei gestire lato Processing in quanto arduino prende i valori già belli e pronti e accende i vari led.

Come o meglio in che modo invio i dati da PRocessing ad arduino??

Io faccio così:

arduinoPort = new Serial.....

arduinoPort.write("R");

in tal caso come devo modificare

Non uso Processing, quindi da questo "lato" non so aiutarti.

La spedizione su seriale avviene sempre per byte. Se scrivi Print("ABC") viaggeranno i byte 65, 66 e 67, ASCII rappresentativi delle lettere A, B e C. Quindi per spedire R100 devi solo spedire R e poi il valore 100. Immagino Processing sia come Arduino, quindi Serial.write('R') e poi Serial.write(100).

Per la ricerca basta che tu metta "seriale" oppure "spedire seriale" e vedi cosa viene fuori.

Ok ti ringrazio allora farò ulteriori prove.

Ascolta io per fare delle prove lato arduino utilizzo il metodo Serial.print o println per vedere cosa combina.

Per far vedere questi valori l'unico modo è attivare la consolle con ctrl maiusc h ???

Se stai comunicando con l'Arduino da Processing non penso tu possa aprire anche il terminale dell'IDE. La seriale può essere impegnata per 1 comunicazione a volta.

E si infatti lo avevo immaginato.
Resta da fare qualche esperimento. Ho letto in giro che è possibile tramite Processing leggere cioè che arudino scrive tramite l'istruzione Serial.print....

bircastri:
E si infatti lo avevo immaginato.
Resta da fare qualche esperimento. Ho letto in giro che è possibile tramite Processing leggere cioè che arudino scrive tramite l'istruzione Serial.print....

si certo puoi leggere quello che c'è sulla serial con processing quindi potresti fare una cosa così Processing->arduino->processing ovvio però che c'è più spazio per gli errori

Ciao, volevo ringraziare tutti per le risposte ma purtroppo non sono ancora riuscito a combinare nulla.

Ho provato come ha suggerito leo72 a scrivere questo codice lato arduino

if (Serial.read() == 'R') {
  analogWrite(PIN_RED, Serial.read());
}

Come risultato ho che sul secondo Serial.read() ad arduino gli arriva un -1

Ho provato tramite processing ad inviare ad arduino sulla seriale con il metodo .write

le varie stringhe

R100
oppure ad inviare
R
100
richiamando due volte il metodo, nel primo caso non succede nulla nel secondo caso si accende il led rosso veramente debole ma gli arriva un -1 quindi insomma non so più che pesci prendere...

sono ben lieto di seguire altri consigli....

grazie a tutti