Go Down

Topic: encoder in quadratura (Read 2 times) previous topic - next topic

cyclone

allora, tutto dipende da come vuoi leggere gli encoder ad 1X, 2X, o 4X(quadratura)
ma se non vuoi complicarti la vita.. e non sei vincolato al tipo di encoder, e devi al più presto consegnale la tesi,

utilizza qualche encoder con minore risoluzione,,,, anche un 25/50 impulsi giro potrebbe andare. (devi ridurre almeno di un fattore 10)
chiarmente se abbassi la risoluzione hai qualche difficoltà in più nel controllare la velocità..
domanda : devi usare PID, PI o solo P? o devi realizzarla in logica fuzzy?

max00

volevo usare l'ottimo simmetrico. ora mi tocca acquistare un nuovo motore con encoder

cyclone

#17
Aug 25, 2012, 12:38 pm Last Edit: Aug 25, 2012, 12:46 pm by cyclone Reason: 1
guarda se devi dimostrare solo la funzione dell'ottimo simmetrico  di tipo 2 con un polo reale e 2 poli complessi coniugati
ti consiglio di non complicarti la vita con l'hardware. Usa un encoder con più bassa risoluzione, studia come usare gli int, e
di sicuro con la PI e con filtro di smoothing farai un buon lavoro riuscendo nel tuo intento.

max00


cyclone

mi sono ricordato proprio adesso che con la famiglia AVR XMega (es: ATxmega128a1) avresti potuto farlo  poichè possiede una parte hw dedicata chiamata Quadrature Decoder (QDEC)....
Io l'ho provato qualche mese fa e funziona alla grande anche con encoder molto risoluti.


max00

cioè?
ps non so se ho scritto che ho inserito un moror shield

max00

ciao ho cambiato motorino ed encoder ma il problema persiste non riesco ad acquisire il valore dell'encoder
http://www.micromotorssrl.com/electricaldata_1/e_data_1_pg.html

questo è ciò che sto utilizzando cosa ne pensate come mai non va

cyclone

Nooooooooooooooooooooooooo !!!!!

ma che hai fatto! quell'encoder non va bene per la tua applicazione:
intanto hai solo 3 impulsi per giro, non bastano per realizzare un controllo di velocità e poi hai un solo canale e quindi non puoi risalire alla direzione di rotazione.



max00

per la direzione uso il pin di direzione del motor shield mentre come mai dici che non si può fare con 3 impulsi?

cyclone

#24
Sep 03, 2012, 07:13 pm Last Edit: Sep 03, 2012, 07:18 pm by cyclone Reason: 1
max tu cosa devi fare, ancora non mi è chiaro.

a) un controllore di posizione
b) devi controllare solo la velocità dell'azionamento meccanico al variare del carico
c) devi controllare la posizione ove la velocità deve assumere profili diversi (inviluppo dinamico del profilo di velocità es: profilo trapezoidale)
d) devi controllare entrambe le cose

spiega meglio e dai più dettagli.....

max00

devo fare un controllo di velocita, coppia e posizione, però per prima cosa devo fare il controllo in velocità e per far questo dovrei ricavare dall'encoder gli impulsi e ricavarmi la velocità il problema che invece di avere per ogni giro 0000011100000111000000 ho una combinazione casuale di giri ho provato una soluzione farlocca usando questo codice ma non è stabile e nemmeno preciso

"
#include <SoftwareSerial.h>

#define encoder 5
#define motore 3


int val;
int flag;
int cont;
int app;
int pwm;
int pwmfb;
float giro;
float durata;
float app2;
float app3;
float vel;
float pausa;
int posizione;
int pot=5;


void setup() 
{
  pinMode(encoder,INPUT);
  pinMode(motore,INPUT);
  Serial.begin(9600);
  app2=0;
}

void loop()
{
  // acquisizione del valore del pwm
 
  posizione=analogRead(pot);
  pwm=map(posizione,0,1023,100,255);
  //pwm=pwm-pwmfb;
 
  // fine acquisizione valore del pwm
  analogWrite(motore,pwm);
    // comincio la procedura per acquisire il dato dall'encoder
 
  durata=millis();
  //durata=durata-app2;
 
  val= digitalRead(encoder);  // acquisisco il valore (alto o basso del encoder)
  // incremento il valore cont ognivolta che trovo una variazione di valore
  if (val!=flag)
     { if (val==HIGH)
          {flag=1;}
       else
          {flag=0;}
     cont=flag+cont;
  }
  cont=cont;
  //dividendo per 3 calcolo quanti giri ha fatto il rotore
  giro=cont/3;
  //Serial.print("impulsi ");
  //Serial.println(cont);
  //Serial.print("il motore ha fatto ");
  //Serial.println(giro);
  giro=giro*100; // trasformo in giri al secondo
  vel=giro/durata;
  pausa=map(pwm,100,255,350,20); // calcolo la pausa da calcolare per campionare l'impulso
  //pwmfb=map(vel,0,0.75,0,255);
  //Serial.print("la velocita ");
  Serial.println(vel);
  //Serial.print("il tempo ");
  //Serial.println(durata);
  Serial.flush(); // pulisco il buffer seriale
  delay(pausa); // pausa per il campionamento
 
  // fine acquisizione velocità
 

 
}
"

max00

Risolto il controllo in velocità se vi interessa vi posto il codice.
Ora il problema è come aumentare la coppia

cyclone

#27
Sep 11, 2012, 09:17 pm Last Edit: Sep 12, 2012, 08:35 am by cyclone Reason: 1
dopo i vari replay, sarei curioso di dare una sbirciatina al codice....

come aumentare la coppia?
chiaramente implementando algoritmo PID o controller fuzzy logic.... anche via firmware.

a te la scelta
ciao

max00

eccovi il codice

#include <SoftwareSerial.h>

#define encoder 5
#define motore 3
#define pot 5

int pwm,pwmfb,posizione,err;
float vel,durata,durh,durl;

void setup() 
{
  pinMode(encoder,INPUT_PULLUP);
  pinMode(motore,INPUT);
  Serial.begin(19200);
  err=0;
  durata=0;
}

void loop()
{
// acquisizione del valore del pwm
    posizione=analogRead(pot);
    pwm=map(posizione,0,1023,100,255);
// fine acquisizione valore del pwm
// inizio del controllore
    err=pwm-pwmfb;
    pwm=pwm+err;
    if (pwm>255) {pwm=255;}
// fine controllore

    analogWrite(motore,pwm);
       
// comincio la procedura per acquisire il dato dall'encoder
    durh = pulseIn (encoder, HIGH);
    durl = pulseIn (encoder, LOW);
    durata=durl+durh;
// fine acquisizione velocità
   
    vel=10000/durata;
    Serial.println(vel);
    vel=vel*100;
    pwmfb=map(vel,0,98,0,255);
}


Janos


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...  ;) Non so che rapporto di riduzione ha acquistato...

Go Up