Domanda:
Come interfacciare un encoder in quadratura con PIC?
Bergamin
2012-05-10 03:08:36 UTC
view on stackexchange narkive permalink

Sto sviluppando un prototipo che utilizza un codificatore di quadratura per misurare il suo spostamento lineare. L'encoder è attaccato al corpo del prototipo e ha una ruota nel suo albero. Quando il prototipo si sposta in avanti, l'encoder misura la distanza lineare. Tutti i problemi intorno alla conversione tra unità lineari / angolari sono stati risolti.

Il motivo per misurare la distanza con un encoder è che DEVO sapere ogni volta che il prototipo ha percorso esattamente 1 mm (1 millimetro = 0,0393 pollici). Ogni volta che si sposta di 1 mm, PIC attiva un altro sistema.

Il modo in cui è stato fatto prima che iniziassi a lavorarci è leggendo l'encoder con un PIC (16F688) nelle sue porte I / O. Era un po 'ok, ma quando ho aggiunto alcune funzionalità al codice PIC, se la velocità lineare del prototipo è maggiore di ~ 1,77 in / s (~ 45 mm / s) il PIC inizia a perdere il conteggio dell'encoder.

I ho provato a utilizzare IOC (interrupt on change) dalla porta A per leggere il segnale di quadratura (canali A e B) ma non è stato efficace.

So che ci sono dsPIC ma devo risolvere questo problema nella mia scheda e ho solo 14 pin per farlo lol. Quindi ho trovato questo PIC16F1825 che ha una frequenza più alta (4x). Potrebbe essere questo (il mio PIC basso freq) il mio problema principale ??

Stavo pensando di utilizzare i segnali LFLS7183 UP / DOWN con il timer / contatore da PIC o altro contatore IC in modo che ridurrebbe la quantità di segnalazione al PIC. Funzionerebbe? Quale contatore dovrei usare? Non ho 8 pin nel mio PIC da usare come in quei http://goo.gl/2Wc3d.

Il mio codificatore non è un mio problema, ho controllato e può tracciare fino a 76 piedi / s per il raggio della mia ruota.

Di quali frequenze stai parlando? Quanto velocemente cambia l'encoder e quanto velocemente corri il tuo orologio MCU?
Sei risposte:
Olin Lathrop
2012-05-10 17:03:09 UTC
view on stackexchange narkive permalink

Hai tralasciato le informazioni più importanti su quanto velocemente arriveranno gli impulsi, quindi presumo che i casi peggiori siano ancora abbastanza lenti da essere rilevati dal firmware scritto correttamente.

I hanno trovato alcuni trucchi per eseguire la decodifica in quadratura nel firmware:

  1. Non cercare di catturare le modifiche individuali, invece interroga a intervalli regolari. Si supponga che l'encoder possa rimanere bloccato proprio sulla transizione per qualsiasi fronte e che quindi possa rapidamente dithering. Questo creerebbe un pasticcio di qualsiasi interruzione sulla tecnica di modifica.

    Con il polling regolare, puoi regolare attentamente il sistema per quanto tempo vuoi spendere nella routine di interruzione. Anche il limite superiore della velocità dell'encoder è ben noto, e comunque non è più lento del caso peggiore con il metodo di interruzione al cambio. Il metodo di polling è garantito per funzionare correttamente fino a una certa velocità massima di movimento che puoi facilmente calcolare. Il metodo di interruzione in caso di modifica si degrada in modo imprevedibile poiché si verificano rimbalzi sulle transizioni.

  2. Decodifica sempre la posizione 4x completa. Non cercare di essere sveglio e fare cose stupide come contare +1 quando A transita mentre B è alto, ecc. Queste "scorciatoie" sono in realtà più difficili da implementare e hanno casi angolari che ti mettono nei guai. Anche se i livelli superiori vogliono conoscere la posizione solo per un singolo ciclo completo, ti tieni fuori dai guai decodificando la nuova posizione da ogni cambiamento di stato.

  3. Decodifica utilizzando una tabella di ricerca. Ad ogni interrupt, si scatta un'istantanea dello stato corrente delle due linee dell'encoder. Questo insieme all'istantanea dell'interrupt precedente è di 4 bit di dati. Dallo stato precedente e dal nuovo stato puoi dire se il conteggio 4x è rimasto lo stesso o è aumentato o diminuito 1. Poiché ci sono solo 16 casi possibili, puoi usarli per inviare da una tabella. Ci sono 4 casi in cui ciascuno rimane lo stesso, +1 e -1.

    Ci sono anche i 4 casi in cui il conteggio è cambiato di 2 che richiedono una gestione speciale. Un cambiamento di 2 significa che una transizione è stata persa e l'encoder si sta muovendo rapidamente. Guardando solo il vecchio e il nuovo stato, non sai se è andato avanti di mezzo ciclo o indietro. Nota che 1/2 ciclo è un conteggio di +2 o -2 in questo sistema. Il modo in cui gestisco questo è mantenere un'ultima bandiera di direzione conosciuta. Il codice che fa +1 e -1 imposta questo flag in base alla direzione nota. Quando si ottiene un passaggio di 2, si presume che vada nella stessa direzione dell'ultimo passaggio di 1. Questa è un'ipotesi piuttosto buona considerando l'inerzia dei sistemi meccanici reali.

    In realtà quindi si hanno davvero 5 bit di informazioni per elaborare ogni interrupt, i 2 livelli di linea dell'encoder precedenti, i nuovi livelli di linea dell'encoder e l'ultima direzione nota. Quindi, per la massima velocità, rendi questa tabella a 32 voci e gestisci ogni possibile caso con codice esplicito. Il codice per ciascuno dei casi aggiunge da -2 a +2 alla posizione corrente ed eventualmente aggiorna il flag di direzione noto.

