calcolo velocità con encoder ottico

astrobeed:

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

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

Sto andando a comprare il cilicio. :sweat_smile:

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. :~

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.

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

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"

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

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

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