Pages: 1 2 [3]   Go Down
Author Topic: encoder in quadratura  (Read 1937 times)
0 Members and 1 Guest are viewing this topic.
Ivrea
Offline Offline
God Member
*****
Karma: 5
Posts: 680
"La teoria è quando si sa tutto ma non funziona niente. La pratica è quando funziona tutto ma non si sa il perché. In ogni caso si finisce sempre con il coniugare la teoria con la pratica: non funziona niente e non si sa il perché." Albert Einstein
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

dubito fortemente che riuscirai a leggere la sequenza in quadratura con il solo arduino alla max velocità.
la famiglia HEDS5xxx sono encoder con risoluzione molto elevata e in base alla sigla si può arrivare fino a 1024 CPR.

anche gestendo bene i segnali A e B utilizzando gli interrupt potrai stare dietro alla lettura solo se farai andare il motore molto ma molto lentamente.
per migliorare un pò la funzione di intercettazione e conteggio degli impulsi dovresti scrivere la routine in assembly (codice macchina).

Non è vero, per un'applicazione che ho sviluppato a lavoro sono riuscito a leggere un encoder in quadratura da 500 imp/giro a circa 25rpm dell'albero, quindi ad una frequenza di 12KHz per canale. Ovviamente c'è da scordarsi le digitalRead nel gestore di interrupt, troppo lente.

Inoltre, rispondendo ad un post successivo, i micromotors li utilizziamo anche a lavoro e sono con due fasi, non con una. Non so se quel micromotors che max ha acquistato ha solo una fase... Ad ogni modo considera che sono motoriduttori, quindi anche se hanno solo 3 imp/giro ma se hanno un rapporto di riduzione di 100 diventano 300 imp/giro sull'albero lento...  smiley-wink Non so che rapporto di riduzione ha acquistato...
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 18
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

mi potresti dire come hai fatto e la logica cosi potrei riuscire a fare la retroazione in posizione
« Last Edit: September 20, 2012, 04:16:46 am by max00 » Logged

Rome (Italy)
Offline Offline
Tesla Member
***
Karma: 120
Posts: 9185
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Non è vero, per un'applicazione che ho sviluppato a lavoro sono riuscito a leggere un encoder in quadratura da 500 imp/giro a circa 25rpm dell'albero, quindi ad una frequenza di 12KHz per canale. Ovviamente c'è da scordarsi le digitalRead nel gestore di interrupt, troppo lente.

Si però per gestire 24000 interrupt al secondo (12000 * 2) con l'ATmega 328 non riesci a fare altro,  per gli encoder con segnali che arrivano ad elevate frequenze tocca usare gli appositi IC oppure micro dotati dell'apposito modulo hardware.
Comunque 500 cpr in quadratura diventano 2000 ppr che a 25 rpm sono solo 833 Hz per canale, valore gestibile con Arduino anche se siamo al limite se vuoi fare pure altre cose.

Quote
Inoltre, rispondendo ad un post successivo, i micromotors li utilizziamo anche a lavoro e sono con due fasi, non con una.

Micromotors i motori te li fornisce come ti pare, ovvero senza encoder, con encoder a una fase o due fasi, tutti a bassa risoluzione, se non mi ricordo male il massimo che offrono loro sono 25 cpr, poi quelle che trovi in giro su i vari store è un altro paio di maniche.
Logged

Rome (Italy)
Offline Offline
Tesla Member
***
Karma: 120
Posts: 9185
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

mi potresti dire come hai fatto e la logica cosi potrei riuscire a fare la retroazione in posizione

Devi implementare un pid per il controllo della posizione.
Logged

Ivrea
Offline Offline
God Member
*****
Karma: 5
Posts: 680
"La teoria è quando si sa tutto ma non funziona niente. La pratica è quando funziona tutto ma non si sa il perché. In ogni caso si finisce sempre con il coniugare la teoria con la pratica: non funziona niente e non si sa il perché." Albert Einstein
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@astro
perché solo 833Hz per canale? Comunque con tutti quegli interrupt, oltre al programma, ho un tempo ciclo di circa 150us, valore che acquisisco con la funzione micros() ad ogni inizio del loop.

