Corso programmazione PICMicro in C – Approfondimenti – Come utilizzare un encoder in quadratura per l’immissione dei dati

Ho preferito inserire questo articolo nel corso di programmazione come un’appendice e non come un capitolo a sè stante in quanto non tratta strettamente dell’utilizzo di un particolare circuito integrato o di una particolare periferica del picmicro ma piuttosto dell’utilizzo alternativo di altre tecniche già apprese fin’ora (gli interrupt e l’utilizzo dei pulsanti con l’antirimbalzo nella fattispecie). Per tale motivo, per quanto mi sia possibile, ogni tanto inserirò in questo piccolo corso anche qualche “appendice” o se preferite “appunti di utilizzo” per spiegare come fare questa o quell’altra cosa sfruttando cose che già abbiamo imparato.

In quest’articolo impareremo a conoscere uno strumento semplice e molto interessante con cui abbiamo a che fare spesso nella vita di ogni giorno e lo impareremo ad utilizzare come metodo alternativo per l’inserimento o la modifica di variabili al posto dei classici pulsanti.  In più sfrutteremo in contemporanea 2 sorgenti di interrupt le quali si aiuteranno a vicenda nello svolgimento  di un compito.

Molti di voi hanno un’autoradio in macchina, alcuni autoradio (soprattutto modelli di marche famose e di fascia medio/alta) hanno, per la regolazione del volume e dei toni, una manopola che ruota. I più attenti già sanno che quella manopola non è assolutamente il classico potenziometro (altrimenti come mai gira di continuo, senza blocchi? Ok qualcuno potrebbe pure obiettare che esistono i potenziometri a rotazione continua ma dal momento che costano un a cifra non si tratta assolutamente di questo caso). Quella manopola è un congegno davvero semplice ma geniale per alcuni aspetti: si tratta di un encoder rotativo (Rotary Encoder). Una “manopola” del genere la troviamo comunque un po’ dappertutto: ce l’hanno anche alcuni forni a microonde, anche se il suo utilizzo più “in voga” è attualmente quello della regolazione del volume audio negli impianti hi-fi.

Sappiamo bene che un encoder, in senso generale, è un dispositivo che serve per codificare un tipo di segnale in  un’altra “forma”. Un encoder rotativo è appunto un dispositivo che permette di codificare la rotazione di un albero in un segnale elettrico.

Gli encoder rotativi vengono utilizzati, soprattutto in ambito industriale, per il computo delle velocità degli alberi di rotazione. Erano usati nei vecchi mouse con la “pallina” per far muovere il puntatore, sono utilizzatissimi anche in robotica per determinare le velocità delle ruote dei robottini e quindi correggerne la traiettoria, e come abbiamo appena detto vi è anche questo utilizzo più “ludico” per il controllo del volume su un impianto audio o per impostare la temperatura del forno a microonde.

Un encoder rotativo altro non è che una serie di “contatti” (azionati in vari modi: meccanicamente, tramite infrarossi o sfruttando l’effetto hall) che chiudono ciclicamente un contatto quando l’albero ad essi collegato effettua una rotazione. A seconda del numero di contatti e del modo in cui questi vengono chiusi, abbiamo vari tipi di encoder. In questo articolo ci occuperemo unicamente dei cosiddetti encoder in quadratura.

Per capire come è fatto un encoder in quadratura possiamo anche aprire un vecchio mouse di quelli con la pallina: per ogni asse (X e Y) la pallina mette in rotazione una ruota con tante fessure, da un lato di ciascuna ruota ci sono due diodi infrarossi e dall’altro due ricevitori (in genere accorpati in un unico blocco):

MouseEncoder
Immagine prelevata da www.eehomepage.com/report.php?report=20080225

Quando di fronte ad un diodo viene a trovarsi la finestra aperta, il raggio passa mandando in conduzione il ricevitore che gli sta di fronte il quale “chiude” un contatto, quando invece tra la coppia trasmettitore/ricevitore si trova la parte di ruota “piena”, il contatto rimane aperto: all’uscita del sensore avremo quindi un segnale ad onda quadra che è indicativo del movimento che sta effettuando la ruota.

