encoder incrementale

salve a tutti, ho creato un encoder incrementale (1Fase), 16 fori, l ho fatto comunicare con due diodi infrarossi, uno mittente, l altro ricevente, il circuito creato sono sicuro che vada bene, la cosa che più mi preme e il codice che dovrebbe fare stampare sullo schermo (lcd presente nel kit started arduino uno) la velocità'.

lo sketch è il seguente

#include <LiquidCrystal.h>
# define NFORI 16
int time, N;
float f, UU;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup()
{
pinMode(6, INPUT);
lcd.begin(16, 2);
}
void loop()
{
 N=0;
if(digitalRead(6)==HIGH) N=N+1;    //se il secondo led riceve la luce.. 
time = 0;
while(time <= 3000)                //esegue il ciclo per 3 secondi
{ 
  lcd.print("creato da matteo");
  if(digitalRead(6)==HIGH) N=N+1;
  time=time+1;  
}
  f=N/3;
  UU=(60*f)/NFORI;
  lcd.clear();
  lcd.print( UU );
  delay(5000);
 
}

La velocità' la stampa, il problema e che non rimane costante, ma aumenta, e diminuisce casualmente, ogni tanto, diventa persino vegativa -_- ,e un mese che provo e riprovo a guardarmi il codice, senza nessun risultato. se qualcuno avesse la soluzione ne sarei grato. Grazie ancora, anticipatamente :slight_smile:

Ti invitiamo a presentarti qui: Re: Presentazioni nuovi iscritti, fatevi conoscere da tutti! (Part 1) - Generale - Arduino Forum
e a leggere il regolamento: http://forum.arduino.cc/index.php?topic=149082.0

Per favore il codice racchiudilo nei tag code, vedi sezione 7 del regolamento, spiega bene come fare. Altrimenti parte del codice può risultare non visibile (viene interpretato come attributo del testo).

ho fatto tutto ora, scusami ma non avevo visto, grazie :slight_smile:

Tre appunti/consigli:

  1. quando lavori con i float e le divisioni è meglio dichiarare float anche le costanti, aggiungi virgola 0
f=N/3.0;
UU=(60.0*f)/float(NFORI);
  1. Nel while da 3000 hai messo lcd.print("creato da matteo");
    quindi stampi ben 3000 volte quella frase !!! L'LCD impazzirà :grin:
    mettila prima del while (così la fa una volta sola)

  2. Quel while hai commentato "esegue il ciclo per 3 secondi" ma chi te lo dice? Quel while cicla 3000 volte ma non sai quanto tempo ci mette. Leviamo quel lcd.print, ma le 3 istruzioni ad ogni ciclo sono il tempo di quel ciclo e non è detto sia 1 millisecondo *3000

while(time <= 3000)                
{ if(digitalRead(6)==HIGH) N=N+1;
  time=time+1;  
}

grazie del consiglio, ne starò' più attento la prossima volta, il problema cmq sia, persiste, se io mando il disco a velocità' costante il valore dovrebbe rimanere costante mentre invece da me varia, ad' esempio da 280 giri/min mi passa a 140 giri/min, e non riesco proprio a capire dove sia lo sbaglio.

Secondo me sbagli nella logica.
Non puoi chiederti semplicemente se il pin 6 ti dà HIGH ma devi verificare la variazione da LOW a HIGH.
Se per assurdo l'encoder è fermo proprio su un foro (credo sia quello il caso di HIGH) allora digitalRead(6) è sempre HIGH.

esatto, ma l encoder non potra' mai essere fermo sul foro, quello che a me serve capire, che forse ho sbagliato, anzi sicuramente, è il tempo impiegato da un foro all altro, ovvero da {HIGH - LOW - HIGH }. io pensavo che tutte le volte che prendevo un valore alto, lo addizionavo a N, pero prima credevo che la durata di quel ciclo l'avessi impostata con i secondi, invece ho solo impostato il numero di volte che esegue il ciclo. potrebbe essere li l'errore, e come posso fare a preimpostare io una durata di tempo per quel ciclo ?

while(time <= 3000) //esegue il ciclo per 3 secondi
{
lcd.print("creato da matteo"); // (t1)
if(digitalRead(6)==HIGH) N=N+1; (t2)
time=time+1; (t3)
_delay_ms(0.998); (t4)
}

0.998 millesimi di secondo (quasi un secondo millesimo di secondo * 3000 = secondi) valore da trovare sperimentalmente.
Il while dura t1+t2+t3+t4.

Ciao.

scusami l' ignoranza, non ho capito l' l'ultimo tempo del ciclo…. potresti rispiegarmelo per cortesia? grazie

ciao
sto facendo esperienza con un encoder da 360 punti/giro e la scelta migliore per contare gli impulsi è usare l'interrupt

stefano

stefa24, grazie per il consiglio, ma qui il problema è di programmazione -_- sbaglio qualche sintassi e non capisco dove

Uso di interrupt con encoder ottico:
http://www.gavinkenneally.com/?p=10

Altrimenti pulseIn() ma non sò se la pulseIn() è in grado di stare dietro alla velocità dell'encoder.
http://forum.arduino.cc/index.php?topic=22298.msg167824#msg167824