Sommario:

Come interpretare la direzione di rotazione da un commutatore rotante digitale con un'immagine: 5 passaggi
Come interpretare la direzione di rotazione da un commutatore rotante digitale con un'immagine: 5 passaggi

Video: Come interpretare la direzione di rotazione da un commutatore rotante digitale con un'immagine: 5 passaggi

Video: Come interpretare la direzione di rotazione da un commutatore rotante digitale con un'immagine: 5 passaggi
Video: Sega Circolare per Legno, tutto quello che devi sapere per usarla in Falegnameria e fai da te 2024, Dicembre
Anonim
Come interpretare la direzione di rotazione da un commutatore rotante digitale con un PIC
Come interpretare la direzione di rotazione da un commutatore rotante digitale con un PIC

L'obiettivo di questo Instructable è illustrare come interfacciare un commutatore rotativo digitale (codificato in quadratura) con un microcontrollore. Non preoccuparti, ti spiego cosa significa per noi la quadratura codificata. Questa interfaccia e il software di accompagnamento consentiranno al microcontrollore di riconoscere il senso di rotazione per ogni spostamento da un arresto all'altro. Recentemente ho utilizzato questo tipo di interruttore in un progetto di microcontrollore che richiedeva l'inserimento di un setpoint di pressione utilizzando una manopola con 16 fermi al posto dei pulsanti su/giù. L'idea era quella di consentire all'utente di "comporre" la pressione desiderata. Di conseguenza, abbiamo dovuto sviluppare una routine software per ottenere le informazioni sulla posizione dall'interruttore e dedurre la direzione di rotazione per aumentare o diminuire il punto di regolazione della pressione per il sistema principale. In questo Instructable, tratterò l'interfaccia fisica al microcontrollore, la teoria del funzionamento per il commutatore rotante, la teoria del funzionamento per il software e la routine di deduzione. Infine, ti mostrerò la mia applicazione della routine di detrazione. Man mano che avanziamo, cercherò di mantenere le cose un po' generiche in modo che l'idea possa essere applicata su quante più piattaforme possibili, ma condividerò anche ciò che ho fatto in modo che tu possa vedere un'applicazione specifica.

Passaggio 1: parti

Parti
Parti

Per implementare ciò, avrai bisogno di:Un commutatore rotante (codificato in quadratura)Resistenze di pull-upPiattaforma di microcontrollore adattaPer il mio progetto, ho usato un encoder ottico Grayhill 61C22-01-04-02. La scheda tecnica dell'interruttore rotante richiede resistori di pull up da 8,2 k ohm sulle due linee dati provenienti dall'interruttore. Ti consigliamo di controllare la scheda tecnica dell'encoder che scegli di utilizzare. L'interruttore rotante che ho utilizzato può essere ordinato anche con un interruttore a pulsante assiale. È una funzione utile per confermare le selezioni che sono state effettuate, ecc., ma non discuterò qui la sua interfaccia. Ho elencato una "piattaforma di microcontrollori adatta" perché (penso) questo può essere implementato su più di una piattaforma. Ho visto molte persone usare altri microcontrollori per Instructables, quindi voglio mostrare anche l'approccio generale. Ho scritto tutto il codice in PIC Basic Pro per l'utilizzo con un Microchip PIC16F877A. In realtà, la cosa fondamentale di cui hai bisogno sul microcontrollore è la capacità di interrompere quando c'è un cambiamento logico su uno dei due pin. Sul PIC16F877A, questo è chiamato PORTB change interrupt. Potrebbero esserci altri nomi per esso su altri controller. Questa funzione di interruzione del microcontrollore fa parte di ciò che rende questa implementazione così elegante.

Passaggio 2: interfaccia hardware

Interfaccia hardware
Interfaccia hardware

Una soluzione "semplice" sarebbe quella di avere un interruttore "single pole-16 throw" con 16 connessioni al microcontrollore. Ogni uscita dell'interruttore sarebbe quindi collegata a un pin sul microcontrollore in modo che ogni posizione del quadrante possa essere controllata dal microcontrollore. Questo è un uso eccessivo di pin I/O. Le cose peggiorano ancora se vogliamo avere più di 16 posizioni (fermi) a nostra disposizione sullo switch. Ogni posizione in più sull'interruttore richiederebbe un input extra al microcontrollore. Questo diventa rapidamente un uso molto inefficiente degli ingressi su un microcontrollore. Inserisci la bellezza del commutatore rotante. Il commutatore rotante ha solo due uscite per il microcontrollore elencate come A e B nella scheda tecnica. Ci sono solo quattro possibili livelli logici che queste linee possono assumere: AB = 00, 01, 10 e 11. Ciò riduce notevolmente il numero di linee di ingresso che è necessario utilizzare per collegare l'interruttore al microcontrollore. Quindi, abbiamo ridotto il numero di righe di input a solo due. Ora cosa? Sembra che abbiamo davvero bisogno di 16 stati diversi, ma questo nuovo interruttore ne ha solo quattro. Ci siamo sparati ai piedi? No. Continuare a leggere. Tratteremo un po' della teoria alla base del funzionamento dell'interruttore rotante per spiegarla.

