Go Down

Topic: Debounce hardware per encoder rotativo (Read 1 time) previous topic - next topic

the_dragonlord

Salve a tutti, per il mio progetto prevedo l'utilizzo di un encoder rotatativo (e del relativo pulsante) per la navigazione fra i menu e la selezione delle varie voci.
Mi sto facendo una cultura sui debouncer hardware (dai semplici RC ad integrati ecc) ma la confusione regna sovrana... l'encoder sarà gestito da uno degli interrupt del Mega2560 (solo la rotazione, non il click perché non penso mi serva un interrupt per questo)... mi chiedo se per la rotazione sia effettivamente necessario un debouncer hardware... per il click ne metterò in piedi uno software... che ne dite? il mio problema è che non ho in casa condensatori ne' ho negozi di elettronica nelle vicinanze per cui comprare uno stock di condensatori online che costano più di spedizione che altro, beh, se posso evitare....
che mi dite?
come sempre grazie
Andrea

fabpolli

Se usi gli interrupt non è che hai tanta scelta... devi usare la soluzione hardware quella software è esclusa con gli interrupt, per il click puoi fare come meglio credi quindi anche software può andar bene

the_dragonlord

Se usi gli interrupt non è che hai tanta scelta... devi usare la soluzione hardware quella software è esclusa con gli interrupt, per il click puoi fare come meglio credi quindi anche software può andar bene
Stavo valutando che tutto sommato anche il discorso degli interrupt tenendo conto della "bassa" velocità di commutazione forse non è nemmeno così importante, che ne dici?

Ho trovato questa libreria che permette di gestire un rotary encoder: https://github.com/brianlow/Rotary

Che ha come esempio questo:

Code: [Select]
/*
    Rotary Encoder - Interrupt Example
   
    The circuit:
    * encoder pin A to Arduino pin 2
    * encoder pin B to Arduino pin 3
    * encoder ground pin to ground (GND)
*/

#include <Rotary.h>

Rotary r = Rotary(2, 3);

void setup() {
  Serial.begin(9600);
  PCICR |= (1 << PCIE2);
  PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
  sei();
}

void loop() {

}

ISR(PCINT2_vect) {
  unsigned char result = r.process();
  if (result == DIR_NONE) {
    // do nothing
  }
  else if (result == DIR_CW) {
    Serial.println("ClockWise");
  }
  else if (result == DIR_CCW) {
    Serial.println("CounterClockWise");
  }
}


Pensavo di provarlo...

gpb01

#3
Nov 09, 2017, 09:40 am Last Edit: Nov 09, 2017, 09:41 am by gpb01
1. Stavo valutando che tutto sommato anche il discorso degli interrupt tenendo conto della "bassa" velocità di commutazione forse non è nemmeno così importante, che ne dici?

2. Ho trovato questa libreria che permette di gestire un rotary encoder: https://github.com/brianlow/Rotary
... emmm ... le due cose sono leggermente in contraddizione visto che quella libreria fa proprio uso degli interrupts ::)

Guglielmo
Search is Your friend ... or I am Your enemy !

the_dragonlord

... emmm ... le due cose sono leggermente in contraddizione visto che quella libreria fa proprio uso degli interrupts ::)

Guglielmo
Sì sì, scusa Gugliemo hai ragione, ho dato sfogo a due ragionamenti in parallelo facendo partire le mani prima del cervello, volevo dire che ho trovato questa libreria che mi gestisce gli interrupt ma mi stavo anche contemporaneamente interrogando sulla necessità o meno di utilizzarli...anche perchè io ODIO usare cose "prefabbricate" senza capire cosa faccio e la sintassi:

Code: [Select]
    PCICR |= (1 << PCIE2);
  PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);


Non la capisco, nel senso che ho visto che PCICR, PCIE1 ecc. sono delle costanti predefinite ma, purtroppo, non ho ancora capito cosa sono e a cosa servono...purtroppo come sempre il materiale in rete è infinito e per chi è alle prime armi la confuzione (e mal di testa) sono una costante....da quello che ho capito quelle due istruzioni servono per "confugurare" l'interrupt, però non capisco il legame fra PCICE2 ed i pin 2 o 3...poi su PCIMT18 e PCINT19 proprio sono andato alla deriva...riesci a farmi un po' di chiarezza o ad indicarmi qualcosa da studiare in proposito che sia abbordabile?

Grazie
Andrea

gpb01

#5
Nov 09, 2017, 10:04 am Last Edit: Nov 09, 2017, 10:21 am by gpb01
E' programmazione a "basso livello" utilizzando direttamente i "registri" interni della MCU. E' tutto ampiamente descritto nel datasheet del ATmega328P e i nomi dei registri sono gli stessi che trovi li.

Esempio:
PCICR: Pin Change Interrupt Control Register
PCIE2: è il bit 2 di detto registro, Pin Change Interrupt Enable 2
... e così via. Ovviamnete, senza studiare il datasheet e senza capire il funzionamneto HW delle varie cose ... è impossibile capire cosa fanno quelle righe.

Ah ... NON sono esattamente cose per chi si avvicina ad Arduino ed è "alle prime armi" ... ::)

Guglielmo

Edit: ... nota che non sta usando i classici interrupt che conosci sui due pin di Arduno, sta utilizzando i "Pin Change Interrupt" che si possono attivare anche su altri pin.
Search is Your friend ... or I am Your enemy !

the_dragonlord

E' programmazione a "basso livello" utilizzando direttamente i "registri" interni della MCU. E' tutto ampiamente descritto nel datasheet del ATmega328P e i nomi dei registri sono gli stessi che trovi li.

