Go Down

Topic: Lettura di un encoder incrementale (Read 2423 times) previous topic - next topic

iw1evm (Tecno)

Salve a tutti ragazzi, sono di nuovo qui con un nuovo problema nei miei vari esperimenti sto cercando di utilizare un encoer ricavato da un vecchio videoregistratore. Quindi ho scritto un skech per leggere i due canali (A e B). Quando mi fermo su un punto continua  a in crementare i conteggio ansichè fermarsi.Questo è l skech che ho scritto

Code: [Select]

#define AR_SIZE( a ) sizeof( a ) / sizeof( a[0] )
#define CAN_A 6 // ingresso encoder canale A
#define CAN_B 7 // ingresso encoder canale B
int  impulsi = 0; // impulsi encoder
void setup(){

  Serial.begin(9600);       // apre la porta seriale x il pc}
}
void loop(){
    boolean canold_a;
    boolean canold_b;
    boolean can_a;
    boolean can_b;
    can_a=digitalRead(CAN_A);//leggo in canale a dell'encoder
    can_b=digitalRead(CAN_B);//leggo in canale b dell'encoder
    if ((can_a==HIGH) && (canold_a==LOW) && (can_b==LOW)) {
     canold_a=HIGH;
     impulsi=impulsi + 1;
     Serial.println(impulsi);
    }
    if ((can_b==HIGH) && (canold_b==LOW) && (can_a==LOW)) {
     canold_b=HIGH;
     impulsi=impulsi - 1;
     Serial.println(impulsi);
    }
   
  if (can_a==LOW && can_b==LOW ) {
  canold_a=LOW;
  canold_b=LOW;
  }
}

leo72

La funzione loop() viene ripetuta all'infinito.
Ogni volta che viene ripetuta le variabili canold_a/b vengono reinizializzate quindi saltano tutti i controlli negli if.

Mettile all'inizio dello sketch, in modo che siano globali, impostane i valori iniziali nella funzione setup() e dovrebbe andare.

iw1evm (Tecno)

ho fatto le modifiche come sugerito però adesso la lettura varia tra 0 e -1 oppure tra 0 e 1 la mia idea era che appena un canale andava a uno bloccava l'altro e canold serviva per legere il fronte di salita, non sono sicuro che
Code: [Select]

if ((can_a==HIGH) && (canold_a==LOW) && (can_b==LOW)) {

sia corretto

leo72

Questo devi vederlo tu. Non so come funziona il tuo progetto HW  XD

iw1evm (Tecno)

gli encoder incrementali quando vengono ruotati generano due treni di impulsi che sono sfalsati di mezza durata dell'impuso.invertendo la rotazione si inverte ordine di arrivo degl'impulsi.

http://forum.lithium.it/portal/images/stories/Image/Controlli%20Automatici/EncoderIncr.png

Ti ringrazio per l'aiuto ciao.

MauroTec

Ciao tecno, nel playground italiano c'è uno sketch, puoi prendere esempio da li, solo che la lettura degli encoder in pooling è inaffidabile.
Per la lettura degli encoder è meglio ricorrere alle routine di interrupt, vedi nel reference la funzione attachInterrupt().
Quelle funzioni lavorano solo sui pin 2 e 3 di arduino 2009 o UNO, sul mega ci sono mi pare in totale 4 pin interrupt.


Il pooling è la tecnica che controllo ripetutamente lo stato di un qualcosa in questo caso lo stato di un pin.

Ciao.
AvrDudeQui front end per avrdude https://gitorious.org/avrdudequi/pages/Home

lesto

usando i registri dell'atmega puoi settare interrupt su qualsiasi pin  :)

ma per ora credo che quelli messi a disposizione da attachInterrupt() possano bastare. Se poi per ogni treno di impulsi la durata del segnale basso è uguale a quello del segnale alto anziché usare l'interrupt sul change puoi usarlo solo su rising o falling, dimezzando il carico di lavoro dell'arduino
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

MauroTec

Quote
usando i registri dell'atmega puoi settare interrupt su qualsiasi pin  smiley

Esatto, però non su gli altri pin hai un vettore per porta, cioè in totale sul 328 ci sono 3 vettori di interrupt appunto uno per ogni porta, anche per questo non è possibile trigerarli come si fa con i pin 2 e 3, cioè sono solo changed.

Però non credo che tecno sia a questo livello, meglio attachInterrupt che le ISR nude è crude.

Ciao.
AvrDudeQui front end per avrdude https://gitorious.org/avrdudequi/pages/Home

iw1evm (Tecno)

vi ringrazio tutti per i consigli.
Per MauroTec nel fratempo ho visto lo skech e penso di studiarmelo.
Per tutti gli altri penso che per adesso non intrapendo la via degli
interrup perche come dice un mio amico io sono programmatore della domenica.
Ciao a tutti

lesto

#9
Feb 20, 2011, 09:28 pm Last Edit: Feb 20, 2011, 09:33 pm by lesto Reason: 1

Quote
usando i registri dell'atmega puoi settare interrupt su qualsiasi pin  smiley

Esatto, però non su gli altri pin hai un vettore per porta, cioè in totale sul 328 ci sono 3 vettori di interrupt appunto uno per ogni porta, anche per questo non è possibile trigerarli come si fa con i pin 2 e 3, cioè sono solo changed.

Con un poco di logica booleana riesci a gestire anche le change su pin specifici, e credo che sia la stessa algebra che usa l'attachInterrupt(), ma non ho mai controllato.
Io uso gli interrupt su 4 pin per leggere 4 segnali PPM e mai avuto problemi


Però non credo che tecno sia a questo livello, meglio attachInterrupt che le ISR nude è crude.

Ciao.

non posso che darti ragione, ma in caso gli servisse almeno sà che esistono :_)
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

iw1evm (Tecno)

Questo pomeriggio ho trovato dove era il problema ,bisognava aggiungere queste due istruzioni
Code: [Select]

canold_b = HIGH;// bit oneshot per il canale b
canold_a = HIGH;// bit oneshot per il canale a

adesso riesco a leggere bene l'encoder
Per adesso non ho intenzione di provare con gli interrup per non devo controllare un asse di una cnc quindi se perdo degli inuplsi non è problema.

Go Up