Go Down

Topic: [risolto] Encoder come funziona? (Read 7407 times) previous topic - next topic

iz2rpn

Oct 30, 2012, 01:08 pm Last Edit: Nov 05, 2012, 04:50 pm by Iz2rpn Reason: 1
Ciao a tutti anche avendo letto la documentazione sul sito non riesco a capire come sfruttare il mio encoder per far incrementare e decrementare un contatore non ho per niente le idee chiare su come funziona mi date una mano per favore?

Allego immagine dello schema di collegamento.

grazie a tutti


PaoloP

Mi spiace ma ancora non ho approfondito l'argomento e non ho mai utilizzato encorder.  :smiley-roll-blue:

iz2rpn


Mi spiace ma ancora non ho approfondito l'argomento e non ho mai utilizzato encorder.  :smiley-roll-blue:


Grazie per la risposta cmq se trovo la soluzione la postero sono componenti molto interessanti

PaoloP

#4
Nov 01, 2012, 02:59 pm Last Edit: Nov 01, 2012, 03:01 pm by PaoloP Reason: 1
Su Wiki c'è questo --> http://it.wikipedia.org/wiki/Trasduttore_di_posizione_angolare
e questo --> http://it.wikipedia.org/wiki/Codice_Gray

--> http://www.arduino.cc/playground/Main/RotaryEncoders

tazzo


Ciao a tutti anche avendo letto la documentazione sul sito non riesco a capire come sfruttare il mio encoder per far incrementare e decrementare un contatore non ho per niente le idee chiare su come funziona mi date una mano per favore?

Allego immagine dello schema di collegamento.

grazie a tutti


Il mio era molto semplice, avevo 3 pin, quello al centro era da collegare alla massa gli altri due quando si girava la manopola erano due treni di onde quadre sfasati tra loro, leggevo un canale e se l'altro era ad 1 allora era una direzione, se era 0 era l'altra.
Avevo messo un circuito di debouncing prima di leggere i segnali però, ti scrivo un pò di fretta dimmi se non hai capito

Ciao

iz2rpn

@PaoloP grazie per i link li avevo letti ma io e l'inglese abbiamo dei problemi tecnici li sto traducendo con molta fatica.

@flz47655 anche il mio e cosi con in più il pulsante praticamente posso pigiare il rotore dell'encoder, cmq si ho capito già se potevo capire quando giravo da un lato invece che dall'altro sarebbe ottimo, poi devo capire come incrementare un contattore.

ho trovato questo codice ma secondo me ha problemi di debouncing pur avendo messo le resistenze da 10k hai due pin dell'encoder:

Code: [Select]
//From bildr article: http://bildr.org/2012/08/rotary-encoder-arduino/

//these pins can not be changed 2/3 are special pins
int encoderPin1 = 2;
int encoderPin2 = 3;

volatile int lastEncoded = 0;
volatile long encoderValue = 0;

long lastencoderValue = 0;

int lastMSB = 0;
int lastLSB = 0;

void setup() {
  Serial.begin (9600);

  pinMode(encoderPin1, INPUT);
  pinMode(encoderPin2, INPUT);

  digitalWrite(encoderPin1, HIGH); //turn pullup resistor on
  digitalWrite(encoderPin2, HIGH); //turn pullup resistor on

  //call updateEncoder() when any high/low changed seen
  //on interrupt 0 (pin 2), or interrupt 1 (pin 3)
  attachInterrupt(0, updateEncoder, CHANGE);
  attachInterrupt(1, updateEncoder, CHANGE);

}

void loop(){
  //Do stuff here

  Serial.println(encoderValue);
  delay(1000); //just here to slow down the output, and show it will work  even during a delay
}


void updateEncoder(){
  int MSB = digitalRead(encoderPin1); //MSB = most significant bit
  int LSB = digitalRead(encoderPin2); //LSB = least significant bit

  int encoded = (MSB << 1) |LSB; //converting the 2 pin value to single number
  int sum  = (lastEncoded << 2) | encoded; //adding it to the previous encoded value

  if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) encoderValue ++;
  if(sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) encoderValue --;

  lastEncoded = encoded; //store this value for next time
}

tazzo

Con le sole resistenze purtroppo non si fa debouncing..
Utilizzando gli interrupt non si può chiamare delay() quindi conviene fare debouncing via hw..

Io ho usato questo circuito con R da 10K C da 100nF e come IC il 4093 su ogni canale dell'encoder


Quel codice va bene se l'encoder ha la stessa codifica (es. grey), io col mio che non ha nessuna codifica particolare e semplicemente ho fatto così:

