calcolo velocità con encoder ottico

Salve ragazzi, sono dinuovo alla presa con questo dannato calcolo della velocità...Ho deciso di usare un ecoder ottico del tipo come lo vedete in immagine

l'encoder ha sigla tk462.fa.500 quindi credo che sia da 500 scatti ogni giro (correggetemi se sbaglio).Ho pensato di calcolare la velocità usando un interrupt sul cambiamento di stato da high a low quindi un falling. ho trovato questo codice in internet , l'ho testato e in effetti indica i giri ma non so se li indica in modo corretto nel senso che comunque dovrei tarare il codice all'encoder ma non so cosa andar a modificare.Qualcuno potrebbe aiutarmi?

volatile long time;            //timekeeping
int encoderZ = 2;              // Encoder Index
int encoderA = 3;                // Encoder A
int encoderPulse = 0;          //Encoder Pulse Counter
volatile long timePrevious = 0;               //Remembers time before
float rpm = 0;
float  vel=0;
//Setup Display
void setup(){
Serial.begin(9600);
pinMode(encoderZ, INPUT);       // Index pulse input
digitalWrite(encoderZ,HIGH);    // enables pull up to reset signal

//pinMode(encoderA, INPUT);       // A pulse input
//digitalWrite(encoderA,HIGH);    // enables pull up to reset signal

Serial.print("RPM:");

//Configure pin modes
//pinMode(encoderA, INPUT);
//digitalWrite(encoderA, HIGH);  // Turn on pullup resistor
//attachInterrupt(1, count, FALLING);   // call sub count to increment at interrupt pin.

pinMode(encoderZ,INPUT);
digitalWrite(encoderZ, HIGH);  // Turn on pullup resistor
attachInterrupt(0, timeCheck, FALLING);   // call sub count to increment at interrupt pin.
}

void loop(){
rpm = 60000/(time-timePrevious);
Serial.print("Spindle RPM: ");


Serial.println(int(rpm));
delay(1000);

}

/* ———— Function timeCheck —————*/
void timeCheck(){
timePrevious=time;
time = millis();   //sets miLLIseconds to minutes
//  rpm = 1009;

}

/* ————— Function count ———————– */
//void count(){
// encoderPulse++;

//}

Hai il datasheet dell'encoder?

il datasheet è questo http://www.tekel.it/PDF/TK45.pdf

la sigla del pezzo e' tk462.FA.500.12.S.K1.8.PS10.LD.X280 quindi è bidirezionale + index a 500 impulsi al giro alimentato a 12 V con frequenza da 0 a 50 khz

Dalla sigla mi pare di capire che anche le uscite sono a 12V perché manca il /5.
Quindi attento perché non li puoi collegare direttamente all’Arduino, ti serve un traslatore di livello o più semplicemente un partitore di tensione.

paolo io l'ho collegato direttamente ad arduino pare funzionava... c'è da seriale riusciva a darmi dei dati... ho bruciato l'arduino?

C'è una incongruenza sulla sigla: manca il /5 sull'alimentazione per indicare l'uscite a 5V ma come uscite indica LD che si applica (come dice il datasheet) solo ai modelli con uscite a 5V. Boh!

quindi sarà 5v... tralasciando questa cosa del voltaggio in uscita poi appena posso lo misuro con un tester. quel codice perchè non va correttamente? come faccio ad indicare che l'encoder per ogni giro fa sti 500 scatti? ho preso il codice da qui non so se può essere utile http://www.alpha.triggerdog.com/blog/?p=17

Il codice lo puoi prendere qui --> http://playground.arduino.cc/Main/RotaryEncoders Anzi, leggi tutta la pagina, ha decine di esempi per tutte le situazioni possibili. Il tuo encoder ha 2 segnali più lo zero, mi pare di aver capito. controlla tra gli esempi, dovrebbe esserci qualcosa che fa al caso tuo.

Dallo sito del produttore ho visto che ci sono delle istruzioni --> http://www.tekel.it/PDF/Manuali/MU_EI_ITA_A3_R2.PDF e delle spiegazioni interessanti --> http://www.tekel.it/Incr-ita.htm

Anche questo --> http://www.tekel.it/PDF/Appendice%20incrementali.pdf

non ho trovato nulla a riguardo il calcolo di rpm o velocità. già ho letto quella pagina

Quante connessioni ha in uscita l'encoder?

Per ottenere la velocità devi calcolare il numero di impulsi nell'intervallo di tempo oppure il tempo tra due impulsi. Ma prima occorre, in base al modello dell'encoder, ottenere l'impulso.

Millis è troppo grande come unità di tempo, devi usare micros(). Con 500 impulsi al giro, bastano 2 giri al secondo, ovvero 120 al minuti che la millis non riesce più a calcolare il tempo.

allora in uscita io ho 6 fili… 2 out A 2 out B e 2 out z due fili per l’alimentazione e poi la schermatura del cavo

Allora in base al codice di ordinazione, siccome hai un "Line Driver" devi usare un integrato che fa da interfaccia tra l'encoder e l'arduino. L'integrato è il 26LS32 (http://www.ti.com/lit/ds/symlink/am26ls32a.pdf) che dispone di 4 ingressi, tu ne userai tre. Inoltre ti serviranno resistenze da 4.7K, condensatori da 10nF e impedenze da 150Ohm, secondo lo schema pubblicato qui, ultimo in basso a destra --> http://www.tekel.it/PDF/Appendice%20incrementali.pdf