Esempio:
PCICR: Pin Change Interrupt Control Register
PCIE2: è il bit 2 di detto registro, Pin Change Interrupt Enable 2
... e così via. Ovviamnete, senza studiare il datasheet e senza capire il funzionamneto HW delle varie cose ... è impossibile capire cosa fanno quelle righe.

Ovviamente NON sono esattamente cose per chi si avvicina ad Arduino ed è "alle prime armi" ... ::)

Guglielmo

Edit: ... nota che non sta usando i classici interrupt che conosci sui due pin di Arduno, sta utilizzando i "Pin Change Interrupt" che si possono attivare anche su altri pin.
Grazie! Mi ci metto d'impegno a studiare allora

Etemenanki

Guarda che stai parlando di un'encoder ruotato a mano per cambiare i menu, non di un'encoder da motore a 200 o piu passi per giro ... a quelle velocita', anche un solo interrupt sarebbe piu che sufficente ... ci colleghi uno dei due pin e lo agganci al corretto cambio di stato (rising se il pin chiude a VCC, falling se chiude a massa), poi nella ISR controlli lo stato dell'altro, se e' alto stai girando in un senso, se e' basso stai girando nell'altro, sempre ...

Come debounce basta un condensatorino da 10n o valori simili fra il pin e massa, anche per il click ... puoi pure recuperarli da qualche scheda, se non hai un negozio a portata di mano ...
"Sopravvivere" e' attualmente l'unico lusso che la maggior parte dei Cittadini italiani,
sia pure a costo di enormi sacrifici, riesce ancora a permettersi.

the_dragonlord

Come debounce basta un condensatorino da 10n o valori simili fra il pin e massa, anche per il click ... puoi pure recuperarli da qualche scheda, se non hai un negozio a portata di mano ...
Grazie, purtroppo anche il discorso di reperire una scheda da cui smontare non è proponibile, proverò a vedere cosa riesco a trovare....10nF quindi poliestere o ceramico, giusto?

Etemenanki

Si ... o un qualsiasi altro valore simile ... dato che serve per pilotare un'interrupt, i soliti 100n potrebbero essere troppi, ma qualsiasi cosa fra 4.7n e 47n dovrebbe andare ... o comunque aiutare ad eliminare eventuali disturbi da rimbalzo ...
"Sopravvivere" e' attualmente l'unico lusso che la maggior parte dei Cittadini italiani,
sia pure a costo di enormi sacrifici, riesce ancora a permettersi.

the_dragonlord

#10
Nov 09, 2017, 11:06 am Last Edit: Nov 09, 2017, 11:20 am by the_dragonlord
Si ... o un qualsiasi altro valore simile ... dato che serve per pilotare un'interrupt, i soliti 100n potrebbero essere troppi, ma qualsiasi cosa fra 4.7n e 47n dovrebbe andare ... o comunque aiutare ad eliminare eventuali disturbi da rimbalzo ...
eccellente, grazie, quindi solo un condensatore fra pin e massa, non un RC

Etemenanki

#11
Nov 09, 2017, 11:28 am Last Edit: Nov 09, 2017, 11:30 am by Etemenanki
Dipende, se l'encoder chiude a massa, puoi attivare le pullup interne e risparmiarti le resistenze di pullup esterne, se invece chiude a VCC, servono per forza le resistenze di pulldown verso massa, perche' la MCU internamente non le prevede ... poi certo sarebbe piu corretto se ci fossero anche le resistenze da 100 ohm in serie ai contatti, ma quelle si possono anche evitare ...
"Sopravvivere" e' attualmente l'unico lusso che la maggior parte dei Cittadini italiani,
sia pure a costo di enormi sacrifici, riesce ancora a permettersi.

the_dragonlord

Dipende, se l'encoder chiude a massa, puoi attivare le pullup interne e risparmiarti le resistenze di pullup esterne, se invece chiude a VCC, servono per forza le resistenze di pulldown verso massa, perche' la MCU internamente non le prevede ... poi certo sarebbe piu corretto se ci fossero anche le resistenze da 100 ohm in serie ai contatti, ma quelle si possono anche evitare ...
L'encoder è questo: http://www.ebay.it/itm/Modulo-encoder-rotativo-2-canali-con-pulsante-arduino-pic-ART-CR10/331712061894?ssPageName=STRK%3AMEBIDX%3AIT&_trksid=p2057872.m2749.l2649
Purtroppo non c'è scritto se chiude verso massa....

brunello22

Chiude a massa e ha gia' a bordo le resistenze di PullUp

astrobeed

#14
Nov 09, 2017, 12:18 pm Last Edit: Nov 09, 2017, 12:19 pm by astrobeed
Gli encoder meccanici non hanno una polarità, semplicemente sono due contatti che vengono chiusi ciclicamente, sfasati di 90°, girando l'alberino, hanno un comune, che si può collegare a piacere a GND o al 5V, due uscite per i contatti, nel modello specifico è presente una terza uscita per il pulsante centrale.
Nella parte inferiore del pcb sono visibili due resistenze da 10k, più il posto per una terza che non è montata, ovvero sono giù presenti le resistenze di pullup, i contatti sono da interpretare come GND per il comune degli switch, + per il 5V delle pullup, volendo si può lasciare libero e si attivano le pullup integrate nei AVR su i pin, DT e CLK sono le uscite dei due contatti, ovvero il canale A e B del encoder, SW l'uscita del contatto dello switch a pressione.
Scientia potentia est

Go Up