Go Down

Topic: [Risolto] progetto scolastico sensori luce (Read 941 times) previous topic - next topic

revolver995

Feb 05, 2013, 05:31 pm Last Edit: Feb 13, 2013, 07:24 pm by revolver995 Reason: 1
Salve a tutti   sto facendo un programma su arduino per scuola , il programma consiste nel rilevare le fonti di luce attraverso 3 fototransistor (nel robot sostituiti da sensori di luce ), uno avanti uno a Sx e uno a Dx;
ora vi spiego meglio , ho costruito una macchinetta robot con 2 motori collegati ad arduino , in pratica lo scopo di questa macchinetta è quello di rilevare tutte le luci in un campo , e di fermarsi e accendere un led quando le trova , però deve essere vicino a queste luci più o meno a 10 cm.
il robot inoltre rimbalza con dei sensori di contatto quando sbatte su qualcosa .
Ora , l'intensità luminosa che deve riconoscere il robot me la regolo attraverso un trimmer .

utilizzo arduino UNO , è alimentato da una batteria di 6 volt circa , e sulla piattaforma di arduino è montata una scheda che serve per i motori , di colore verde  :~ scusate l approssimazione

fino ad ora ho scritto questa parte di programma , che non comprende i sensori di luce , premetto di essere un principiante , quindi se potreste spiegarmi anche solo in che modo posso dire che se la luce è forte il computer deve fermarsi e accendere il LED
Grazie a tutti in anticipo =)

Code: [Select]
int dir_a = 3;
int dir_b = 7;
int pwm_a = 11;
int pwm_b = 12;
int bmp_right = 9;
int bmp_left = 5;
int speed_loop = 220 ;

void setup ()
{
 pinMode (dir_a, OUTPUT);
 pinMode (dir_b, OUTPUT);
 pinMode (pwm_a, OUTPUT);
 pinMode (pwm_b, OUTPUT);
 pinMode (bmp_right, INPUT);
 pinMode (bmp_left, INPUT);
 }
 
void avanti()
{
 digitalWrite (3 , HIGH);
 digitalWrite (7 , HIGH);
 digitalWrite (pwm_a , speed_loop);
 digitalWrite (pwm_a , speed_loop);
}
void indietro()
{
 digitalWrite (3 , LOW);
 digitalWrite (7 , LOW);
 digitalWrite (pwm_a , speed_loop);
 digitalWrite (pwm_a , speed_loop);
}
void left()
{
 digitalWrite (3 , HIGH);
 digitalWrite (7 , LOW);
 digitalWrite (pwm_a , speed_loop);
 digitalWrite (pwm_a , speed_loop);
}
void right()
{
 digitalWrite (3 , LOW);
 digitalWrite (7 , HIGH);
 digitalWrite (pwm_a , speed_loop);
 digitalWrite (pwm_a , speed_loop);
}
void smettila()
{
 digitalWrite (pwm_a , 0);
 digitalWrite (pwm_a , 0);
}
void loop ()

{
 avanti();
 if ((bmp_left == HIGH && bmp_right == HIGH ))
 {
   smettila();
   delay (10);
   indietro();
   delay (700);
   left ();
   delay (1800);
 }
 if ((bmp_left == LOW && bmp_right == HIGH ))
 {
   smettila();
   delay (10);
   indietro();
   delay (700);
   left ();
   delay (900);
 }
  if ((bmp_left == HIGH && bmp_right == LOW ))
 {
   smettila();
   delay (10);
   indietro();
   delay (700);
   right ();
   delay (900);
 }
}


dir_a e dir_b è il nome che dò ai motori
pwm_a e pwm_b è la potenza dei motori
bmp_left e bmp_right sono i sensori di contatto , funzionano come interruttori , quando si chiudono entrambi il robot va      indietro e quando se ne chiude uno solo il robot gira

Spiegaci che cosa c'e che non va con il tuo codice, perchè così su due piedi ci vuole un po per assimilare tutte la variabili e ricordarsi ogni volta cosa fa una e cosa fa l'altra, Dicci che cosa c'e che non va nel tuo codice, che parti vengono correttamente svolte, e che cosa c'e da aggiungere o inserire nel tuo programma ;)

revolver995

#2
Feb 05, 2013, 09:08 pm Last Edit: Feb 05, 2013, 09:12 pm by revolver995 Reason: 1
allora è un po dura spiegarlo perchè dovreste avere sotto mano il circuito dei sensori , allora praticamente c è un trimmer e un fototransistor , il fototransistor si chiude solo se la luce trasformata in corrente , sommata alla corrente che fa scorrere il trimer , è sufficentemente alta .
Se volessi un intensità luminosa più alta per far chiudere il transistor dovrei mettere il trimmer a una resistenza piu alta
questa è una parte di stringa che mi serve

Code: [Select]

int lux_a = 4 ;
int led_a = 10;

void loop ()
{

if (lux_a == HIGH)
 {
   smettila();
   delay (400);
   digitalWrite (10 , HIGH);
   delay (20000);
 }
}


ora come faccio a scrivere il fatto che il valore logico è alto quando al sensore di luce arriva una luce sufficentemente alta ?

smettila è una funzione che richiamo e che fa fermare il mio robot

pablos