Passaggio 3: teoria del funzionamento dell'hardware

Teoria del funzionamento dell'hardware
Teoria del funzionamento dell'hardware
Teoria del funzionamento dell'hardware
Teoria del funzionamento dell'hardware
Teoria del funzionamento dell'hardware
Teoria del funzionamento dell'hardware

Il rilevamento della direzione di rotazione è possibile utilizzando il suddetto interruttore "single pole-16 throw" ma utilizza molti ingressi sul microcontrollore. L'uso dell'interruttore rotante riduce il numero di ingressi al microcontrollore, ma ora dobbiamo interpretare i segnali provenienti dall'interruttore e tradurli in una direzione di rotazione. Ho detto prima che l'interruttore era codificato in quadratura. Questa è anche una delle eleganze chiave di questa soluzione. Ciò significa che esiste un codice a 2 bit fornito dall'interruttore che corrisponde alla posizione dell'interruttore. Potresti pensare: "Se c'è un input a due bit per il microcontrollore, come rappresentiamo tutte e 16 le posizioni?" Questa è una bella domanda. Non li rappresentiamo tutti. Abbiamo solo bisogno di conoscere le posizioni relative della manopola in modo da poter determinare il senso di rotazione. La posizione assoluta della manopola è irrilevante. Per la rotazione in senso orario, il codice fornito dall'interruttore si ripete ogni quattro arresti ed è codificato in grigio. Il codice Gray significa che c'è solo un cambio di bit per ogni cambio di posizione. Invece dell'ingresso AB che conta per la rotazione in senso orario in binario come questo: 00, 01, 10, 11, cambia in questo modo: 00, 10, 11, 01. Notare che per quest'ultimo modello, c'è solo un ingresso che cambia tra imposta. I valori in senso antiorario per l'ingresso AB al microcontrollore saranno simili a questo: 00, 01, 11, 10. Questo è semplicemente il contrario del modello in senso orario con AB = 00 elencato per primo. Dai un'occhiata ai diagrammi per una spiegazione più visiva.

Passaggio 4: teoria del funzionamento del software

Teoria del funzionamento del software
Teoria del funzionamento del software

