Uscita digitale > ingresso analogico

Buongiorno,

Prima di tutto se non lo avete notato mi sono appena registrato ed approfitto per presentarmi a tutti voi. E' da qualche tempo che faccio semplici esperimenti con Arduino, ma oggi mi si e' auto-presentata un domanda a cui cercando nel forum non mi è riuscito di trovare una risposta (forse anche perche non sapevo che cosa cercare).

La domanda e' abbastanza semplice e forse per molti di voi banale:

vorrei far lampeggiare un led e nello stesso tempo leggere un sensore di temperatura e stampare la temperatura nel monitor pero' (ed e' questo per me il difficile) separare la frequenza di lampeggio del led dalla frequenza di lettura analogica della temperatura. Nel mio primo tentativo infatti la lettura analogica viene fatta in contemporanea con il lampeggio del led.

Ciao, benvenuto nel forum.

Come fai a definire la frequenza del lampeggio (e della lettura del sensore)? Utilizzi un delay/millis/metro?

Se posti il codice possiamo risponderti in modo più appropriato.

Si! in pratica ho semplicemente unito l’esempio base del “blink” con l’esempio base dell’ “analogread”

come separare le due funzioni perche vengano eseguite indipendentemente?

..se usi un delay, sostanzialmente blocchi l'esecuzione del codice. Per fare in modo di gestire 2 o più eventi senza bloccare il codice e quindi in modo asincrono (non è il termine corretto ma sperto aiuti a capire), devi utilizzare le funzioni millis() http://www.arduino.cc/en/Reference/Millis oppure metro http://www.arduino.cc/playground/Code/Metro

In pratica accendo e spengo il led usando un metodo diverso (al posto del delay) e stampo sul monitor seriale le letture analogiche utilizzando in questo caso il "delay".

Se ho capito bene provo ad eseguire e ti ringrazio per l'input!

In pratica accendo e spengo il led usando un metodo diverso (al posto del delay) e stampo sul monitor seriale le letture analogiche utilizzando in questo caso il "delay".

il delay lascialo proprio stare..

Cerca di utilizzare millis sia per il led che per il sensore; per il led già trovi un esempio qui: http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay e se lo adatti lo puoi utilizzare anche per la lettura analogica, definendo un ulteriore intervallo.

infatti...me ne sono accorto cercando di fare il programma che il delay devo dimenticarlo...studio il millis.

Vediamo se riesco a combinare qualcosa!

grazie!

Aggiornamento:

Ancora non ho ottenuto il risultato sperato, sarebbe facile postare il mio codice perche venga corretto da un ma preferisco perderci ore e ore. A questo punto pero' mi servirebbe un'altra spinta:

Ho operato in questa maniera:

Creo due istruzioni del tipo (basandomi sul blink con millis) unsigned long millsled = millis(); unsigned long millistemp = millis();

la prima con una istruzione "if" e un intervallo di 1000ms (fa lampeggiare il led) la seconda sempre con un "if" e un intervallo di 100ms (fa leggere il sensore su ingresso analogico) stampo sul monitor seriale i "millis" della lettura del dato analogico e il dato analogico.

cosa ottengo?: il led lampeggia alla frequenza desiderata. viene letto il dato analogico ma sempre in contemporanea con il lampeggio del led. anche i "millis" si riferiscono al lampeggio.

dove sbaglio?

In questi giorni ho studiato un un po’ l’istruzione millis()
Per semplificare le cose ho deciso di cambiare leggermente lo scopo del mio progetto:
Far lampeggiare un led sfruttando l’ istruzione millis pero’ con un duty cicle non al 50% ad esempio 1000ms acceso e 350ms spento.
Sono arrivato alla conclusione che questo non si puo’ fare.(vero?)
Prendendo come esempio questo lavoro:

ho visto che il primo evento (che e’ anche il piu’ frequente) e’ anche multiplo del secondo che a sua volta e’ multiplo di un eventuale terzo) quindi riportando il tutto al mio led lampeggiante il tempo di “on” e’ multiplo del tempo di “off” (o viceversa).
E’ corretto???

Non ho guardato quel link ma puoi farlo benissimo anche tu.

unsigned long contatore=0;
byte flag=0;
void setup() {
....
contatore=millis()+1000;
digitalWrite(PIN, HIGH);
}

vodi loop() {
  if (millis()>contatore) {
    if (flag==0) {
      digitalWrite(PIN, LOW);
      contatore=350;
    } else {
      digitalWrite(PIN, HIGH);
      contatore=1000;
    }
    flag^=1;
    contatore+=millis();
    }
  }
}