Mi sembra chiaro che serve un analog input (i pin A0 A1 A2 ecc) http://playground.arduino.cc/Learning/PhotoResistor
Negli esempi ci sono degli sketch che mostrano come lavorare con questi input, una volta letto il valore "if lettura fotoresistenza > di xxx esegui la funzione" nel tuo caso fermi i motori portando a low il pin

ciao
no comment

Esatto, come ti suggeriscono io ti consiglierei di usare gli le porte analogiche, usare come input..
In pratica su una A0 inserisci la tua fotoresistenza
Successivamente nello sketch nella funzione loop inserisci il codice per Sapere che tensione hai su A0,  che mi pare sia questo:
Valore = analogRead(A0);
Successivamente stampi sulla seriale il valore, in modo da poterlo visualizzare su schermo, con:
Serial.Println(Valore);

Fatto questo illumina sufficientemente la stanza in modo tale da creare l'illuminazione massima, oltre la quale vorresti che il robot cambiasse comportamento.. Quando è sufficientemente illuminata allora leggi il valore che hai nella seriale, e imposti quello come valore Nell'IF del tuo codice..
Capito quello che intendo? ;) Saluti ;)

revolver995

io pensavo a qualcosa di piu basilare , ad esempio arduino riconosce un segnale come high se è superiore a 2,5V e low se inferiore , quindi con una luce forte il sensore aumenta la resistenza creando una caduta di potenziale maggiore , e facendo cadere su arduino un voltaggio minore di 2,5 volt .... ora non posso usare solo il sensore perche sarebbe scomodo e mal regolabile ... e servirebbe una luce troppo forte per far aumentare la resistenza abbastanza da avere il voltaggio richiesto , quindi metto un trimmer regolabile che mi facilita il tutto .
Adesso spero mi abbiate seguito , la domanda è se io lascio il codice
Code: [Select]
int lux_a = 9 ;
if ((digitalRead (lux_a) == LOW ))
in caso incontrasse una luce e quindi il voltaggio si abbassa sotto i 2,5V arduino riconosce  quel segnale come low o devo fare a modo vostro ?

se riusciste a spiegarmi come usare le porte analogiche vi ringrazierei , cioè se ho ben capito mi basta mettere un trimmer e una fotoresistenza in serie e collegarle ad arduino ed alla terra , e poi tramite il comando Valore = analogRead(A0) lui mi dice il voltaggio , e successivamente gli dico
Code: [Select]
if (( valore < 2,5))
{ esegui azione
}


corregetemi se sbaglio

#6
Feb 06, 2013, 04:39 pm Last Edit: Feb 06, 2013, 04:49 pm by EnigmaAren92 Reason: 1
Si hai capito (Sempre se testandolo è tutto ok) Comunque c'e solo un piccolo accorgimento da fare, cioè quei 2,5v che tu continui ad insistere.. Ti ho detto, collega tutto il tuo marchingegno pieno di  potenziometro resistenza e sensore, collegali all'analogico.. tramite un
Serial.println(Valore) Vedi quanto è il valore critico di luce (in modo tale che sai a quanto voltaggio corrisponde Se c'e luce/Se non c'e luce)
E poi basta scrivere quel valore al posto dei tuoi 2,5v..
Capito? Se vuoi una mano  vieni sul mio pc da qua ;) : https://join.me/364-507-266

revolver995

#7
Feb 06, 2013, 09:33 pm Last Edit: Feb 06, 2013, 10:35 pm by revolver995 Reason: 1
OK ho capito tutto , però un ultimissima cosa ,  XD prima riassumo quello che ho capito mi metto il mio bel sensore e il mio bel potenziometro collegato alla porta analogica , lo metto alla distanza che mi serve dalla luce e poi gli dico


Code: [Select]
int lux_a = A0 ;
void loop ()
{
Valore = analogRead(A0);
Seria.lPrintIn (valore)
}


ora , se io non ho lo schermo ne l interfaccia grafica , ma solo arduino UNO e il mio buon pc , come faccio a sapere il valore ? , e cosi facendo posso evitare il potenziometro , perche modificherei tutto dal pc ... se non dovesse andar bene

e poi questa stringa vale solo per la prima volta , una volta che ho il valore numerico come scrivo ?

io avevo pensato a
Code: [Select]

int lux_a = A0;                                  // 1234 è il valore che ho trovato prima
if (analogRead ,lux_a > 1234)
{
      esegui azione
}

mi chiarisco questi punti e poi ti lascio vivere in pace XD



leo72

Devi usare una variabile tampone e salvarci la lettura precedente.
Questa var la inizializzi al'avvio dello sketch con la lettura del pin, poi nel loop fai il confronto con la nuova lettura
Code: [Select]
int vecchiaLettura;
void setup() {
  vecchiaLettura = analogRead(A0);
....
}

void loop() {
  int tempLettura = analogRead(A0);
  if (tempLettura > vecchiaLettura) {
    vecchiaLettura = tempLettura;
    ....
  }
}

revolver995

nel codice.di sopra mi diceva che dovevo assegnare un pin a "valore" e gli ho dato il piedino 0 , ma sempmplicemente appuntarmi il numero che esce dal serial.printin in modo che posso modificarlo quando voglio lo posso fare ? mi rimame.piu comodo

Go Up