La routine che deduce il senso di rotazione è guidata dall'interruzione. Il microcontrollore che selezioni deve essere in grado di interrompere ogni volta che c'è un cambiamento su uno di (almeno) due pin quando l'interruzione è abilitata. Questo è chiamato PORTB change interrupt sul PIC16F877A. Ogni volta che l'interruttore viene ruotato, il microcontrollore verrà interrotto e l'esecuzione del programma verrà inviata all'Interrupt Service Routine (ISR). L'ISR capirà rapidamente in che modo è stato ruotato l'interruttore, imposterà un flag in modo appropriato e tornerà rapidamente al programma principale. Abbiamo bisogno che ciò avvenga rapidamente nel caso in cui l'utente ruoti l'interruttore molto velocemente. Sappiamo che il modello AB con codice grigio si ripete ogni quattro posizioni, quindi se facciamo funzionare la routine per le transizioni tra quelle quattro posizioni funzionerà per tutte le altre. Notare che in un ciclo a quattro posizioni, ci sono quattro fronti. Un fronte di salita e un fronte di discesa per l'ingresso A e l'ingresso B. Il microprocessore verrà interrotto ogni volta che c'è un bordo, il che significa che il microcontrollore verrà interrotto ogni volta che si ruota la manopola. Di conseguenza, l'ISR deve capire in che modo è stata girata la manopola. Per aiutarci a capire come farlo, ci rivolgiamo alla forma d'onda per la rotazione in senso orario. Notare che ogni volta che A ha un fronte, il suo nuovo valore è sempre diverso da quello di B. Quando la manopola passa dalla posizione 1 alla 2, A passa da logico-0 a logico-1. B è ancora 0 per questa transizione e non corrisponde al nuovo valore di A. Quando la manopola passa dalla posizione 3 alla 4, A ha un fronte di discesa mentre B rimane a logico-1. Nota di nuovo che B e il nuovo valore di A sono diversi. In questo momento, possiamo vedere che ogni volta che A provoca l'interruzione durante la rotazione in senso orario, il suo nuovo valore è diverso da quello di B. Controlliamo B per vedere cosa succede. B ha un fronte di salita quando l'interruttore passa dalla posizione 2 alla 3. Qui, il nuovo valore di B è lo stesso di A. Guardando l'ultimo fronte rimanente per la rotazione in senso orario, B ha un fronte discendente che si sposta dalla posizione 4 alla 5. (La posizione 5 è la stessa della posizione 1.) Anche qui il nuovo valore di B è lo stesso di A! Ora possiamo fare alcune detrazioni! Se A provoca l'interrupt e il nuovo valore di A è diverso da quello di B, la rotazione era in senso orario. Inoltre, se B provoca l'interrupt e il nuovo valore di B è lo stesso di A, allora la rotazione era in senso orario. Esaminiamo velocemente il caso della rotazione in senso antiorario. Proprio come la rotazione in senso orario, la rotazione in senso antiorario causerà quattro interrupt in un ciclo: due per l'ingresso A e due per l'ingresso B. L'ingresso A ha un fronte di salita quando la manopola si sposta dalla posizione 4 alla 3 e un fronte di discesa dalla posizione 2 alla 1 Quando la manopola si sposta dalla posizione 4 alla posizione 3, il nuovo valore di A è uguale al valore di B. Notare che quando A si sposta dalla posizione 2 alla posizione 1, anche il suo nuovo valore è uguale a quello di B. Ora, possiamo vedere che quando A provoca l'interruzione e il suo nuovo valore corrisponde a quello di B la rotazione era antioraria. Velocemente, esamineremo l'input B per verificare tutto. B provocherà un'interruzione quando la manopola si sposta dalla posizione 5 (che è la stessa di 1) alla 4 e quando la manopola si sposta dalla posizione 3 alla 2. In entrambi questi casi, il nuovo valore di B non corrisponde al valore esistente di A che è l'opposto dei casi in cui B provoca l'interruzione per rotazione oraria. Questa è una buona notizia. Tutto va come dovrebbe. Per riassumere, se A causa l'interruzione e il suo nuovo valore non corrisponde al valore di B o se B provoca l'interruzione e il nuovo valore di B corrisponde al valore di A, sappiamo che c'era una rotazione in senso orario. Possiamo controllare gli altri casi per la rotazione in senso antiorario nel software o possiamo supporre che poiché non era la rotazione in senso orario, era in senso antiorario. La mia routine si basava semplicemente sul presupposto.

Passaggio 5: software

Software
Software
Software
Software

