Arduino Forum

International => Italiano => Software => Topic started by: francescoprisco on Jul 29, 2013, 10:07 pm

Title: calcolo velocità con encoder ottico
Post by: francescoprisco on Jul 29, 2013, 10:07 pm
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
(http://www.tekel.it/IMG/FOTO/TK25.gif)

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?

Code: [Select]


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++;

//}
Title: Re: calcolo velocità con encoder ottico
Post by: PaoloP on Jul 30, 2013, 10:05 am
Hai il datasheet dell'encoder?
Title: Re: calcolo velocità con encoder ottico
Post by: francescoprisco on Jul 30, 2013, 10:16 am
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
Title: Re: calcolo velocità con encoder ottico
Post by: PaoloP on Jul 30, 2013, 10:24 am
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.
Title: Re: calcolo velocità con encoder ottico
Post by: francescoprisco on Jul 30, 2013, 10:27 am
paolo io l'ho collegato direttamente ad arduino pare funzionava... c'è da seriale riusciva a darmi dei dati... ho bruciato l'arduino?
Title: Re: calcolo velocità con encoder ottico
Post by: PaoloP on Jul 30, 2013, 10:34 am
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!
Title: Re: calcolo velocità con encoder ottico
Post by: francescoprisco on Jul 30, 2013, 10:36 am
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
Title: Re: calcolo velocità con encoder ottico
Post by: PaoloP on Jul 30, 2013, 10:41 am
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
Title: Re: calcolo velocità con encoder ottico
Post by: francescoprisco on Jul 30, 2013, 10:43 am
non ho trovato nulla a riguardo il calcolo di rpm o velocità. già ho letto quella pagina
Title: Re: calcolo velocità con encoder ottico
Post by: PaoloP on Jul 30, 2013, 10:56 am
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.
Title: Re: calcolo velocità con encoder ottico
Post by: francescoprisco on Jul 30, 2013, 10:59 am
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
Title: Re: calcolo velocità con encoder ottico
Post by: PaoloP on Jul 30, 2013, 11:10 am
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 (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  (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.
Title: Re: calcolo velocità con encoder ottico
Post by: francescoprisco on Jul 30, 2013, 11:18 am
perchè ne userò tre? due di entrata a cui collegara i 6 fili e uno d'uscita?
Title: Re: calcolo velocità con encoder ottico
Post by: PaoloP on Jul 30, 2013, 11:23 am
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.

(http://circuits.datasheetdir.com/124/DS26LS32C-pinout.jpg)
Title: Re: calcolo velocità con encoder ottico
Post by: francescoprisco on Jul 30, 2013, 11:29 am
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?
Title: Re: calcolo velocità con encoder ottico
Post by: PaoloP on Jul 30, 2013, 11:37 am
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.
Title: Re: calcolo velocità con encoder ottico
Post by: francescoprisco on Jul 30, 2013, 12:31 pm
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
Code: [Select]

// 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?
Title: Re: calcolo velocità con encoder ottico
Post by: francescoprisco on Jul 30, 2013, 05:07 pm
ecco la soluzione che avevo visto utilizzando un mouse https://docs.google.com/document/d/1TJYlWxdQgsCGO3YwdHaAeQjpceeQ9hpVJstuHzR1bWs/edit?pli=1
Title: Re: calcolo velocità con encoder ottico
Post by: astrobeed on Jul 30, 2013, 05:26 pm

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.
Title: Re: calcolo velocità con encoder ottico
Post by: astrobeed on Jul 30, 2013, 05:33 pm

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.
Title: Re: calcolo velocità con encoder ottico
Post by: PaoloP on Jul 30, 2013, 05:49 pm


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.


Sto andando a comprare il cilicio.  :smiley-sweat:

Comunque dopo pagine e pagine, topic su topic, non ho ancora capito di che motore si tratta, se ti serve visualizzare la velocità di rotazione del motore o la velocità lineare di un traslatore, se l'encoder lo vorresti acquistare o lo hai già, ma soprattutto se questo motore è già in funzione anche senza tutti questi controlli o lo stai progettando.  :~
Title: Re: calcolo velocità con encoder ottico
Post by: francescoprisco on Jul 30, 2013, 06:44 pm
PaoloP il motore è di una manovia che trasposta carrelli attraverso le varie fasi di produzione. Il sistema già è tutto in funzione ma mi serviva comandare appunto il motore tramite internet. Il sistema c'è, accende il motore spegne il motore ne aumenta la velocità e la diminuisce. mi occorre vedere la velocità del motore per sapere appunto di quanto aumentare o di quanto diminuire.L'encoder già lo tengo.Il sistema è fatto da un motore che gira sempre fisso alla stessa velocità con un riduttore con frizione che gestisce la velocità della puleggia che fa muovere tutto.Il tutto va ad esempio a 1 metro al minuto. La velocità mi servirebbe lineare ma se è più facile in rpm fa lo stesso.Sono mesi che non riesco a trovare una cavolo di soluzione.
Title: Re: calcolo velocità con encoder ottico
Post by: icio on Aug 20, 2013, 02:00 pm
Il limk da cui hai preso spunto
http://www.alpha.triggerdog.com/blog/?p=17
mostra un' applicazione SIMILE ad un encoder , ma non è un encoder , gli serve solo per misurare gli RPM per un tornio e non la posizione del mandrino, infatti non usa il canale B che non c'è neppure , anche se l'ha dichiarato non usa nemmeno il canale A , usa solo lo Z che manda fuori 1 solo impulso al secondo,  come vedi la durata dell'impulso Z è molto lungo prendendo 90 gradi sulla rotazione,

tornando al tuo encoder puoi usare o il canale A (o B è indifferente )  oppure il canale Z,  se usi il canale A avrai grande precisione sul numero di giri usando un frequenzimentro,  invece se usi il canal Z avrai bassa precisione con un frequenzimetro , per avere alta precisione con il canale Z deve usare un periodometro

mettendo che tu voglia usare il canale A per fare un frequenzimetro è molto semplice, aprire un gate software che dura 1 secondo e contare tutti gli impulsi che arrivano nel tempo di gate in una variabile a 16bit o 32 bit uint32_t , puoi farlo semplicemente con la tecnica del polling senza usare un interrupt esterno sul canale A.
alla fine del secondo  calcoli gli rpm:   (numero_impulsi_contati  x 60)  / 500 .

riazzerri in contatore , riapri il gate per 1 secondo e ripeti
Title: Re: calcolo velocità con encoder ottico
Post by: icio on Aug 20, 2013, 02:04 pm
L'applicazione del signore:  http://www.alpha.triggerdog.com/blog/?p=17   dice "build a encoder...." ma non è corrette , è invece "build a tachometer and  RPM meter"

invece la tua applicazione è "build a RPM meter using a encoder"
Title: Re: calcolo velocità con encoder ottico
Post by: icio on Aug 20, 2013, 02:07 pm
mi sono dimenticato:

alla fine del gate di un secondo  calcoli gli rpm:   (numero_impulsi_contati  x 60)  / 500 .

visualizzi sull lcd

riazzerri in contatore , riapri il gate per 1 secondo e ripeti
Title: Re: calcolo velocità con encoder ottico
Post by: icio on Aug 20, 2013, 02:20 pm
ti metto un codice che avevo fatto per un altro MC:
c'è un interrupt periodico da 16384usec generato da un timer in free running
ogni 61 interrupt fà un secondo ma io gli faccio raggiungere 63 interruzioni così 2 interruzioni (32msec) servono per il rinfresco del lcd
nel main si fà il conteggio per polling il calcolo e la visualizzazione

Code: [Select]

unsigned short tik, gate;
unsigned int Countgiri, Ngiri;  //int=16bit long=32bits

//-------------interrupt----------------------------------------------------------------------------------
void interrupt() {  // Interrupt  viene da TIMER0
//-----------rtc-----------------------------
   tik++;             //ogni 16,384 msec
   if (tik == 63) {   //61 tik =1 secondo    2 tik per il display
      tik=0;
      gate=0;
   }
   if (tik == 2) {
      gate=1;
   }
  INTCON.f2  = 0;  //cancella flag  timer0
} //fine interrupt

//----------------- Main procedure-----------------------
void main() {

        Init_Main();    // perform initialization
        scrivi_logo();  // scrivi logo su lcd
 
    while (1) {
   
        while (gate==0) {}         //aspetta gate
        while (gate==1) {          //ra4=pulsante coin rb5=in_coin
           if (!portb.f5) {        //fronte negativo
              Countgiri++;
           while (!portb.f5) {}    //aspetta fronte positivo
           }
        }
        Ngiri = (Countgiri * 60)  / 500;
        Countgiri=0;
        WordToStr(Ngiri, tnum6);
        LCD_Out(2,3,tnum6);       //visualizza valore giri su lcd

    }   //fine while
  }  //fine main