Come puoi vedere, solo sono necessarie alcune istruzioni per ogni interrupt di polling. Il tuo PIC (16F1825) può funzionare fino a una frequenza di clock di 32 MHz, che è una frequenza di istruzioni di 8 MHz. Supponiamo che tu imposti un interrupt ogni 50 istruzioni, che è ben più del necessario per fare ciò che ho descritto sopra. Ciò significa che puoi eseguire il polling a 160 kHz. Poiché l'encoder può cambiare fino a 1/2 ciclo per interrupt, questo supporta fino a 80 kHz di velocità di ciclo completo dell'encoder.

tcrosley
2012-05-10 04:10:25 UTC
view on stackexchange narkive permalink

Recentemente ho realizzato un progetto simile utilizzando un microcontrollore Freescale. Ho utilizzato la capacità di acquisizione del timer per catturare l'ora degli eventi, senza dover fare affidamento su un interrupt che si verifica (ad es. Interrupt su cambiamento) proprio quando si è verificato l'evento. La tua routine di interrupt legge e memorizza solo un valore del contatore, e il resto del calcolo è a cupola nel codice di livello base.

Ho controllato e anche il PIC16F1825 ha questa capacità. Sezione 24.1 (Modalità di acquisizione) del foglio dati che ho scaricato:

La modalità di acquisizione utilizza la risorsa Timer1 a 16 bit. Quando si verifica un evento sul pin CCPx, la coppia di registri CCPRxH: CCPRxL a 16 bit acquisisce e memorizza il valore a 16 bit della coppia di registri TMR1H: TMR1L, rispettivamente. Un evento è definito come uno dei seguenti ed è configurato dai bit CCPxM<3: 0> del registro CCPxCON:

• Ogni fronte di discesa

• Ogni fronte di salita

• Ogni 4 fronte di salita

• Ogni 16 fronte di salita

Quando viene eseguita una cattura, viene impostato il bit CCPxIF del flag di richiesta di interrupt del registro PIRx. Il flag di interruzione deve essere cancellato nel software. Se si verifica un'altra cattura prima che il valore nella coppia di registri CCPRxH, CCPRxL venga letto, il vecchio valore catturato viene sovrascritto dal nuovo valore catturato.

Devi comunque gestire i valori catturati velocemente abbastanza per evitare di perdere un evento.

narendra
2012-09-06 21:54:34 UTC
view on stackexchange narkive permalink

Utilizzare la porta B per rilevare il cambio di fronte per gli impulsi dell'encoder. È necessario gestire il software per la lettura degli impulsi se l'encoder ruota in senso orario o antiorario.

AngryEE
2012-05-10 03:48:07 UTC
view on stackexchange narkive permalink

Il tuo problema è che gli interrupt di cambio pin generati dal codificatore si verificano troppo velocemente perché il tuo software possa gestirli. Ciò è probabilmente dovuto al fatto che il gestore degli interrupt funziona troppo a lungo. La sequenza di eventi è probabilmente qualcosa del tipo:

  1. Spostamenti dell'albero
  2. Il codificatore produce un fronte di salita
  3. Si verifica un'interruzione del cambio di pin
  4. Il gestore degli interrupt cambia pin inizia
  5. L'albero si sposta di nuovo prima che il gestore degli interrupt sia finito
  6. Viene generato un altro interrupt, ma non gestito perché stai ancora gestendo l'ultimo
  7. Il gestore degli interrupt di cambio pin termina, cancellando il flag di interrupt
  8. Il secondo interrupt non viene mai gestito

È così che perdi gli interrupt ad alta velocità - l'interruzione successiva si verifica prima di te " hai finito di gestire il primo e non viene mai gestito.

Primo, non dovresti fare nulla che richieda molto tempo in un gestore di interrupt. I gestori di interrupt dovrebbero essere il più brevi possibile per evitare il problema che stai vedendo in questo momento. Probabilmente stai cercando di fare tutto sotto il sole nel tuo gestore. Non farlo.