Questo particolare tipo di encoder viene definito “encoder in quadratura” perchè possiede 2 contatti che forniscono due segnali sfalsati di 90°. Ma cosa significa? Cerco di farvelo capire con delle immagini, perchè il concetto è apparentemente complicato ma nella pratica è davvero semplice. Guardiamo questa immagine stilizzata:

encoder_in_quadratura

Abbiamo la ruota sulla quale sono disegnati dei settori: i settori neri fanno rimanere il contatto aperto, i settori bianchi fanno chiudere il contatto, i due quadratini grigi sono i due contatti dell’encoder. Come vedete i due contatti si trovano sulla ruota posizionati su due rette, passanti per il centro dell’asse di rotazione, inclinate tra loro di 90°. Quando la ruota gira, ogni contatto produrrà un’onda quadra (transizioni tra contatto chiuso e contatto aperto). Avendo i due contatti posizionati come in figura, le due onde quadre prodotte saranno anch’esse sfalsate di 90° in questo modo:

encoder_in_quadratura_segnale_sfalsato_90_gradi

Ok, ma a cosa serve mettere due contatti quando per calcolare unicamente la velocità di rotazione di un albero basterebbe un unico contatto? Avete ragione: con un unico contatto sappiamo ogni quanti gradi di rotazione il contatto viene chiuso, e quindi quante volte viene chiuso per un giro di completo di 360°: calcolando il tempo impiegato per effettuare il giro completo, possiamo trovare la velocità di rotazione dell’albero. Se ci serve unicamente sapere la velocità di rotazione un unico contatto potrebbe anche bastare.

Ma… La manopola del volume dello stereo? Non serve certo a calcolare la velocità con la quale la stiamo ruotando! Ha difatti ben altra funzione: se la giriamo in un senso il volume aumenta, se la giriamo nell’altro il volume diminuisce, quindi c’è qualcosa in quella manopola che capisce in quale senso la stiamo ruotando.

E difatti è proprio così. Quella manopola mette in rotazione un albero sul quale è appunto montato un encoder in quadratura come quello che abbiamo visto nell’immagine. La produzione di due segnali sfalsati di 90° permette appunto, oltre che di calcolare la velocità di rotazione (che ovviamente nel caso del volume dello stereo non viene affatto calcolata perchè non serve a nulla), di stabilire anche il verso in cui l’albero sta ruotando. Come?

Innanzitutto diamo un nome ai segnali che escono dai due contatti dell’encoder:  come il buon Guido Ottaviani mi ha insegnato, chiamerò un segnale PULSE e l’altro DIR, il perchè della scelta di questi due nomi, al posto dei classici A e B che in genere si trovano in giro, sarà presto chiaro.

Supponiamo di collegare questi due segnali a due ingressi di un picmicro.  Collegherò un segnale ad un ingresso che mi genera un interrupt (ad esempio al pin RB0 oppure ad uno dei pin da RB4 a RB7) e questo segnale sarà quello che chiamo PULSE, e colleghiamo l’altro segnale, DIR, ad un ingresso che non genera interrupt, quindi ad un ingresso qualunque.

Ruotiamo l’albero. Ad un certo punto scatterà un interrupt perchè il contatto che fornisce il segnale PULSE passa da  aperto a chiuso (o viceversa, insomma: cambia stato logico). A questo punto intercettiamo l’interrupt e confrontiamo il livello logico attuale del segnale PULSE con il livello logico attuale del segnale DIR: sta qui la “magia”!

Se entrambi i livelli logici sono uguali (entrambi alti o entrambi bassi), possiamo dire che l’albero sta ruotando in un senso (possiamo dire che l’albero sta ruotando in senso orario oppure che il nostro robottino si sta muovendo in avanti), se invece i due livelli logici sono differenti, allora l’encoder sta ruotando in senso antiorario (o il nostro robottino sta camminando all’indietro).

Un’immagine dovrebbe far capire cosa accade nella pratica:

encoder_in_quadratura_segnali_avanti_e_indietro