Non ho usato gli interrupt incorporati in PIC Basic Pro. Ho usato un paio di file che ho incluso nel mio codice di Darrel Taylor per guidare la routine. È qui che appartiene un enorme merito a Darrel! I file sono gratuiti. Basta visitare il suo sito Web per ulteriori informazioni, altre applicazioni e per scaricare i file. Puoi saltare questa parte se non stai usando un PIC con gli interrupt di Darrel Taylor. Basta impostare gli interrupt secondo necessità sulla piattaforma che stai utilizzando. Per impostare gli interrupt di Darrel Taylor (DT) ci sono due cose da fare: 1.) Includi i file DT_INTS-14.bas e ReEnterPBP.bas nel tuo code.2.) Copia e incolla questo nella macro code. ASMINT_LIST;IntSource, Label, Type, ResetFlag? INT_Handler RBC_INT, _ISR, PBP, yes endm INT_CREATEENDASMInserire tab e spazi come il grafico alla fine di Instructable così puoi vedere le cose un po' più facilmente nel tuo codice. Dovrai modificarlo leggermente per adattarlo alle tue esigenze. Sotto Etichetta, sostituisci ISR con il nome della subroutine che è la tua ISR. Non dimenticare il carattere di sottolineatura! Ne hai bisogno! Per far funzionare gli interrupt, ci sono altre due cose da fare: 1.) Scrivi l'ISR. Lo scriverai proprio come stavi per scrivere una subroutine PBP, tranne per il fatto che dovrai inserire @ INT_RETURN alla fine della subroutine invece di RETURN. Questo riconoscerà l'interruzione e riporterà l'esecuzione del programma al punto in cui era stata interrotta nel ciclo principale. Leggere semplicemente PORTB è tutto ciò che deve essere fatto per cancellare il flag di interrupt sul PIC16F877A. Ogni diverso microcontrollore ha un modo diverso di cancellare i flag di interrupt. Controlla la scheda tecnica del tuo microcontrollore.2.) Quando raggiungi il punto nel tuo codice in cui vuoi abilitare l'interrupt, usa questa riga di codice:@ INT_ENABLE RBC_INTQuando vuoi disabilitare l'interrupt usa semplicemente:@ INT_DISABLE RBC_INTC'è molto di cose racchiuse in ciò che ho appena trattato, quindi riassumerò rapidamente. Finora, il tuo programma dovrebbe assomigliare a questo:; Qualsiasi configurazione o codice necessarioINCLUDE "DT_INTS-14.bas"INCLUDE "ReEnterPBP.bas"ASMINT_LIST macro;IntSource, Label, Type, ResetFlag? INT_Handler RBC_INT, _myISR, PBP, sì endm INT_CREATEENDASM; Qualsiasi altra configurazione necessaria o codice@ INT_ENABLE RBC_INT; Codice che deve sapere in che direzione ruota la manopola@ INT_DISABLE RBC_INT; Altro codiceEND; Fine del programmaISR:;Codice ISR qui@ INT_RETURN(Interrupt Handler Set Up Table) Penso che questo sia il punto in cui chiunque non stia utilizzando un interrupt PIC o DT può partecipare di nuovo. Ora, dobbiamo effettivamente scrivere l'ISR in modo che il microcontrollore sappia in che direzione ruota la manopola. Ricordiamo dalla sezione di teoria del software che possiamo dedurre il senso di rotazione se conosciamo l'input che ha causato l'interrupt, il suo nuovo valore e il valore dell'altro input. Ecco lo pseudocodice: Leggi PORTB in una variabile scratch per cancellare il flag di interruzione Controlla se A ha causato l'interruzione. Se vero, confrontare A e B. Controllare se diverso, se diverso, Era la rotazione in senso orario Altrimenti, Era in senso antiorario EndifControllare se B ha causato l'interruzione. Se vero, Confronta A e B Controlla se diverso, se uguale, Era la rotazione in senso orario Altrimenti, Era in senso antiorario EndifReturn from interruptCome facciamo a sapere se un cambiamento su A o B ha causato l'interrupt? Scoprire il nuovo valore dell'input modificato e dell'altro input (invariato) è facile perché possiamo leggerli all'interno dell'ISR. Dobbiamo sapere qual era lo stato di ciascuno prima che l'esecuzione venisse inviata all'ISR. Questo accade nella routine principale. La routine principale rimane in attesa che una variabile di byte che abbiamo chiamato CWflag venga impostata su 1 o cancellata a 0 dall'ISR. Dopo ogni modifica confermata della manopola o se non c'è attività della manopola, la variabile viene impostata su 5 per indicare uno stato di inattività. Se il flag viene impostato o viene azzerato, la routine principale immediatamente incrementa o decrementa la pressione del punto di regolazione in modo appropriato in base alla rotazione e quindi reimposta la variabile CWflag su 5 perché la manopola è di nuovo inattiva. Poiché la routine principale controlla il flag CW, documenta anche lo stato dei valori dei selettori rotativi A e B. Questo è davvero semplice e assomiglia a questo:oldA = AoldB = BNon c'è davvero niente di super stravagante qui. Basta includere quelle due righe all'inizio del ciclo che controlla la rotazione di CWflag. Stiamo solo aggiornando i valori logici degli ingressi dalla manopola rotante all'interno del ciclo di incremento/decremento nella routine principale in modo da poter vedere quale ingresso ha causato l'interruzione quando viene eseguito l'ISR. Ecco il codice ISR:ABchange: scratch = PORTB ' Leggi PORTB per cancellare il flag di interrupt ' Se A provoca l'interrupt, controlla B per il senso di rotazione IF oldA != A THEN ' Se A e B sono diversi, era la rotazione in senso orario IF A != B THEN GOTO CW ' Altrimenti è stata una rotazione antioraria ELSE GOTO CCW ENDIF ENDIF ' Se B provoca l'interrupt, controlla A per il senso di rotazione IF oldB != B THEN ' Se A e B sono uguali, era in senso orario IF A == B THEN GOTO CW ' Altrimenti era in senso antiorario ELSE GOTO CCW ENDIF ENDIFCW: CWflag = 1@ INT_RETURNCCW: CWflag = 0@ INT_RETURNHo incluso il codice ISR in un file AB_ISR.bas perché il le schede nel codice non vengono visualizzate come dovrebbero. Ora, poiché l'ISR ha i vecchi valori per gli ingressi A e B, può determinare quale ingresso ha causato l'interruzione, confrontarlo con l'altro ingresso (invariato) e determinare la direzione di rotazione. Tutto ciò che la routine principale deve fare è controllare il flag CW per vedere in quale direzione è stata girata la manopola (se lo ha fatto) e aumentare o diminuire un contatore, un set point o qualunque cosa ti piaccia o di cui hai bisogno. Spero che questo aiuti e non lo sia stato troppo confusione. Questo tipo di interfaccia è particolarmente utile se il sistema sta già utilizzando gli interrupt poiché si tratta solo di un altro interrupt da aggiungere. Divertiti!

Consigliato: