[risolto] Encoder come funziona?

Niente?

Mi spiace ma ancora non ho approfondito l'argomento e non ho mai utilizzato encorder. :roll_eyes:

PaoloP:
Mi spiace ma ancora non ho approfondito l'argomento e non ho mai utilizzato encorder. :roll_eyes:

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

Su Wiki c'è questo --> Trasduttore di posizione angolare - Wikipedia
e questo --> Codice Gray - Wikipedia

--> Arduino Playground - RotaryEncoders

Iz2rpn:
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

@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:

//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
}

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ì:

#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

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 :slight_smile:

OptiEnc.pdf (570 KB)

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

Ciao

flz47655:
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°.

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 FuturaNet: Il portale per makers ed elettronica by Futura Group

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

uwefed:

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?

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

astrobeed:

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

perfetto grazie per la gentilezza, cosi per avere qualche altro sistema di gestione, proverò anche quello di flz47655 poi valuterò quello più conveniente, ma con arduino due leggevo che la gestione degli encoder diventa più semplice o sbaglio?

Iz2rpn:
perfetto grazie per la gentilezza, cosi per avere qualche altro sistema di gestione, proverò anche quello di flz47655 poi valuterò quello più conveniente, ma con arduino due leggevo che la gestione degli encoder diventa più semplice o sbaglio?

Arduino DUE ha la gestione degli encoder in hardware, però mi pare non sia supportata da wiring 1.5, ma non ti è di molto aiuto perché il problema del debouncing rimane, anzi è ancora peggio perché sei obbligato ad usare gli appositi IC antidebouncing perché non è possibile gestirlo a software se usi il decodificatore hardware.
La decodifica degli encoder in hardware ti semplifica la vita dal punto di vista software perché hai un registro che incrementa/decrementa in automatico ogni volta che l'encoder gira, hai anche un flag che ti dice in che verso ruota, può gestire elevate velocità di cambio degli impulsi, centinaia di kHz, tipiche negli encoder ottici ad alta risoluzione utilizzati su i motori per misurare la velocità e lo spazio percorso, cosa inutile nel caso di encoder meccanici visto il loro utilizzo come manopole.

astrobeed:

Iz2rpn:
perfetto grazie per la gentilezza, cosi per avere qualche altro sistema di gestione, proverò anche quello di flz47655 poi valuterò quello più conveniente, ma con arduino due leggevo che la gestione degli encoder diventa più semplice o sbaglio?

Arduino DUE ha la gestione degli encoder in hardware, però mi pare non sia supportata da wiring 1.5, ma non ti è di molto aiuto perché il problema del debouncing rimane, anzi è ancora peggio perché sei obbligato ad usare gli appositi IC antidebouncing perché non è possibile gestirlo a software se usi il decodificatore hardware.
La decodifica degli encoder in hardware ti semplifica la vita dal punto di vista software perché hai un registro che incrementa/decrementa in automatico ogni volta che l'encoder gira, hai anche un flag che ti dice in che verso ruota, può gestire elevate velocità di cambio degli impulsi, centinaia di kHz, tipiche negli encoder ottici ad alta risoluzione utilizzati su i motori per misurare la velocità e lo spazio percorso, cosa inutile nel caso di encoder meccanici visto il loro utilizzo come manopole.

Credevo si sarebbe passati a una semplificazione del tutto, va bene lo stesso :slight_smile:

Dai un'occhiata qui, c'è il codice pronto all'uso per un encoder meccanico.

http://bildr.org/2012/08/rotary-encoder-arduino/ risolto con questo grazie a tutti