In secondo luogo, dovresti passare a un metodo meno pesante di software per leggere il codificatore. Se hai un timer gratuito puoi usarlo per misurare lo spostamento del tuo albero. Se non ti interessa la direzione o la velocità dell'albero , puoi misurare lo spostamento del tuo albero a intervalli di 1 mm procedendo come segue:

  1. Calcola il numero di conteggi dell'encoder sono in 1 mm. Si spera che sia un numero abbastanza grande - circa 100
  2. Collega l'encoder a un segnale di clock esterno di uno dei tuoi timer - sul 16F88 è probabilmente preferibile utilizzare il Timer 1 poiché può funzionare come contatore .
  3. Configura il timer per funzionare come un contatore, essere pilotato dall'orologio esterno e per interromperlo in caso di overflow.
  4. Carica il registro del conteggio del timer con un valore di MAX - (# di encoder conta in 1 mm). Il timer 1 è un timer a 16 bit, quindi MAX è 0xFFFF.
  5. Avvia il timer e abilita gli interrupt.
  6. Ogni volta che il tuo timer va in overflow, nel gestore, ricarica il registro di conteggio con il valore originale di MAX- # conta in 1 mm

Ora, ogni volta che il tuo timer si interrompe, il tuo albero lo farà si sono spostati di 1 mm. Questo non è perfetto: si preoccupa solo che il tuo albero si muova di 1 mm ma non ha idea in quale direzione si sia mosso l'albero o quanto velocemente stia andando. Questo è, tuttavia, un metodo semplice e veloce per ottenere un'interruzione ogni volta che l'albero si sposta di 1 mm in qualsiasi direzione.

La maggior parte degli encoder in quadratura può oscillare mentre è a riposo, questo farà sì che il tuo timer conti falsi cambi di posizione. Tuttavia, se decodificata correttamente, questa oscillazione di solito non ha effetti negativi.
Non dovrebbe collegare i pin dell'encoder agli ingressi che generano interruzioni. Usa il CCP e controlla la direzione, usa un contatore avanti / indietro e leggi il conteggio, oppure usa un interrupt del timer e cerca i cambiamenti di stato della quadratura.
Può essere eseguito in modalità di acquisizione dati in tempo reale o in modalità evento IRQ asincrono, in entrambi i casi l'UC ha bisogno di velocità sufficiente per contare l'evento in tempo reale. Il punto è che il problema non è stato specificato, quindi qualsiasi consiglio è incerto per chiunque possa dare una soluzione perfetta. Il passaggio # 1 definisce gli input, la velocità e gli stati
da quanto ho capito, 45 mm / sa 1 mm per evento è di 45 pps, la velocità di input è dannatamente lenta. C'è qualcosa di sbagliato nel suo codice che non tiene conto di questi eventi .. Credo che sia dovuto alla mancanza di memoria degli eventi e che debba essere bloccato. Non sappiamo perché l'evento è andato perduto. in quel periodo di 22 ms (1 / 45pps) Ma non conosciamo l'esatta natura di questo segnale, ad esempio se c'è isteresi ecc come dovrebbe esserci per 1/4 di un ciclo di quadratura. Se il codice può richiedere più di questo tempo. allora certamente deve essere pilotato in modo sincrono (es. frequenza di 15 ms) se le routine non possono essere interrotte. (cattivo design)
Malife
2012-05-10 09:33:35 UTC
view on stackexchange narkive permalink

So che hai detto esplicitamente che hai solo 14 pin per risolvere il tuo problema, ma non capisco se questo sia correlato alla quantità di stato reale che hai sul PCB o se questa è una scheda legacy. Se ciò è dovuto allo stato reale, potresti usare un dsPIC33FJ12MC201, che è una parte a 20 pin, non molto lontano dal tuo limite di 14 pin, e include un modulo QEI che ti semplificherebbe la vita ; forse puoi spremere questa parte nella tua tavola.

Spero che questo ti aiuti.

Tony Stewart Sunnyskyguy EE75
2012-05-10 04:07:31 UTC
view on stackexchange narkive permalink

Il tuo PIC era semplice?

  • Calcola il salto basato sul valore di quadratura

  • restituisci +1 o -1 o 0

  • quindi aggiungi al valore attuale.

Dovrebbe essere in grado di gestirlo, penso ...

.... eventuali metastati? quindi bloccare i valori di input.

Se ancora nogo. Quindi utilizzare un CPLD con contatori su / giù e spostarsi su PIC su un pin I / O seriale. Scegli binario o decimale come desideri.

Nel 1978, ricordo un piccolo aspetto di un importante progetto di un sistema di ispezione robotica a correnti parassite per il sistema di scambiatore di calore secondario Candu, ho aiutato a progettare. la sonda a correnti parassite è stata tracciata ogni 0,1 mm lungo il tubo a velocità che penso fossero fino a 5000 mm al secondo e le letture dell'impedenza della sonda in quadratura a 12 bit sono state combinate con la posizione della sonda presa da un semplice encoder rotativo in quadratura come il tuo. Abbiamo utilizzato hardware personalizzato e un 6800 mpu. Se il tuo progetto è troppo lento, procurati gli strumenti giusti per il lavoro. Ma non dare per scontato. Creare un impulso di uscita ogni ISR ​​e controllarlo.


Questa domanda e risposta è stata tradotta automaticamente dalla lingua inglese. Il contenuto originale è disponibile su stackexchange, che ringraziamo per la licenza cc by-sa 3.0 con cui è distribuito.
Loading...