Parti con il led acceso per 1000 ms. Passati questi, entri nell'if, e controlli se il flag è a 0 o 1, per capire se devi spengere o accendere il led. A seconda dell'operazione, riaggiorni il contatore. Il flag lo imposti con lo XOR. Così se il flag è a 1, viene messo a 0 e viceversa. CODICE NON TESTATO

L'ho testato io e funziona!. Ne ho di strada da fare! Teoricamente, con questa soluzione, posso ancora leggere un sensore analogico ogni 10mS indipendentemente dal lampeggio del led??? Non datemi la soluzione! ditemi solo se e' possibile!

Certo che è possibile.

ok, ho bisogno ancora di aiuto, e' tutto il pomeriggio che ci sbatto la testa e non trovo lo strumento (o meglio l'istruzione giusta) per realizzare quello che voglio. Ritorniamo al mio problema iniziale. Il led lampeggia alla fraquenza e con i tempi che voglio. Adesso con una fotoresistenza voglio rilevare e contare i lampeggi del led. Il primo tentativo che ho fatto e' stato quello di dire: se la lettura analogica supera un certo valore (quando il led e' acceso) allora incrementa il contatore. Il problema semplice di quello che ho fatto e' che il led puo rimanere acceso anche mezzo secondo e in questo periodo il contatore di lampeggi continua a contare (visto che appunto rileva il led acceso). Che istruzione si puo usare quindi per dire: se supera il particolare valore butta fuori un "1" una volta fino a quando non ripassa da un valore inferiore???. O in altre parole...vorrei contare le volte che la soglia e' superata non per quanto tempo la soglia e' stata superata...

inizio - stato attuale led spento loop - confronti lo stato attuale del led con l'input analogico, se sono diversi conteggi, e inverti lo stato attuale del led. in questo modo se ci sono tante letture acceso o spento di fila, conteggi solo la prima. giusto? :)

inizio - stato attuale led spento loop - confronti lo stato attuale del led con l'input analogico, se sono diversi conteggi, e inverti lo stato attuale del led. in questo modo se ci sono tante letture acceso o spento di fila, conteggi solo la prima. giusto?

Non credo sia proprio cosi, il led lampeggia per i fatti suoi, costantemente. Voglio contare i lampeggi usando lo stesso arduino. Posso dire che quando l'ingresso analogico della fotoresistenza supera un certo valore il led e' acceso. Se per contare i lampeggi uso un'istruzione del tipo: if(valoreanalogico maggiore di tot) alora incrementa il contatore di 1. la cosa non puo' funzionare perche il valore analogico resta "maggiore di tot" per diversi mS. Cercavo quindi un seggerimento per l'istruzione adeguata da usare. Qualcosa che incrementi solo al superamento della soglia.

PS: So che cerco di inventare "l'acqua calda" ma il mio e' un pretesto per imparare studiare e far pratica.

nonno, hai capito male, stato attuale led NON comanda il led, è solo una variabile in cui salvi lo stato del led nell'ultima lettura. Se il suo stato cambia, per esempio è salvato HIGH ma ora è LOW, allora il led si è spento, e viceversa. In effetti così consti quante volte il led si accende e spegne, diviso 2 da il numero di volte che il led ha lampeggiato :)

ok…dimentica che il led e’ collegato all’arduino. Il led lampeggia e non so ne perche ne come.
Con un sensore devo contare i lampeggi.

paowow: ok...dimentica che il led e' collegato all'arduino. Il led lampeggia e non so ne perche ne come. Con un sensore devo contare i lampeggi.

è esattamente quello che fai con la la logica che ti ho scritto.

Si!...non mi ero concentrato a sufficienza sul tuo procedimento.... Adesso l'ho pigliato...Sono duro. :D

praticamente appena leggi che 'una luce' si è accesa, setti un flag a 1 (acceso) e quindi ora controlli quando si spegne. e poi viceversa.

Ecco! il tutto accoppiato con il codice della prima pagina ottengo un led lampeggiante ed il conteggio dei lampeggi

val=analogRead(0); // legge il sensore di luce

if (val>600) { //se e' maggiore di 600 il LED e' acceso statoledadesso=HIGH;} else statoledadesso=LOW;

if (statoledprecedente&statoledadesso==LOW){ n=n+1; // incrementa il conteggio

Serial.println(n); } statoledprecedente=statoledadesso;

Adesso: mi piacerebbe vedere sul terminale solo l'ultimo valore letto e non tutti i valori che scorrono verticalmente...possibile???