Esatto! Hai scoperto le mie fonti.
https://github.com/PaulStoffregen/Encod ... /Encoder.h
Se ti apri il file encoder.h vedrai che il suo incremento a 32bit ed il mio sono identici tranne per il fatto che lui usa 4 diversi registri, mentre io ri-uso sempre quello sui 4 byte.
La differenza è invece nello schema di decodifica, lui alla fine ha implementato il classico algoritmo che trovi anche in altri siti dove la lettura precedente è shiftata di due posizioni a sinistra ed unita in OR con la lettura attuale a formare un codice a quattro bit con 16 combinazioni possibili.
- 4 Che hanno i bit 1 e 2, 3 e 4 uguali a due a due, che sono in pratica 'Nessuna variazione'
- 4 Che sempre a coppie a due a due sono diversi su entrambi i canali, che sono gli stati nel caso l'encoder sia avanzato di due posizioni dall'ultimo passo. Non ho ben capito la decisione di incrementare/decrementare di 2 in questo caso. Dal mio punto di vista è un errore di conteggio. Se accade ho semplicemente superato la frequenza max leggibile e lo devo evitare a priori sapendo i limiti del mio programma. Così rischi di illuderti di contare lo stesso, ma prima o poi ti frega.
-4 Che sono i quattro possibili casi di incremento e
-4 Che sono i quattro possibili casi di decremento.
Lui poi con un uso particolare del codice di decodifica crea un offset su un puntatore e ricava da una tabella in memoria il valore da sommare/sottrarre alla variabile.
Scrivendo in una tabella di quattro righe quei valori, ho notato 'per caso' che facendo l'XOR tra due stati successivi avevo sempre:
00 - (0) con nessuna variazione
11 - (3) con doppio step sia avanti che indietro
01 - (1) in due casi di incremento ed in due casi di decremento
10 - (2) in due casi di incremento ed in due casi di decremento
ma se scambiavo i bit dei canali A e B nella nuova lettura la situazione diventava sempre:
00 - (0) con nessuna variazione
11 - (3) con doppio step sia avanti che indietro
01 - (1) nei casi di decremento
10 - (2) nei casi di incremento
Di li è nata l'idea di fare la decodifica con una prima operazione preparatoria di scambio bit, quindi l'XOR e poi con due confronti successivi ai valori 1 o 2 per decidere se chiamare l'incremento, il decremento o nessuno dei due e ne è nato un primo programma per la lettura di un solo encoder.
Il fatto è che fatta la preparazione dei dati con mascheratura swap dei bit XOR e confronti, non è che ci fosse poi sto gran vantaggio.
Il vantaggio c'è quando invece di farlo per un solo encoder lo devi fare per quattro, perché lo fai in parallello per tutti e quattro. E come detto in post precedente sarebbe ancor più vantaggioso con 16 encoder su un micro a 32bit, dato che a quel punto, essendo l'incremento una sola istruzione, puoi invece di fare una mascheratura, due confronti e due salti condizionati alle somme/sottrazioni, puoi:
Partendo dal bit di ordine zero nella doppia word generata dall'XOR:
-Caricare in un registro dalla variabile counter in memoria
-Con un semplice salto condizionato sul test del bit pari decidere se saltare l'istruzione di incremento del registro
-Fare lo stesso col bit di ordine dispari per decidere se decrementare
-Ricaricare il counter col registro. (con l'Arduino, ma su byte, 8 cicli di clock. Col Teensy non lo so non lo conosco)
.... Procedere così per gli encoder successivi. Velocemente e con poche istruzioni.
Il contesto lo salvi e lo ripristini una sola volta.
Poi se preferisci avere un tempo dedicato alle interruzioni magari sempre il maggiore ma costante e determinato, fai il richiamo di questa routine con un int a tempo, se invece preferisci, per il tipo di gestioni che fai nel loop principale avere un tempo dedicato agli encoder che potrebbe arrivare al max , ma potrebbe anche essere minore quando questi non contano tutti alla massima velocità, la ISR la richiami sul pin-change. Lo valuti tu che sai cosa ti serve.
Ecco quale è stato il mio percorso. Poi dato che è un po il mio carattere, parte la fantasia... ci metti il ModBus e quant'altro, ma alla fine non ho bisogno di fare nulla. Solo il piacere di allenare un po i neuroni.