Code: [Select]

#define pin_encA  3  // Deve essere pin3 altrimenti non funziona l'interrupt
#define pin_encB  4

void setup() {
 attachInterrupt(1, OnEncoderChange, FALLING);
}

void OnEncoderChange()
{
 if (digitalRead(pin_encB) == HIGH) {
   // un verso
 } else {
   // l'altro verso
 }
}


Ciao

astrobeed

Con gli encoder meccanici il debouncing hardware è praticamente obbligatorio, solo tramite software allungherebbe molto i tempi di risposta e farebbe perdere scatti durante la rotazione a meno che non sia molto lenta.
Ti allego un tutorial sugli encoder ottici (vale anche per quelli meccanici) incrementali che avevo iniziato a scrivere nel 2001 e mai completato, però ci trovi tutte le informazioni di base su come funzionano ed è in italiano :)


Scientia potentia est

tazzo

Hai una pagina di dove hai comprato l'encoder che spiega le sue caratteristiche tecniche? Così controllo se utilizza qualche codifica particolare

Ciao

astrobeed


Hai una pagina di dove hai comprato l'encoder che spiega le sue caratteristiche tecniche? Così controllo se utilizza qualche codifica particolare


Gli encoder meccanici di quel tipo sono tutti uguali, può cambiare la disposizione dei pin, possono avere un pulsante integrato sull'albero, eventuali led per illuminarlo, ma a livello di funzionamento non cambia nulla, sono tutti del tipo incrementale con due segnali sfasati a 90°.
Scientia potentia est

iz2rpn

#11
Nov 02, 2012, 06:19 pm Last Edit: Nov 02, 2012, 06:27 pm by Iz2rpn Reason: 1
http://www.futurashop.it/allegato/7719-ENCODER12MM.asp?L2=VARIE&L1=COMPONENTI%20ELETTRONICI&L3=&cd=7719%2DENCODER12MM&nVt=&d=3,50

ho comprato questo, grazie astrobeed ora mi leggo il pdf con molta attenzione spero di capire meglio il funzionamento

flz47655 ma perchè in altri siti fanno vedere che collegano l'encoder direttamente? non ci sono proprio modi per gestire al meglio un encoder senza usare un hw esterno?

guarda i link che consiglia futura elettronica http://www.futurashop.it/allegato/7300-ENCODEROTA.asp?L2=CORRELATI&L1=7300-ENCODERLED&L3=&cd=7300-ENCODEROTA&nVt=&d=4,50

uwefed


flz47655 ma perchè in altri siti fanno vedere che collegano l'encoder direttamente? non ci sono proprio modi per gestire al meglio un encoder senza usare un hw esterno?


Parliamo di encoder con contatti meccanici.
Se vuoi usarlo sul interrupt devi fare il debunce via HW senó un impulso Ti genera 3-4 passi.
Se non usi gli interrupt puoi fare il deboucing via Sw.
Ciao Uwe

iz2rpn



flz47655 ma perchè in altri siti fanno vedere che collegano l'encoder direttamente? non ci sono proprio modi per gestire al meglio un encoder senza usare un hw esterno?


Parliamo di encoder con contatti meccanici.
Se vuoi usarlo sul interrupt devi fare il debunce via HW senó un impulso Ti genera 3-4 passi.
Se non usi gli interrupt puoi fare il deboucing via Sw.
Ciao Uwe


Allora ti faccio una domanda forse stupida, quindi significa che atmel ha un campionamento del segnale troppo lento? e per questo che si crea questo tipo di problema?

astrobeed


Allora ti faccio una domanda forse stupida, quindi significa che atmel ha un campionamento del segnale troppo lento?


Non è un problema di campionamento lento, è un problema di rimbalzi, un contatto meccanico quando chiude crea una serie di impulsi rapidissimi, anche molte decine, che creano una serie di conteggi fasulli.
Si può gestire anche solamente da software, magari con l'accortezza di utilizzare almeno un filtro passa basso (RC) sul pin collegato al canale, però dato che è indispensabile introdurre dei ritardi di molti ms, anche diverse decine, questo si traduce in forti ritardi nella gestione dell'encoder con la conseguenza che se non lo giri lentamente, dipende da quanti impulsi giro fornisce, rischi di perderti dei conteggi.
Adesso non ho tempo per farlo però domani ti posto uno schema di base, solo con rete RC, e un minimo di codice per gestire l'encoder tramite interrupt e debounce software.

Scientia potentia est

Go Up