Forse puoi utilizzare solo una delle 2 uscite per canale senza tutto l'ambaradan qui sopra. Ma non credo.

perchè ne userò tre? due di entrata a cui collegara i 6 fili e uno d'uscita?

Quell'integrato ha 4 coppie di ingressi, mentre il tuo encoder ha 3 coppie in uscita. Intendevo questo. Dalle 3 coppie in ingresso al 26LS32 otterrai in uscita 3 singoli segnali ripuliti di eventuali disturbi.

quindi questo integrato serve solo a ripulire il segnale? serve un segnale sull'enable? l'altro schema a cosa serve in particolare? è possibile collegare direttamente l'encoder e l'arduino?

Si, l'uscita dell'encoder è differenziale, da quanto ho capito. E' per quello che ho detto che potresti utilizzarlo ugualmente usando solo i segnali positivi (quelli senza il trattino sopra). Però la gestione è molto critica perché con 500 impulsi a giro non hai tempo di fare altro se non contarli e a volte neanche quello.

Se il motore gira a 500 rpm, avrai 500*500*60 = 15'000'000 impulsi al secondo, ovvero uno ogni 0,06 microsecondi. Quindi Arduino, neanche con la funzione micros li conta.

io ho un motore che gira molto lento…oltre all’utilizzo di un encoder non ho trovato soluzione…ho visto in giro gente che usa gli encoder del mouse per calcolare gli rpm… come funziona con quelli?

tipo questo http://www.youtube.com/watch?v=KPv-s-e4HAA

edit:

Allora io ho una puleggia grande che gira molto lenta.Se collego vicino alla puleggia grande una puleggia molto + piccola con nelle prossimità del centro dei fori in modo circolare a ugual distanza e metterei su due sensori IR e utilizzerei questo codice

// read RPM

int rpmcount = 0;
int rpm = 0;
unsigned long lastmillis = 0;

void setup(){
 Serial.begin(9600); 
 attachInterrupt(0, rpm_fan, FALLING);//interrupt cero (0) is on pin two(2).
}

void loop(){
 
 if (millis() - lastmillis == 1000){  //Uptade every one second, this will be equal to reading frecuency (Hz).
 
 detachInterrupt(0);    //Disable interrupt when calculating
 
 
 rpm = rpmcount * 60;  // Convert frecuency to RPM, note: this works for one interruption per full rotation. For two interrups per full rotation use rpmcount * 30.
 
 Serial.print("RPM =\t"); //print the word "RPM" and tab.
 Serial.print(rpm); // print the rpm value.
 Serial.print("\t Hz=\t"); //print the word "Hz".
 Serial.println(rpmcount); //print revolutions per second or Hz. And print new line or enter.
 
 rpmcount = 0; // Restart the RPM counter
 lastmillis = millis(); // Uptade lasmillis
 attachInterrupt(0, rpm_fan, FALLING); //enable interrupt
  }
}


void rpm_fan(){ // this code will be executed every time the interrupt 0 (pin2) gets low.
  rpmcount++;
}

poi faccio una proporzione tra la circonferenza di una puleggia e dell 'altra e gli rpm
in modo da trovarmi gli rpm del tipo circA:rpmA=circB:rpmB rpmA=(circA*rpmB)/circB e quindi mi trovo gli rpm della puleggia grande e poi da li mi trovo i m/s o i m/m o i cm/m a seconda di quello che mi serve. potrebbe funzionare?

ecco la soluzione che avevo visto utilizzando un mouse https://docs.google.com/document/d/1TJYlWxdQgsCGO3YwdHaAeQjpceeQ9hpVJstuHzR1bWs/edit?pli=1

PaoloP: Se il motore gira a 500 rpm, avrai 500*500*60 = 15'000'000 impulsi al secondo,

Il calcolo corretto è 500 * 500/60 = 4166 impulsi al secondo.

francescoprisco:
io ho un motore che gira molto lento…oltre all’utilizzo di un encoder non ho trovato soluzione…

Il tuo encoder ha i due canali su bus RS422, ovvero una linea differenziale e questo è il motivo per cui hai due fili per ogni canale, per collegarlo ad Arduino puoi usare due SN75176, o MAX485, in modo da trasformare le linee differenziali in segnali TTL, il vantaggio dui avere i canali su bus di questo tipo è che permette di usare cavi molto lunghi, anche 20 metri, per collegare l’encoder al circuito.
Per calcolare la velocità di rotazione non devi fare altro che misurare il tempo tra due scatti dell’encoder, va bene farlo sia sul fronte di salita che di discesa a piacere, e moltiplicarlo per 500 (risoluzione encoder), in questo modo ottieni il tempo per una rivoluzione completa, ne fai il reciproco e hai la frequenza di rotazione che moltiplicata per 60 ti da gli rpm.
Esempio pratico, ipotizziamo che il tempo tra due scatti dell’encoder è 2 ms pertanto il tempo per una rotazione è 2*500 = 1000 ms = 1s, 60 * 1/1s → 60/1 = 60 rpm.