Sensore di colore - thread ufficiale

Salve, ho deciso di aprire un 3d ufficiale per il sensore di colore auocostruito che sto cercando di realizzare. Il principio si basa sulla luce riflessa da una superficie colpita da una sorgente luminosa avente tre diversi colori (almeno all'inizio) e una fotoresistenza inserita in un semplice partitore con una resistenza da 1k.

Ecco il codice:

 int redled = 2; // RGB rosso collegato al pin 2
 int greenled = 3; // RGB verde collegato al pin 3
 int blueled = 4; // RGB blu collegato al pin 4
 int lightread = 0; // fotoresistenza collegata all'entrata analogica 0


 
 void setup() {

  Serial.begin(9600);
  pinMode(redled, OUTPUT); 
  pinMode(greenled, OUTPUT);
  pinMode(blueled, OUTPUT);

  
 }
 
 void loop() {
  
   lightread = analogRead (0);
   digitalWrite(redled, LOW); //spegne tutti i led
   digitalWrite(greenled, LOW); //spegne tutti i led
   digitalWrite(blueled, LOW); //spegne tutti i led
   delay(500);
   
   digitalWrite(redled, HIGH);
   delay(500);
   Serial.print("R= ");
   Serial.println(lightread);
   delay(500);
   
   digitalWrite(redled, LOW);
   digitalWrite(greenled, HIGH);
   delay(500);
   Serial.print("G= ");
   Serial.println(lightread);
   delay(500);
   
   digitalWrite(greenled, LOW);
   digitalWrite(blueled, HIGH);
   delay(500);
   Serial.print("B= ");
   Serial.println(lightread);
   Serial.println("-");
   delay(500);
   
   
   
 }

ll problema è che così facendo mi restituisce sulla seriale lo stesso valore per ogni lettura, in ogni ciclo, mentre vorrei che ogni lettura restituisse il valore necessario. E il mio primo programmino serio, abbiate pietà di me :slight_smile:

Grazie

Lo sto realizzando anche io!!! grande!!
Il problema è che non credo che vadano bene i normali led colorati...
tu che valori ottieni? valori differenti?

Uso un led RGB ad alta luminosità, solo che i vari colori non sono tutti luminosi allo stesso modo, ad esempio il rosso è molto meno luminoso del blu e del verde, quindi dovrò trovare il modo tramite pwm di portare tutti alla stessa luminosità, magari con una porzione di codice che legge la riflessione del rosso su bianco e porta gli altri due colori alla stessa luminosità, ma mi pare un po' fuori della mia portata, quindi vi stresserò ulteriormente :slight_smile:

Il mio problema, ora è che il codice che ho scritto riporta la lettura come se la facesse una sola volta all'inizio di ogni ciclo RGB, e non dopo 500 ms che il led di quel colore particolare è acceso.
In pratica sulla seriale mi riporta una cosa del genere:

R= 778
G= 778
B= 778
-
R= 801
G= 801
B= 801
-
R= 994
G= 994
B= 994

...e così via, eppure gli faccio fare la lettura ogni volta che il colore adatto si accende, dopo 500ms per compensare un po' l'inerzia che ha la fotoresistenza nella lettura. E' impossibile che legga la stessa luminosità perchè, per provare, ho coperto col ditino la fotoresistenza quando stava passando da rosso a verde, ma niente.

Dovrei forse dichiarare la variabile prima?
Ossia modificare all'inizio eliminando int lightread = 0; e sostituendolo con

int lightsensor= 0;

e nel loop un

lightread= analogRead(lightsensor);

Chiedo perchè ci ho provato, ma mi da un errore, forse sbaglio una sciocchezza :frowning:
Per la cronaca in giro, ma solo dopo aver preparato tutto su breadboard, ho trovato questa pagina: Cadmium-Sulfide Active Color Object Sensor - Robot Room che parla del sensore che stiamo costruendo noi, e altre che parlano di un sensore sottrattivo, ossia l'oggetto viene illuminato con luce bianca e la luminosità letta da tre fotoresistenze ognuna con su un filtro rosso, verde o blu :slight_smile:

gbm scusami potresti aiutarmi a realizzare il Sensore Infrarosso Sharp IS471F perchè ho letto da una tua discussione che anche tu l'hai realizzato:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1244072890

se vieni su questa discussione mi puoi aiutare grazie:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1265793466

MrGhost, ho aperto un 3d apposito proprio perchè laltro era incasinato, usa i messaggi privati piuttosto :smiley:

scusa.. partecipo ma credo di essere parecchio scarso... mi sembra di capire che tu leggi il valore su analog 0, poi spegni tutti i led, poi accendi il rosso e lo rispegni, accendi il verde e lo rispegni e poi lasci il blu acceso... cosi come capisco io quando leggi analog0 hai sempre (tranne la prima vlta) solo il blu acceso... era questo che volevi ottenere? non dovevi mettere la lettura della analog0 ogni volta che cambi i led accesi/spenti (quindi tre volte) ??
scusa se non ho capito
ciao

int redled = 2; // RGB rosso collegato al pin 2
int greenled = 3; // RGB verde collegato al pin 3
int blueled = 4; // RGB blu collegato al pin 4
int lightread = 0; // fotoresistenza collegata all'entrata analogica 0

void setup() {

Serial.begin(9600);
pinMode(redled, OUTPUT);
pinMode(greenled, OUTPUT);
pinMode(blueled, OUTPUT);

}

void loop() {

lightread = analogRead (0); // Qui chiami la analogread(0) della porta 0 e metti il valore in lightread, ok.

digitalWrite(redled, LOW); //spegne tutti i led
digitalWrite(greenled, LOW); //spegne tutti i led
digitalWrite(blueled, LOW); //spegne tutti i led
delay(500);

digitalWrite(redled, HIGH); / Qui accendi il LED rosso
delay(500); / Qui aspetti mezzo secondo

Qui dovresti inserire di nuovo lightread = analogRead (0);

Serial.print("R= ");
Serial.println(lightread); Qui Invii il valore di lightread, ma dove hai richiamato analogread(0) per il valore aggiornato da copiare in lightread ??????
delay(500);

digitalWrite(redled, LOW);
digitalWrite(greenled, HIGH);
delay(500);

Qui dovresti inserire di nuovo lightread = analogRead (0);

Serial.print("G= ");
Serial.println(lightread);
delay(500);

digitalWrite(greenled, LOW);
digitalWrite(blueled, HIGH);
delay(500);

Qui dovresti inserire di nuovo lightread = analogRead (0);

Serial.print("B= ");
Serial.println(lightread);
Serial.println("-");
delay(500);

}

Scusa, quindi dovrei dichiarare sempre la variabile?
Credevo bastasse dichiarare all'inizio che lightread è la lettura di analogread, e poi richiederne la stampa, ora provo, grazie :slight_smile:

non devi 'dichiarare'.. la devi riempire...

Come ti ha detto lapsus la devi "riempire" ovvero la lettura avviene solo quando chiami la funzione analogread metre il codice
lightread= analogread(0) la chiama ed assegna il valore alla variabile, ma la variabile non e' la funzione, per ottenere questo effetto avresti dovuto usare un puntatore a funzione al posto di lightread.
Ma ancora piu semplice ( e piu elegante ) oltre a risparmiare byte nella mem del AVR era:

Serial.println(analogread(0));

<Senza sprecare una variabile che non ti serve ad altro. :slight_smile:

Perfetto, ora funziona, grazie :slight_smile:
resta da verificare se la resistenza per il partitore è corretta...
io ho messo quella da 1k perchè era la prima che ho trovato, ad essere sincero.
Prima però mi concentro sull'algoritmo per calcolare l'HUE, vediamo cosa viene fuori. Prima però devo assegnare ad ogni lettura (R, G e B) una variabile, perchè devo poi effettuare i calcoli per trovare il colore riflesso.

nel frattempo per ottimizzare come propostomi ho creato questo accrocchio:

digitalWrite(redled, HIGH);
   delay(500);
   Serial.print("R="), Serial.println(analogRead(0));
   delay(500);

aggiornamento:

ho aggiunto qualche riga in modo da stivare ogni lettura di colore nella rispettiva variabile, spero sia corretto, per ora sembra funzionare :slight_smile:

 int redled = 2; // RGB rosso collegato al pin 2
 int greenled = 3; // RGB verde collegato al pin 3
 int blueled = 4; // RGB blu collegato al pin 4
 int rread=0;
 int gread=0;
 int bread=0;
 int hue=0;
 

 
 void setup() {
  Serial.begin(9600);
  pinMode(redled, OUTPUT); 
  pinMode(greenled, OUTPUT);
  pinMode(blueled, OUTPUT);
 
  
 }
 
 void loop() {
  
 
   digitalWrite(redled, LOW); //spegne tutti i led
   digitalWrite(greenled, LOW);
   digitalWrite(blueled, LOW);
   delay(500);
   
   digitalWrite(redled, HIGH);
   delay(500);
   rread = analogRead(0);
   Serial.print("R="), Serial.println(rread);
   delay(500);
   
   digitalWrite(redled, LOW);
   digitalWrite(greenled, HIGH);
   delay(500);
   gread= analogRead(0);
   Serial.print("G="), Serial.println(gread);
   delay(500);
   
   digitalWrite(greenled, LOW);
   digitalWrite(blueled, HIGH);
   delay(500);
   bread= analogRead(0);
   Serial.print("B="), Serial.println(bread);
   Serial.println("-");
   delay(500);
   
   
   
   
   
 }

io utilizzo dei led ad alta luminosità del colore dell'emettitore per percepire il singolo colore, mi chiedevo se è possibile collegare via analog e fare lo stesso procedimento di ledsensor....
Purtroppo la lettura (digitale) è davvero lenta..qualcuno ha qualche consiglio per velocizzarla?

io credo funzioni... per il delay dopo la serial.print sono sufficienti, da manuale, 10ms per la conversione analogica/digitale... i 500 che metti dopo aver manipolato i led suppongo siano per ottenere il perfetto spegnimento o la perfetta accensione ( un po' come il rosso dei semafori qui a napoli, che se non e' proprio rosso rosso si puo' ancora passare) ....
la soluzione proposta di trasmettere direttamente la lettura analog0, era più veloce, pero' tu hai comunque necessita' di conservare i valori letti quidi va bene....
ciao

Sempre se è possibile, si potrebbe collegare i led utilizzati come sensori in analgico e dopo averli caricati valutare piu' che il valore in se, la caduta di tensione in un periodo, anche di soli 100millis, magari cosi' si puo' accorciare il tempo di acquisizione per colore. Cosa ne dite?

Fattibile, ma preferisco non complicarmi troppo la vita, per ora.
I 500ms sono più per l'inerzia di lettura che hanno le fotoresistenze che per i tempi di conversione, mi sono tenuto un pochino largo :smiley:

Scusate se mi introduco nel discorso.
Non ho capito bene come funziona questo sensore di colore.

Praticamente accendete un led blu (ad esempi) ed in base alla luminosità riflessa valutate se è di colore blu?
:-?

esatto... ma se vedi l'esempio, vengono anche 'miscelati' i 3 colori fondamentali (accendendo i relativi led) cosi da ottenere anche gli altri dello spettro..... con il sensore connesso alla porta analogica 0 si legge il valore e, da questo, etc etc

in teoria dovrebbe funzionare, ho comprato le M&M's, se ne avanzano testo il sensore ;D

Ma...funziona?
Cioè voglio dire capirei se fosse una superfice piatta e regolare, ma gli M&M sono di forma irregolare e lucidi.

il bello del progetto è che se non funziona mi mangio gli elementi da analizzare :slight_smile: Costruisco il case del sensore e ti so dire ;D