Ho evidenziato in viola l’istante in cui scatta l’interrupt, ovvero l’istante in cui il segnale PULSE effettua il cambio di livello logico. Notiamo inoltre come i due segnali DIR e PULSE siano sfalsati tra loro di 90° come detto in precedenza. Ruotando in avanti, al verificarsi dell’interrupt, i due segnali hanno sempre il livello logico uguale tra loro, ruotando all’indietro, invece, i livelli logici sono sempre opposti. Chiamo appunto PULSE il segnale che mi genera una “pulsazione”, ovvero l’interrupt, e DIR l’altro che mi serve per poterlo confrontare e stabilire quindi la DIRezione di rotazione.

Bene, passiamo ora ad un’applicazione pratica: sfruttiamo un encoder per incrementare/decrementare una variabile.  Questo sistema lo potete utilizzare per qualsiasi applicazione che richieda due pulsanti up/down: l’utilizzo di un encoder è sicuramente molto più professionale: un controllo di volume, la regolazione di un livello, di una temperatura, di un tempo, il posizionamento di un servocomando…

Per questo “esperimento” ho utilizzato un encoder rotativo meccanico di fascia economica ma che fa in maniera eccellente il suo lavoro. Tale encoder esternamente si presenta come un comune potenziometro ed in più ha anche un contatto che si chiude quando l’alberino viene premuto verso il basso:

encoder_rotativo_in_quadratura

Questo tipo di encoder nell’immagine è davvero economico (l’ho trovato su Ebay in Inghilterra per meno di 3 euro, ma se lo acquistate in Cina, e soprattutto se avete la pazienza di aspettare un mese, ne potete portare a casa ben 10, completi di manopole, per circa 10/12 euro). Come potete vedere è davvero molto piccolo, per tale motivo l’ho messo a confronto con la moneta da 2 euro, difatti quando mi è arrivato a casa sono rimasto un po’ smarrito perchè mi aspettavo qualcosa di un po’ più grande, almeno quanto un potenziometro.

encoder_rotativo_in_quadratura_2

Vi sono due ganci laterali per l’ancoraggio allo stampato, i tre pin vicini sono quelli dell’encoder (il centrale è il comune e i laterali sono i due contatti), gli altri due pin di fronte a quelli dell’encoder sono quelli del pulsante normalmente aperto, che si chiude premendo l’alberino. Ho visto che la nota marca PIHER (che produce potenziometri, trimmer, switch ecc) ha in catalogo un encoder molto simile a questo, lo potete vedere in questa pagina. Quello della Piher ha la stessa, identica, piedinatura e forma (non ho verificato le dimensioni).

Dovremo trattare i segnali dei due contatti dell’encoder come se fossero un normale pulsante. Trattandosi di un’encoder meccanico, la chiusura dei contatti non è pulita per cui dovremo tener conto di dover attuare anche qualche meccanismo di antirimbalzo. Utilizzando invece encoder ottici o magnetici la chiusura del contatto è pulita e quindi non dovremo preoccuparci dei rimbalzi.

Faremo arrivare il segnale di massa al comune  e i due segnali forniti dai contatti saranno applicati a due ingressi del picmicro tramite le solite resistenze di pull-up. Ovviamente dobbiamo ricordarci di collegare un segnale ad un pin che produce interrupt (lo collegheremo ad RB0) e l’altro ad un pin qualsiasi: questo concetto è essenziale. Ho montato da subito l’encoder su un pezzetto di millefori collegandovi sopra tutto l’occorrente: uno strip di contatti a 90° per la connessione con una breadboard o con il circuito di utilizzo, le resistenze di pullup (anche per il pulsante, che però in questa prova non userò) e un piccolo condensatore sull’alimentazione:

encoder_montato

Sul datasheet della Piher è consigliato l’utilizzo di due piccoli condensatori da 10nF sui due terminali dei contatti, verso massa. Per questa prova personalmente non li ho montati, anche perchè l’encoder della piher l’ho scoperto solo dopo aver fatto le prove, se fate questo circuito, montateli.

Lo schemino del circuito in foto è molto semplice:

schema_circuito_encoder

Anche se penso di essere stato abbastanza chiaro, vi espongo comunque il layout dell’encoder (prelevato dal datasheet della Piher e uguale a quello comprato su Ebay) per maggior completezza:

layout_encoder

Quindi ricapitolando: i due segnali che dovranno arrivare al pic sono quelli uscenti dai pin contrassegnati come A e B sullo schema dell’encoder, quello che collegate al pin RB0 (è indifferente: potete collegare o l’A o il B) lo chiameremo PULSE e l’altro lo collegheremo al pin RB1, quest’ultimo non scatena interrupt e ci serve per poterlo confrontare con l’altro segnale e poter quindi capire la direzione di rotazione, per cui lo chiameremo DIR. Il pulsante che si aziona premendo l’alberino, presente sui contatti E e D, non verrà usato in questa prova. Se voi lo volete usare, sapete come fare.

Il software che ho scritto esegue la funzione di base di un encoder in quadratura: la rotazione in senso orario incrementerà una variabile, la rotazione in senso antiorario invece la decrementerà, per dimostrarne il funzionamento  il valore della variabile sarà mostrato su un display LCD compatibile Hitachi HD44780. Il circuito che ho utilizzato è lo stesso della lezione 7, al quale ho ovviamente tolto i 4 led e i 3 pulsanti (insomma tutta la parte destra del circuito), rimangono quindi di quello schema solo il display e il cicalino.

Dal momento che ho utilizzato la demoboard Freedom 2, nel codice troverete un define diverso per il cicalino e la presenza di un define per abilitare la retroilluminazione dell’LCD: se usate la Freedom 2 non dovete fare modifiche al codice, altrimenti basta cambiare un paio di define del file settings.h

Lato software, dal momento che abbiamo capito come funziona un encoder in quadratura, non dovremo far altro che intercettare l’interrupt su RBO e fare le opportune considerazioni: confrontare il segnale che ha scatenato l’interrupt con l’altro: se i due segnali hanno lo stesso livello logico, mi setterò una variabile che nel main mi produrrà un incremento e viceversa:

void interrupt ISR (void)
	{
	if (INTF) // L'interrupt è stato causato da un cambio di stato di RB0/INT ?
		{
		if (ENCODER_PULSE==ENCODER_DIR) // rotazione oraria
			{
			INTE=0; // disattivo l'interrupt su RB0/INT
			mode=INCR; // modalità incremento
			ABcounter=0; // resetto contatore
			}
		else // rotazione antioraria
			{
			INTE=0; // disattivo l'interrupt su RB0/INT
			mode=DECR; // modalità decremento
			ABcounter=0; // resetto contatore
			}
		INTF=0; // Resetto il flag interrupt su RB0/INT
		} // fine che interrupt verificatosi su RB0/INT

In realtà avrei potuto gestire l’incremento e il decremento della variabile anche nella stessa routine di interrupt, ma come vedete non l’ho fatto per vari motivi:

  1. Le routine di interrupt, come ripetuto tantissime volte, devono essere le più snelle possibile.
  2. Stiamo gestendo un encoder meccanico, per cui dobbiamo inventarci un sistema per effettuare un antirimbalzo via software. Dal momento che l’antirimbalzo via software prevede un ritardo, non possiamo assolutamente gestirlo nella routine di interrupt.

Per tale motivo ho previsto un counter (ABcounter) che viene incrementato dall’interrupt sul Timer0 e che mi serve a creare un ritardo nel main. Appena scatta l’interrupt sul pin RB0/INT, disattivo subito l’interrupt (INTE=0) per non intercettarne due successivi (come detto prima: l’encoder usato è molto economico!), mi setto una variabile (mode) che nel main mi attiverà una routine per incrementare o decrementare il valore della variabile, e azzero il contatore (ABcounter) che mi blocca il controllo del successivo interrupt per un tempo stabilito nel main. Spulciatevi il codice per vedere cosa accade. Suppongo che questa non sia la migliore gestione dell’antibounce, ma mi è venuta  al volo funzionando in maniera abbastanza soddisfacente: senza essa, difatti, l’encoder produceva degli incrementi/decrementi a volte esagerati. Penso anche che l’utilizzo dei due condensatori sui terminali di uscita dell’encoder migliori ulteriormente la situazione.

Gli iscritti possono scaricare il codice di esempio:

Corso Programmazione PICMicro in C - Approfondimenti - Utilizzo di un encoder rotativo per l'immissione dei dati (667)

Consigli e suggerimenti

Nel caso in cui si voglia collegare più di un encoder (ad esempio: un robottino per il quale dobbiamo verificare la velocità e il verso di rotazione delle due ruote), dovremo fare affidamento al cambio di interrupt sulle porte RB4/RB7, abilitando il flag RBIF. Possiamo collegare un segnale pulse ad RB0 e quello dell’altra ruota ad uno dei pin RB4-RB7 o entrambi a due pin di RB4-RB7. In quest’ultimo caso dovremo predisporre altre variabili per memorizzare lo stato precedente dei segnali per poter capire quale dei due encoder ha scatenato l’interrupt dal momento che uno qualsiasi dei pin RB4-RB7 scatena l’interrupt.

Se volete realizzare un encoder per le ruote del vostro robottino potete anche utilizzare il sensore P5587 prodotto dalla Hammamatsu, che è molto piccolo ed adatto appunto a fare questo lavoro, ovviamente sulla ruota dovrete predisporre un disco con settori bianchi e neri in quanto tale sensore lavora per riflessione. Per realizzare un encoder in quadratura avrete bisogno di due sensori per ruota.

Se volete approfondire il discorso sugli encoder, la rete è piena di esempi appunto perchè in robotica gli encoder sono uno strumento davvero necessario. Posso consigliarvi di cominciare da questa voce su wikipedia in inglese (la versione in italiano è piuttosto scarna).

Puoi andare alla fine dell'articolo e lasciare un commento. I trackback e i ping non sono attualmente consentiti.

  1. #1 da piero il 28 giugno 2010

    Giovanni,

    ho trovato per caso questo tuo Blog googlando.
    Partendo da questo approfondimento sugli encoder ho scoperto le altre cose interessantissime e non ho esitato ad iscrivermi.
    Complimenti per l’impegno e i risultati. Approfitto di questo spazio per salutare tutti, dato che non vedo nessun posto dove fare le presentazioni.

    Cerchero’ di farmi vivo ogni tanto.

    In gamba,

    Piero

  2. #2 da vittorio il 25 luglio 2010

    sono a livello 0 in programmazione di pic e bestioline simili,ai miei tempi non esistevano,pero’ devo dire che sei riuscito a risvegliarmi un po’ di interesse per gli encoder.
    grazie e buon proseguimento
    vittorio

    • #3 da Giovanni Bernardo il 25 luglio 2010

      Salve, è un piacere avere un commento da un grande come lei. Ho visitato il suo sito e l’ho trovato molto interessante. Complimenti vivissimi per la vasta collezione di radio, che ritengo sia davvero invidiabile. Anche io adoro le radio antiche (ma purtroppo non ne capisco molto), soprattutto quelle valvolari. Ho avuto l’enorme piacere di ripararne una, con non poca fatica, appartenente ad un mio zio che oramai non c’è più, e che ora tengo bella esposta nel soggiorno, perfettamente funzionante. Sono pezzi di storia, che rievocano bei tempi andati, tempi in cui la semplicità ancora destava meraviglia e stupore.

  3. #4 da odessos il 13 febbraio 2011

    ho un encoder che fornisce un inpulso ogni 10gradi di rotazione, quindi sono 36 impulsi a giro.
    Ho la necessità di creare una funzione per calcolare la velocità di rotazione del motore. premetto che il programma utilizza già l’interrupt per altri scopi, e non posso rallentare l’esecuzione del programma utilizzando routine con Delaytime troppo lunghi. come posso fare? devo utilizzare un’altro PIC?
    salutissimi e grazie di tutto.

    • #5 da Giovanni Bernardo il 14 febbraio 2011

      Il programma usa già gli interrupt sul portb change? Se no, quale sarebbe il problema di usare l’interrupt pure per l’encoder? Se si: hai già tutte e 4 le porte B occupate?

  4. #6 da odessos il 14 febbraio 2011

    perchè uso il Timer0 per generare un segnale che pilota un motore passo passo, se leggo un,altro interrupt mi interrompe quello del Timer0, oppure si possono gestire in maniera indipendente?
    forse con un PIC serie 18F?

    • #7 da Giovanni Bernardo il 14 febbraio 2011

      Se il problema fosse questo i picmicro sarebbero andati nel dimenticatoio da un pezzo… I PIC16 gestiscono gli interrupt in sequenza, se mentre gestisci il TMR0IF si verifica un altro interrupt, non accade nulla: la ISR continua a servire il TMR0IF e quando ha finito serve l’altro. Sui PIC18 puoi impostare la priorità alta o bassa: se mentre servi un interrupt a bassa priorità si verifica uno ad alta priorità, quello a bassa viene messo in pausa e lo si torna a servire quando si è finito di servire quello ad alta. Altrimenti di default i pic18 hanno la gestione degli interrupt in modalità pic16-compatibile. Il problema per la tua applicazione non sussiste e tutto dipende da quanto rendi veloci le ISR. Se ti serve un calcolo davvero preciso della velocità, senza possibilità di errore, allora dovresti usare un pic18 con la priorità alta sull’encoder e bassa sul timer. Metti che sul pic16 ti scatta prima un interrupt sull’encoder mentre servi TMR0, e poi ne scatta un altro quando ancora non hai finito con TMR0: ovviamente ti perdi il secondo perchè il flag è già stato settato dal primo. Ma questo può accadere solo se “perdi tempo” in TMR0 e se la velocità di esecuzione è bassa.. Insomma dovresti farti due conti di quanto è la velocità massima del motore per capire ogni quanto ti scatta un interrupt sull’encoder e capire se ce la fai a gestire tutto. Io direi fai una prova, ma non preoccuparti perchè di interrupt ne puoi gestire quanti ne vuoi, cerca solo di lavorare alla massima frequenza possibile col quarzo e di rendere le ISR più snelle possibile.

    • #8 da Giovanni Bernardo il 14 febbraio 2011

      Se poi vuoi fare le cose piu complicate ma meglio, ci sono alcuni pic, anche della serie 18 che hanno la periferica QEI (Quadrature Encoder Interface) che come potrai capire gestisce tutto lei, indipendentemente dal resto. Ma non ci ho mai messo mano quindi non so dirti di più.

  5. #9 da Haru il 13 giugno 2011

    esistono anche degli encoder che invece di essere in quadratura mandano il bit sull’uscita in base al senso di rotazione? (tipo danno un impulso ogni 10 gradi di rotazione su una delle due uscite in base alla rotazione)

    perchè fino a 5 minuti fa pensavo funzionassero così :D

  6. #12 da Aigor il 4 agosto 2011

    In odore di sperimentazione ho cercato qualcosa sugli encoder e ho trovato, googolando, un sistema per usare i motori dei dischi rigidi come encoder, sperando di non violare qualche regola, ecco il link
    http://www.instructables.com/id/HDDJ-Turning-an-old-hard-disk-drive-into-a-rotary/step4/Amplifying-the-output/

  7. #13 da Haru il 21 agosto 2011

    è possibile collegare ad un pic gli encoder senza utilizzare l’interrupt? il mio problema è che ho tipo una ventina di encoder usati come manopole da controllare, ed è evidente che RB0 non mi basta… qualche consiglio?

    • #14 da Giovanni Bernardo il 21 agosto 2011

      Beh si… Te li controlli in Polling ma se non hai un Tcy abbastanza elevato non so se ce la fai a controllarti tutto.

      • #15 da Haru il 22 agosto 2011

        Tecnicamente avrei il pic che fa solo quel lavoro, l’unica altra funzione che ha è quella di inviare i dati ricavati dagli encoder tramite uart o spi (devo ancora vedere per quello).
        Per la serie nessun rallentamento dovuto a display o led, nel ciclo metto solo il controllo di ogni porta e in base allo stato precedente verifico se è stato spostato o meno, giusto?

        Un’altra cosa: dici sia meglio cloccarlo a 20MHz o gli 8 dell’oscillatore interno possono bastare?

  8. #16 da Faustino il 10 dicembre 2011

    Ciao Giovanni e a tutti
    dovrei fare qualcosa del genere, ti citerò nei commenti della sorgente :).
    Ho un encoder assoluto ottico e su due uscite ci sono le onde in quadrature citate, più un’altra uscita che mi da un impulso ogni giro. Ci sono 1000 impulsi per giro ma ce ne possono essere anche 24000 impulsi per giro (dipende dal modello).
    Per giocare ho preso quello da 1000. il data sheet mi dice che ha una banda massima di 200kHz, ovvero un impulso non può durare meno di 2.5 us. Guardando con l’oscilloscopio effettivamente, siamo lì. Al momento pensavo a far gestire la velocità a livello hardware con un convertitore frequenza-tensione e dare in pasto l’uscita al ADC del PIC, questo perchè ho il timore che non ci stia dietro. La mia idea è di interrogare da pc con comunicazion USB o RS488 per interrogare il pic su velocità, angolo e giri compiuti.
    un interrupt ad alto livello per “intercettare” l’impulso dell’angolo un secondo interrupt a basso livello per la comunicazione seriale. il mio timore è uno, domanda: se tramite hyperterminal chiedo la velocita’, con un comando ad esempio “speed”, il pic riconosce un interupt a basso livello e mentre trasmette se allo stesso tempo riceve un interupt ad alto livello, cosa succede? il pic sicuramente da’ la precedenza all’interupt ad alto livello, ma a livello di comunicazione, si interrompe? c’è il rischio che l’utente non riesca a comunicare a meno che l’encoder vada a una velocità sufficientemente bassa? o tutto avviene in “parallelo”?
    Grazie Fausto

  9. #18 da danielone il 19 dicembre 2011

    Buondì Giovanni!
    Ringraziare per i tuoi articoli è poco.

    Ho usato questo componente:
    http://www.knitter-switch.com/pdf_en_prod11/encoder_seriesMER12.pdf (vedi quello a pagina 8)
    per implementare il tuo progetto, facendo un porting su PIC18F45K22. Pulse è collegato ad RB7 e dir ad RB6. L’interrupt è scansito solo su RB7.

    In uscita visualizzo la variabile su un display 7seg a 4 digit comandato via SPI da un max7219.

    Ho sperimentato questi 2 problemini:
    1) L’encoder funziona solo in decremento…in incremento non va. Che sia colpa del componente?
    2) Circa ABcounter ho sperimentato il passaggio da Fosc a 20Mhz come il tuo progetto ad 8Mhz nel mio. Tramite il tuo programma PIC timer ho quindi impostato il prescaler ad 1:8 (anziché 1:32) e TMR0L a 6 (anziché a 100) per ottenere l’overflow ogni 1ms. Di fatto capita che il sistema risponda con una lentezza allucinante all’input dell’encoder e ruotando velocemente proprio non funzioni. Sospetto a questo punto che 8Mhz sia una frequenza troppo bassa per gestire correttamente il tutto.

    Ne approfitto anche per segnalarti che cliccando al link che indichi per l’encoder Piher (i cui dati ho cercato di consultare per verificare se effettivamente butta fuori un segnale diverso dal mio encoder…anche se non mi pare) si viene mandati su una pagina non più esistente.

    Cari saluti!

    Daniele

  10. #19 da danielone il 19 dicembre 2011

    Dimenticavo di aggiungere quella che potrebbe essere una soluzione hardware al problema di debounce. Non l’ho provato ma lo proverò. Utile magari se si vuole usare l’encoder in polling senza inserire ritardi.

    http://www.onsemi.com/pub_link/Collateral/MC14490-D.PDF

Devi essere collegato per lasciare un commento.

  1. Ancora nessun trackback
Settorezero.com e il logo Zroid™ ©2007÷2017 Giovanni Bernardo - E' vietata la copia e la distribuzione anche parziale dei contenuti di questo sito web senza l'esplicito consenso dell'autore. I contenuti di settorezero.com sono distribuiti sotto una licenza Creative Commons Attribuzione-Non Commerciale-Non Opere derivate 2.5 Italia e sono soggetti alle condizioni definite nel disclaimer. Settorezero.com e tutti i suoi contenuti sono tutelati dalla legge sul diritto d'autore per cui i trasgressori sono perseguibili a norma di legge. Settorezero fa uso dei cookie leggi l'informativa estesa. Il tema di questo sito è basato sul tema Fusion per wordpress, realizzato originariamente da digitalnature e fa uso del plugin Wassup per il computo delle statistiche. Per contattare l'autore siete pregati di utilizzare la sezione contatti. Siamo presenti anche su Facebook e, meno assiduamente, anche su Twitter - Tumblr - Google+ - Blogspot - Youtube.
Creative Commons BY-NC-ND 2.5