@max
Code:
#define encInterrA 0
#define encInterrB 1
#define encA 2
#define encB 3

volatile unsigned long contEnc = 0; //Valore del conteggio dell'encoder

void encoderA() {
  unsigned char i = PINE;                   //Leggo il valore di PINE
  unsigned char a = i & (1 << PE4);         //Maschero gli altri bit per isolare quello corrisp. alla fase A
  unsigned char b = i & (1 << PE5);         //Maschero gli altri bit per isolare quello corrisp. alla fase B
  if (a == (1 << PE4)) {                    //Se A è alto
    if (b == 0) contEnc++;                  //e B è basso incrementa
    else contEnc--;                         //altrimenti decrementa
  }
  else {                                    //Se A è basso
    if (b == (1 << PE5)) contEnc++;         //e B è alto incrementa
    else contEnc--;                         //Altrimenti decrementa
  }
};

void encoderB() {
  unsigned char i = PINE;                   //Leggo il valore di PINE
  unsigned char a = i & (1 << PE4);         //Maschero gli altri bit per isolare quello corrisp. alla fase A
  unsigned char b = i & (1 << PE5);         //Maschero gli altri bit per isolare quello corrisp. alla fase B
  if (b == (1 << PE5)) {                    //Se B è alto
    if (a == (1 << PE4)) contEnc++;         //e A è alto incrementa
    else contEnc--;                         //altrimenti decrementa
  }
  else {                                    //Se B è basso
    if (a == 0) contEnc++;                  //e A è basso incrementa
    else contEnc--;                         //Altrimenti decrementa
  }
};

void setup() {
  digitalWrite(encA, HIGH);                           //Attivo i pullup degli ingressi dell'encoder
  digitalWrite(encB, HIGH);                           //Attivo i pullup degli ingressi dell'encoder
  attachInterrupt(encInterrA, encoderA, CHANGE);      //Attivo il gestore di interrupt per gli ingressi dell'encoder
  attachInterrupt(encInterrB, encoderB, CHANGE);      //Attivo il gestore di interrupt per gli ingressi dell'encoder
}

Considera che ho utilizzato un encoder con uscite npn, quindi ho attivato le resistenze di pullup interne. Queste, però, a 20KHz sono troppo grandi e quindi ne ho messe altre due esterne di valore più piccolo.
P.S. Questo codice è stato scritto per l'Arduino Mega 2560, quindi per il processore ATMega2560. Se usi l'Arduino Uno sicuramente non ti va bene perché i pin di interrupt non saranno sulla porta E. A tal riguardo ti consiglio di controllare il pin mapping dei relativi processori:
http://arduino.cc/en/Main/ArduinoBoardMega2560
http://arduino.cc/en/Main/ArduinoBoardUno
« Last Edit: September 20, 2012, 07:18:04 am by Janos » Logged

Rome (Italy)
Offline Offline
Tesla Member
***
Karma: 120
Posts: 9185
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@astro
perché solo 833Hz per canale?

500 impulsi per rotazione diventano 2000 in quadratura, 25 rpm sono 25/60 = 0.41666 Hz, 2000 * 0.41666 = 833 Hz
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 18
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

grazie per il codice ora cerco di capire la logica.
ps tu riesci a contare il num di impulsi?
Logged

Ivrea
Offline Offline
God Member
*****
Karma: 5
Posts: 680
"La teoria è quando si sa tutto ma non funziona niente. La pratica è quando funziona tutto ma non si sa il perché. In ogni caso si finisce sempre con il coniugare la teoria con la pratica: non funziona niente e non si sa il perché." Albert Einstein
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@Astro
Hai ragione, ho sbagliato a dire io...   smiley-mr-green
L'encoder, che ha una ruota di 65mm di diametro, quindi 204mm di perimetro, mi misura una velocità di scorrimento di 5mt/sec. Facendo i calcoli viene che l'encoder gira a 24.5Hz, non rpm...  smiley-wink
Logged

Pages: 1 2 [3]   Go Up
Jump to: