quale sarebbe il modo migliore per gestire un'encoder incrementale libero ?

Ah, ecco, quindi errore mio, non avrebbe funzionato il mio esempio, probabilmente, perche' non ci avevo pensato mettendole tutte standard ... grazie della spiegazione ...

Etemenanki: le prove che ho fatto io si riferivano a movimenti a mano, quindi boh decine di giri/min ?

Per testarlo, ho montato una manopola con riferimento e l'ho allineato con il corpo dell'encoder, quindi ho azzerato il conteggio ed ho visto che, a seconda delle librerie, un giro vale 25 o 100 passi; poi ho fatto diversi giri a mano sia velocemente che lentamente nei due versi e fermandomi sopra il riferimento, la lettura dava un multiplo dei passi

Non ho provato a collegarlo ad un trapano per vedere come si comporta il codice ad alta velocità; magari cerco degli esempi per un contagiri e se ho tempo e riesco a costruire un accrocchio idoneo, proverò.

Saluti , Valter

Secondo me, come dice il nostro SMS, dipende dai casi.
Ad es. se la velocità della mcu è simile alla velocità di campionamento che ti serve per non perdere passi, va messo tutto nella ISR, altrimenti perdi pezzi con la latenza indotta dal differimento del conteggio all'esterno, cioè nel loop.
Siamo, però, nel caso in cui la MCU fa solo questo e poco altro perchè sempre ad eseguire l'ISR.
Quindi tanto sforzo pressochè inutile pechè non hai tempo per fare altro.

Se hai un po' più di tempo, a mio avviso, il minimo che va tenuto nella ISR è la lettura degli stati e l'elaborazione dell'incremento/decremento, magari su una variabile assoluta da incrementare/decrementare di un passo ad ogni ISR.
Esternamente alla ISR il loop quando arriva elaborerà un certo numero di passi alla volta reperiti confrontando questo valore assoluto con la copia del loop precedente.
La prima cosa che deve fare la funzione nel loop è uno snapshot di questo contatore per fare il resto dell'elaborazione a bocce ferme.
Questo snapshot deve essere doppio, perchè devi anche salvarti il valore che aveva all'elaborazione precedente.
Confrontando lo snepshot con la copia del giro precedente, calcoli quanti passi sono stati fatti dall'ultima elaborazione.
Di fatto metti nella ISR il minimo per rendere atomica la lettura degli stati e fuori elabori N passi alla volta in base alla velocità del loop.

Se ti serve più velocità devi ricorrere a contatori hardware evitando l'isr ma leggendo il valore del conteggio confrontandolo con quello del loop precedente e anche qui elabori N passi alla volta.

In questo modo avrai il loop lento a piacere ma non perderai passi, almeno finchè la velocità sarà compatibile con il tempo di esecuzione dell'isr.

Maurizio

Si, mi sono reso conto che serve considerare tutto quanto caso per caso ... non esiste un solo sistema che vada bene per tutto e che sia migliore di altri ...

Ora mi serve solo trovare un po di materiale da studiarmi sull'accesso diretto alle porte, un po piu completo delle pagine del reference (e qualche flacone di pastiglie per il mal di testa, probabilmente :stuck_out_tongue: :D)

Etemenanki:
Ora mi serve solo trovare un po di materiale da studiarmi sull'accesso diretto alle porte, un po piu completo delle pagine del reference ...

Comincia con quello che allego ... del caro amico leo ... :wink:

Guglielmo

Manipoliamo direttamente le porte logiche di una MCU.pdf (226 KB)

Grazie :slight_smile:

Io ho trovato che il miglior modo per gestire un encoder ad alta risoluzione incrementale pur mantenendo la possibilità di usare il microcontrollore con altre importanti risorse è quello di gestire l'encoder rispondendo con polling su interrupt temporizzato ad alto rate, usando il timer0 con interrupt ciclico a 12uS si può catturare l'encoder a 83khz pur mantenendo liberi int0 e int1 per altri usi importanti come un ingresso step di conteggio proveniente da un motion controller. Bisogna però usare l'assembler non il C, usando l'interruzione annidata, cioè la possibilità di interrompere se stessa sulla risposta di T0 si hanno ulteriori 2 vantaggi: il raddoppio della frequenza di lettura encoder da 83 s 160khz e l'installazione di un RTC ciclico da 1mS o 10mS che dovrebbe essere sempre presente in qualunque programma su microcontroller.
Ripeto tutto dovrebbe essere fatto in assembler, è fattibile in tutti i microcontrollori atmel, e un esempio di tutto cio è descritto nel sorgente disponibile sul famoso sito di Chan, conosciuto come elm, un giapponese che lo ha scritto una quindicina di anni fa e più quando Arduino non esisteva

http://elm-chan.org/works/smc/report_e.html

Lui ha fatto il polling a 104khz ma io sono riuscito a portarlo a 160khz