Come promesso nel mio post di presentazione, posto questo sketch scritto per Arduino UNO con una funzione scritta in Assembly che esegue la lettura continua di tre encoder collegati ai pin da A0 ad A5 sotto forma di 3 variabili long a 32bit e li trasmette al PC tramite la porta USB in modo che possano essere visualizzati tramite il monitor seriale dell'IDE di Arduino.
L'ho testato positivamente con degli encoder NPN da 500 Imp/giro a 5Vdc.
Ho cercato di commentarlo il più possibile (al limite dell'irritante per gli esperti) per renderlo quanto più comprensibile.
In particolare ho spiegato cosa modificare volendo collegare gli encoder ad altri ingressi.
Il suo limite è che gli encoder devono necessariamente essere connessi su due pin adiacenti es. A0 ed A1 per l'encoder1, A2 ed A3 per l'encoder2, A4 ed A5 per l'encoder3.
Quello che mi piace molto è il sistema usato per decodificare le transizioni di stato sugli ingressi, dato che la cosa viene fatta con una sola istruzione in contemporanea per tutti e tre gli encoder.
In fine listato ci sono alcune mie considerazioni circa la possibilità di modificarlo per arrivare a leggere fino a 9 encoder e circa la frequenza massima di lavoro che potrebbe avere.
Mi farebbe piacere fossero confermate o confutate da altri utilizzatori di Arduino.
triplo_encoder_HFx4.ino (16.8 KB)
Ho cercato di commentarlo il più possibile (al limite dell'irritante per gli esperti) per renderlo quanto più comprensibile.
Si forse ma io lo trovato utile, con asm ci ho provato altre volte, ma poi sono tornato sempre al c, qui i commenti sono stati utilissimi.
Si nota come la ISR sono prive di epilogo prologo grazie a "NAKED", cioè nude e tocca al programmatore rimettere le cose a posto all'uscita.
La serial usa il buffer ring e un IRQ sollevata per ogni carattere spedito. Gestire la seriale senza IRQ non penso possa migliorare la cosa.
Cacchio 500 impulsi giri e tanto, ok grazie salvato lo sketch nel caso mi dovessi trovare a gestire qualcosa del genere, almeno so che "si... può... fareeee". 
Ciao.
La scelta di NAKED per la ISR è stata fatta per l'esigenza di ridurre al minimo il numero di cicli impiegati nel salvataggio ed il ripristino del contesto, non sapendo se il compilatore di suo salvi tutti i registri o solo quelli utilizzati. Per lo stesso motivo ho scelto di fare gli incrementi/decrementi in maniera 'brutale' senza nessun indirizzamento indiretto tramite registri. Per gli interrupt della seriale, considera che PCINT1 ha una priorità superiore, quindi se la seriale non impiega troppo tempo, non è limitante per la frequenza, è lei invece ad essere limitata per il numero di caratteri che effettivamente possono transitare, almeno penso sia così. Io a 115200baud col monitor seriale non ho notato problemi. Nei commenti che ho scritto in effetti c'è un errore usando il PORTB, la sequenza in Assembly va modificata dopo la lettura del porta con uno shift di due bit . Perche se si vuole usare la seriale non si possono usare i pin 1 e 2 che sono TX ed RX della seriale HW. Ovviamente vanno rimappati anche gli ingressi per il reset.
P.S. Ieri sera ho provato a scrivere la versione a 9 encoder. Compilazione OK. Devo ancora provarla. Mi piacerebbe integrarla con una libreria Modbus per creare uno slave modbus per la lettura encoder. Magari poi si potrebbe fare pure con l'Ethernet.
Il massimo sarebbe riuscire a farlo in profinet, ma non ne sono all'altezza. Mi sembra però che esista una libreria chiamata settimino che magari si potrebbe usare.
Mi sono esaltato!

Questa volta lo faccio proprio sudare il povero Arduino!

Provato, Funge...
Eccoti la lettura di 9 Encoder.
Gli unici Pin rimasti inutilizzati (si fa per dire perché leggo tramite il serial monitor) sono il pin 1 ed il 2.
Il prossimo passo come detto è integrarlo con la libreria simple Modbus Slave che ho già trovato, dopodiché con 20€ di arduino e uno shield RS485 ti faccio la lettura di 9 encoder da qualsiasi PLC col Modbus.
Quello che mi fa schifo invece è aver fatto una ASM() che sembra un poema.
Ho tentato di usare un array, scrivendo di volta in volta nell'Assembly il singolo elemento, ma non funge, o almeno non so come fare.
In particolare non mi riesce di capire la sintassi per aver i due byte che compongono l'indirizzo della variabile. Ora scrivo semplicemente il nome variabile ed il compilatore me lo sostituisce con l'indirizzo.
Come faccio a farglielo caricare ad es. nel registro Z? Di li poi non sarebbe poi un gran casino lavorare con indirizzamento indiretto e riuscire magari a spostare l'incremento ed il decremento in una routine che unica da chiamare dopo aver caricato nel registro Z l'indirizzo della variabile che di volta in volta devo manipolare. Mi sono letto più volte Inline Assembler Cookbook ma non mi riesce di capire.
Mi date una mano?
nove_encoder_HFx4_v1.ino (25.5 KB)
Gia che c'ero. Ecco la versione con 9 count ma a soli 8bit.
E' un po più breve. 134 cicli per leggere tutti e nove gli encoder.
nove_encoder_HFx4_v1_8bit.ino (11.6 KB)