Curs de pregatire. Conexiune codificator. Structura tipică a unui program simplu. Generator pe AVR. Conectarea codificatorului la microcontroler

Pe scurt, codificatoarele pot fi numiți traductoare cu deplasare unghiulară. Acestea servesc la modificarea unghiului de rotație al unui obiect de rotație, de exemplu, arborele unui mecanism, într-un semnal de curent electric. În acest caz, se determină nu numai unghiul de rotație al arborelui, ci și direcția de rotație a acestuia, precum și viteza de rotație și poziția curentă față de poziția inițială.

Codificatoarele au devenit cele mai populare atunci când sunt utilizate în sistemele de mișcare de precizie, în fabricile de mașini-unelte, în complexele de producție cu ajutorul roboticii, în dispozitivele de măsurare care necesită înregistrarea măsurătorilor precise ale înclinărilor, virajelor, rotațiilor și unghiurilor.

Tipuri și principiu de funcționare

Codificatoarele sunt senzori de rotație. Cel mai simplu senzor are un mâner care poate fi rotit în sensul acelor de ceasornic sau în sens invers acelor de ceasornic. În funcție de unghiul de rotație și direcția, se emite un semnal digital care informează despre poziția mânerului sau în ce direcție a fost rotit.

Pentru un astfel de encoder, prezentat în figură, mânerul poate fi folosit și ca buton. Aceasta este o funcție auxiliară a unui anumit tip de encoder.

Pe baza tipului de ieșire a datelor, codificatoarele sunt împărțite în două grupuri mari:

  1. Absolut.
  2. incremental.

Codificatoare absolute

Cu un encoder absolut, întregul cerc de rotație este împărțit într-un anumit număr de sectoare, cel mai adesea de aceeași dimensiune. Aceste sectoare sunt numerotate. În timpul funcționării, codificatorul afișează numărul sectorului în care se află în prezent. De aceea se numește absolut. Cu acest tip de encoder, puteți determina întotdeauna în ce unghi față de sectorul zero se rotește encoderul la un anumit moment, adică atunci când este rotit, produce valorile numerelor de sector, până la valoarea maximă. Apoi se întoarce la zero.

Dacă arborele codificatorului este rotit în cealaltă direcție, acesta va începe să producă valori opuse. În cazul nostru, folosește cinci pini pentru a scoate valorile de rotație.

Acest algoritm are dezavantajele sale. Tabelul 1 arată ordinea valorilor de ieșire ale codificatorului al n-lea. Merită să acordați atenție ultimelor două rânduri, trecerea de la 127 la 128.

tabelul 1

Absolut toate elementele se schimbă aici. Într-un encoder ideal, toate se schimbă în același timp și nu sunt probleme. Într-un codificator aproape real, biții se schimbă rapid, dar nu simultan. Și la un moment dat, ieșirea codificatorului se dovedește a fi o valoare complet arbitrară. Deoarece toți biții se modifică, codificatorul va avea o valoare arbitrară de la zero la toți.

Un exemplu de astfel de comutator este afișat în dreapta. Ce ar putea însemna asta? Să ne uităm la un exemplu. Microcontrolerul folosește un motor pentru a controla arborele și pentru a-l roti la un anumit unghi. La un anumit moment, la trecerea de la celula 127 la celula 128, aceasta primește o anumită valoare aleatorie. Controlerul ajunge la concluzia că arborele se află într-un loc complet diferit, spre deosebire de locația reală, și începe să-l rotească într-o direcție diferită, cu o viteză diferită etc.

După un anumit timp, microcontrolerul primește valoarea corectă și începe să încerce să oprească arborele și să-l rotească în direcția corectă. Acest proces poate dura mult timp, cu condiția ca o astfel de eroare să apară frecvent. Astfel de erori sunt neregulate și destul de greu de calculat.

Cod gri

Problema descrisă mai sus este rezolvată prin introducerea unui cod Gray. O caracteristică a codului Gray este că atunci când codificatorul este comutat la unul, valoarea codului Gray se schimbă și cu unul. Se schimbă un singur tip. Acest lucru poate fi văzut în Tabelul 2 în comparația dintre codul binar și codul Gray.

masa 2

Primele două linii sunt aceleași, dar deja în a doua linie s-a schimbat bitul din mijloc. Apoi se schimbă și un pic. De asemenea, merită remarcat faptul că ultimul și primul cod Gray diferă cu un bit, ceea ce înseamnă că codul Gray poate intra într-o buclă.

Avantajul acestui cod este că eroarea discutată mai sus nu este posibilă. Printre dezavantaje, se poate remarca faptul că microcontrolerul trebuie să convertească codul Gray în cod binar pentru a înțelege în ce poziție se află codificatorul absolut.

Codificatoare incrementale

Următorul tip este codificatorul incremental, care are o structură mai simplă. Dar, în același timp, nu arată locația specifică a stiloului său. Afișează doar direcția de rotație, iar numărul de diviziuni de rotație trebuie numărat de microcontroler.

Un encoder incremental are un set de benzi care sunt conectate la masă în mod implicit și, atunci când sunt rotite, ele realizează și întrerup conexiunile. Rezultatul este semnalul prezentat în figură (similar cu o undă pătrată). Codificatorul are două astfel de benzi circulare. Benzile sunt compensate cu un sfert, iar semnalele sunt de asemenea compensate cu un sfert. Acest lucru este important deoarece vă permite să determinați direcția de rotație.

Circuitul unui encoder incremental poate fi reprezentat în figura din dreapta. Butoanele indică conexiunile periodice ale codificatorului la masă. Deoarece encoderul nu este conectat la o unitate logică în interior, este necesar să se tragă în mod independent unitățile logice din exterior prin rezistențe la ieșirea codificatorului. În acest caz, când niciunul dintre picioarele codificatorului nu este conectat la masă, va exista unul logic pe picioare.

Dacă codificatorul a conectat un picior la pământ, atunci acest picior va avea un zero logic. Într-o stare silențioasă, ieșirea codificatorului este una logică. Când începeți să rotiți codificatorul în orice direcție, mai întâi un pin este conectat la masă, apoi celălalt. Apoi, acești pini sunt deconectați la rândul lor de la pământ și se formează din nou o unitate logică pe ei.

Direcția de rotație poate fi determinată de care dintre borne a fost conectată mai întâi la masă. Când numărați ciclurile complete, puteți număra numărul de clicuri pe care le rotește codificatorul.

De fapt, codificatorul are patru stări:

  1. Două unități.
  2. Zero și unu.
  3. Zero și zero.
  4. Unu și zero.

Trei stări care nu sunt egale cu unele sunt instabile, iar codificatorul nu poate fi în ele. Multe microcontrolere implementează funcția de numărare a turelor folosind temporizatoare care au intrări specifice. Cronometrul numără la nivel hardware câte clicuri și în ce direcție a fost rotit codificatorul și afișează valoarea. Adică, contorul crește un număr.

Schimbând acest număr, puteți determina câte clicuri a fost rotit codificatorul. După numărul de clicuri puteți determina unghiul de rotație. Codificatorul are și contact bounce, ceea ce face analiza semnalului dificilă.

Codificatoare optice

Un astfel de convertor este realizat sub forma unui disc fixat pe un arbore și din sticlă. Senzorul optic de rotație diferă de alte tipuri prin faptul că are o matrice optică suplimentară care se mișcă atunci când arborele este rotit. În același timp, transformă cuplul într-un flux luminos, care este apoi primit de un fotosenzor.

Convertorul optic reține unghiurile de rotație. În acest caz, fiecărei poziții individuale îi corespunde un cod digital special, care, împreună cu numărul de rotații, formează unitatea de măsură a senzorului. Encoderul se conectează și funcționează într-un mod similar cu un encoder incremental.

După natura funcționării lor, ele sunt împărțite în fotovoltaiceȘi magnetic . Principiul de funcționare al magnetic se bazează pe utilizarea lui, care a fost descoperit pentru prima dată în 1879. În acest caz, o diferență de potențial apare numai atunci când un fir de curent continuu este plasat într-un câmp magnetic.

În ceea ce privește proprietățile de precizie și rezoluție, senzorul de tip magnetic este inferior celui fotoelectric, cu toate acestea, este mai simplu în design și mai puțin solicitant în condițiile de funcționare și spațiu. Un encoder magnetic este un dispozitiv care detectează trecerea polului magnetic al unui magnet în timpul rotației, situat lângă elementul sensibil. Informațiile despre transmițător sunt exprimate în cod digital.

Encoder fotoelectric este un senzor care funcționează pe principiul fotoelectric. Acest efect se observă atunci când o substanță este expusă la lumină. Acest principiu a fost descoperit în 1887. Când se operează un astfel de senzor, fasciculul de lumină este convertit în mod constant într-un semnal de curent electric.

Analogii codificatorului fotoelectric sunt optoelectronici, optici și. Acești senzori sunt mai sensibili la caracteristicile de fabricație, funcționarea și alți factori în comparație cu alte modele. Cu toate acestea, acest lucru este justificat de precizia lor sporită, spre deosebire de concurenții lor.

Un encoder este un lucru care arată similar cu un rezistor variabil, dar, spre deosebire de acesta din urmă, nu are limitatoare și se poate roti în orice direcție la nesfârșit. Folosind un encoder, este foarte convenabil să organizați tot felul de meniuri pe ecran; în general, un codificator „pushable” (adică dacă poate funcționa și ca buton) este ideal pentru organizarea meniurilor ciclice unidimensionale.

Există două tipuri de encodere: absolute - care emite imediat codul unghiului de rotație și incrementale - emit impulsuri în timpul rotației. Pentru acestea din urmă, microcontrolerul trebuie să fie responsabil pentru numărarea impulsurilor și transformarea acestora în unghiuri de rotație.

Din punct de vedere al designului, codificatoarele pot fi mecanice sau optice; în primul se generează impulsuri de rotație pe o pereche de contacte atunci când sunt închise printr-un contact de alunecare al arborelui; în al doilea se joacă rolul contactelor. prin fotodiode, iar rolul contactorului este un LED care strălucește printr-un disc cu sloturi (bună ziua mouse-ului).

Deși există o mulțime de informații despre programarea codificatoarelor în rețea, precum și biblioteci gata făcute pentru aceasta, toate sunt oarecum inutil de greoaie (IMHO) - sondarea de stat este de obicei implementată ca o mașină cu stări finite sub forma unui comutator. bloc cu if-uri imbricate, care pare oarecum complicat (mai ales când este scris în asamblator). Deși implementarea ar putea fi mai simplă.

Codificatoarele incrementale mecanice ieftine sunt cele mai populare în economia națională, așa că le vom lua în considerare. Procesul de rotire a arborelui codificatorului este prezentat schematic în figură (sus - rotație în sensul acelor de ceasornic, jos - în sens invers acelor de ceasornic):


Aici A și B sunt chiar contactele la care microcontrolerul va procesa nivelurile. Contactul în mișcare le închide pe pământ dacă nu cad în găurile sale. Rețineți că figura arată doar patru găuri pentru simplitate. De fapt, există mai multe dintre aceste găuri (din nou, amintiți-vă de mouse-ul cu bile și cum arată roata sa optică). Terminalele A și B sunt trase în sus de rezistențe la tensiunea de alimentare. Ca rezultat, la rotire, se obțin diagramele prezentate în figura de mai sus.

Lăsați ambele contacte să cadă inițial în gaură, apoi va exista un nivel ridicat de tensiune pe ele (sunt și conectate la sursa de alimentare). În plus, când se rotește în sensul acelor de ceasornic, contactul A va fi primul care va fi închis la pământ, apoi contactul B se va alătura acestuia. Apoi, ajungând la următoarea gaură a discului, contactul A se va deschide și va primi un nivel înalt, după care contactul B. după aceste mișcări vor readuce contactele la starea lor inițială, iar cu rotirea ulterioară această diagramă se va repeta ciclic.

Astfel, se dovedește că starea curentă a codificatorului este descrisă de o valoare pe doi biți. Dar starea actuală în sine conține puține informații utile și pentru a analiza rotația trebuie luată în considerare în legătură cu valoarea stării anterioare. Și această pereche determină deja în mod clar direcția de rotație a mânerului. Pentru comoditate, să luăm un număr de patru biți, dintre care cei mai importanți doi octeți conțin stările anterioare ale contactelor A și B, iar cei mai mici doi octeți îi conțin pe cei actuali.

Și când se rotește în sens invers acelor de ceasornic

Binar Zecimal
1110 14
0001 1
0010 2
0111 7

Acum algoritmul pentru determinarea direcției de rotație a codificatorului pare foarte simplu: obținem valoarea și comparăm dacă se încadrează într-unul dintre seturile (2, 4, 11, 13) și (1, 7, 8, 14). Dacă da, atunci avem o viraj în direcția corespunzătoare. În caz contrar, arborele fie nu s-a rotit deloc, fie s-a rotit atât de repede încât a omis mai multe stări (dacă acest lucru se întâmplă des, atunci ar trebui să vă gândiți la creșterea frecvenței sondajului de stat) sau a existat „sărit” a contactelor. Fără să aprofundăm motivul, toate celelalte semnificații pot fi ignorate în siguranță.

Ca exemplu, luați în considerare funcționarea unui encoder împreună cu un microcontroler AVR:


Aici, doi pini de ordin scăzut ai portului PB al microcontrolerului ATMega8 sunt utilizați pentru conectare. O pereche de rezistențe trage aceste linii până la tensiunea de alimentare (din moment ce rezistențele interne ale Atmega aici ar putea să nu fie suficiente pentru o funcționare stabilă), o pereche de condensatoare sunt instalate pentru a suprima zgomotul de impuls.

Pentru o astfel de diagramă de conectare, puteți schița următoarea implementare în C:

Static uint8_t encoderGetVal() ( returnează PINB & 3; ) static uint8_t encoderGetCode() ( static uint8_t prev; uint8_t val = encoderGetVal(); cod uint8_t = (anterior<< 2) | val; prev = val; return code; } static void encoderInit() { DDRB &= ~0b11; PORTB |= 0b11; encoderGetCode(); } void onEncoderEvent(bool direction); void encoderCheck() { uint8_t code = encoderGetCode(); if (code == 1 || code == 7 || code == 8 || code == 14) { onEncoderEvent(true); } else if (code == 2 || code == 4 || code == 11 || code == 13) { onEncoderEvent(false); } }

Codul este incredibil de simplu - câteva dacă și nicio mașină cu stări finite. Funcția encoderInit() este apelată la început pentru a inițializa portul și a reține valoarea de pornire. Funcția encoderCheck() este apelată în bucla de evenimente (în cadrul main() sau de un cronometru). Manipulatorul onEncoderEvent(bool) va fi apelat ori de câte ori codificatorul este rotit și va primi un steag de direcție de rotație.

Dar există un punct important: codificatorul este un lucru sensibil și, dacă încercați să procesați, de exemplu, evenimentele de navigare în meniu în acest fel, atunci chiar și o mică rotire a butonului codificatorului va apela în mod repetat handlerul onEncoderEvent(), așa cum rezultatul căruia cursorul meniului, în loc să se deplaseze la elementul următor/anterior, va zbura imediat la sfârșitul/începutul listei. Puteți ajusta sensibilitatea codificatorului schimbând frecvența apelului encoderCheck() (de obicei, frecvența optimă este de ~ 10 Hz). În acest caz, metoda encoderGetCode() ar trebui apelată cât mai des posibil pentru a avea întotdeauna valoarea curentă a ultimei stări a contactelor (cu o frecvență de undeva în jur de 100 Hz).

În asamblare, acest cod ar putea arăta astfel:

EQU encoder_port PORTB .EQU encoder_pin PINB .EQU encoder_ddr DDRB .DSEG .ORG SRAM_START sEncoderPrev: .BYTE 1 ... .CSEG .ORG $0000 ... Encoder_init: cbi encoder_ddr, 0 cbi encoder_ddr, 0 cbi encoder_, encoder1 1 în r0, encoder_pin andi r0, 3 sts sEncoderPrev, r0 ... Encoder_check lds ZL, sEncoderPrev lsl ZL lsl ZL în r0, encoder_pin andi r0, 3 sts sEncoderPrev, r0 sau ZL, ; 1 7 8 14 -> cpi clockwise ZL, 1 breq Encoder_clockwise cpi ZL, 7 breq Encoder_clockwise cpi ZL, 8 breq Encoder_clockwise cpi ZL, 14 breq Encoder_clockwise ; 2 4 11 13 -> cpi invers acelor de ceasornic ZL, 2 breq Encoder_contraclockwise cpi ZL, 4 breq Encoder_counterclockwise cpi ZL, 11 breq Encoder_contraclockwise cpi ZL, 13 breq Encoder_counterclockwise Encoder_lockwise_j; ; aici este codul de gestionare a rotației în sensul acelor de ceasornic; Encoder_sens invers acelor de ceasornic: ; ; aici este codul de gestionare a rotației în sens invers acelor de ceasornic; Interval_enc_done.

Aflați cum să utilizați un encoder rotativ incremental într-un proiect Arduino.

Un encoder rotativ este un dispozitiv electromecanic care convertește mișcarea rotativă în informații digitale sau analogice. Este foarte asemănător cu un potențiometru, dar poate fi rotit la nesfârșit, fie în sensul acelor de ceasornic, fie în sens invers acelor de ceasornic. Există mai multe tipuri de codificatoare rotative. Cele două tipuri principale sunt codificatoare absolute și relative (incrementale). În timp ce un encoder absolut emite o valoare proporțională cu unghiul curent al arborelui, un encoder incremental emite pasul și direcția arborelui. Codificatoarele rotative devin din ce în ce mai populare în electronicele de larg consum, în special ca butoane de control, pe lângă aplicațiile din multe alte domenii. Ele înlocuiesc potențiometrele și butoanele de navigare, unde sunt necesare navigarea rapidă, configurarea, introducerea datelor și selectarea meniului. Unele codificatoare includ, de asemenea, un buton încorporat care creează o intrare suplimentară la procesor care poate fi folosită ca o altă comandă de utilizator în interfața de control. În imaginea de mai jos puteți vedea un encoder rotativ incremental tipic cu un buton de pornire.

În acest articol, vă vom arăta cum să utilizați un encoder rotativ incremental într-un proiect Arduino. Vom explica cum să facem față respingerii contactului și să interpretăm semnalele codificatorului într-un program de microcontroler folosind întreruperi.

Semnal de ieșire în cuadratura a codificatorului incremental

Un encoder rotativ incremental produce două semnale de ieșire pe măsură ce arborele se rotește, numite și ieșire în cuadratura. În funcție de direcție, un semnal este înaintea celuilalt. Mai jos puteți vedea forma de undă de ieșire a unui codificator rotativ incremental și secvența de biți așteptată.

După cum se poate observa din figură, ambele ieșiri sunt inițial în starea logică. Când arborele codificatorului începe să se rotească în sensul acelor de ceasornic, starea de la ieșirea A scade mai întâi la zero logic, iar apoi urmează cu o întârziere ieșirea B. Când se rotește în sens invers acelor de ceasornic, se întâmplă opusul. Intervalele de timp din diagrama semnalelor depind de viteza de rotație, dar întârzierea semnalului este garantată în orice caz. Pe baza acestei caracteristici a unui encoder rotativ incremental, vom scrie un program pentru Arduino.

Contact de filtrare a respingerii unui encoder mecanic

Codificatoarele mecanice au comutatoare încorporate care generează un semnal de ieșire în cuadratura în timpul rotației.

Când aveți de-a face cu semnalele codificatorului, principala problemă este respingerea contactului. Provoacă determinarea eronată a direcției de rotație și a cantității de rotație a arborelui codificatorului și face problematica utilizării codificatoarelor. Putem scăpa de contactul de respingere prin filtrarea acestuia într-un program sau folosind scheme suplimentare de filtrare.

Filtrarea zgomotului în software-ul microcontrolerului este o opțiune de filtrare, dar are unele dezavantaje. Trebuie să scrieți un cod mai complex pentru a gestiona zgomotul. Filtrarea va lua timp de procesare și va introduce întârzieri în firul principal al programului. Poate fi necesar să setați cronometre pentru a ignora intervalele de respingere a contactelor. În cele din urmă, este posibil să nu reușiți să obțineți un rezultat satisfăcător și de încredere.

Filtrarea zgomotului cu hardware suplimentar este mai simplă și oprește zgomotul la sursă. Veți avea nevoie de un filtru RC de primă comandă. În imaginea de mai jos puteți vedea cum arată semnalul după ce ați folosit un filtru RC.

Filtrul RC încetinește timpul de cădere și timpul de creștere și asigură debouncing hardware. Când selectați o pereche rezistor-condensator, trebuie să luați în considerare viteza maximă. În caz contrar, răspunsul aşteptat al codificatorului va fi filtrat.

Aplicație simplă

Vom crea o aplicație care să demonstreze cum să folosiți un encoder rotativ într-un proiect Arduino. Vom folosi codificatorul pentru navigare, introducerea datelor și selectare. Mai jos este o diagramă schematică a aplicației.

Circuitul se bazează pe placa Arduino Uno. Pentru interfața grafică este folosit display-ul LCD al Nokia 5110. Se adaugă ca comenzi un encoder rotativ mecanic cu un buton și filtre RC.

Vom dezvolta un meniu software simplu în care vom demonstra funcționarea unui encoder rotativ.

Procesarea semnalelor codificatorului utilizând întreruperi

Semnalele codificatorului trebuie detectate și interpretate în program cât mai repede posibil pentru a nu bloca fluxul principal al programului. Putem detecta semnale prin sondaj în bucla principală sau folosind întreruperi. Sondajul nu este eficient deoarece trebuie să rezervi timp și resurse în bucla principală, ceea ce introduce întârzieri suplimentare. Utilizarea întreruperilor este o soluție mai rapidă și mai rentabilă. Vă vom arăta cum să utilizați întreruperile pentru a procesa semnalele codificatorului.

Atmega328 are două tipuri de întreruperi care pot fi folosite în acest scop; întrerupere externă și întrerupere de schimbare a ieșirii. Pinii INT0 și INT1 sunt alocați unei întreruperi externe, iar PCINT0 - PCIN15 sunt alocați unei întreruperi atunci când un pin își schimbă starea. O întrerupere externă poate detecta dacă semnalul de intrare este în scădere sau în creștere și poate fi declanșată în una dintre următoarele condiții: în creștere, în scădere sau în comutare. Există multe mai multe resurse hardware disponibile pentru întreruperea de schimbare a pinului, dar nu poate detecta marginile de creștere și de descreștere și este apelată atunci când are loc orice schimbare a stării logice (toggle) pe un pin.

Pentru a utiliza o întrerupere de schimbare a pinului, conectați ieșirile A și B ale codificatorului la pinii A1 și A2, iar ieșirea butonului la pinul A0 al plăcii Arduino, așa cum se arată în schema de circuit. Setați pinii A0, A1 și A2 în modul de intrare și porniți rezistențele lor interne de tragere. Activați întreruperea de schimbare a pinului în registrul PCICR și activați întreruperile pentru pinii A0, A1 și A2 din registrul PCMS1. Dacă pe una dintre aceste intrări este detectată orice modificare a stării logice, va fi apelată ISR(PCINT1_vect) (Pin State Interrupt).

Deoarece întreruperea de schimbare a pinului este apelată pentru orice modificare logică, trebuie să monitorizăm ambele semnale (atât A cât și B) și să detectăm rotația atunci când este primită secvența așteptată. După cum se poate vedea din diagrama de semnal, mișcarea în sensul acelor de ceasornic generează A = …0011… și B = …1001… . Când scriem ambele semnale în octeții seqA și seqB, deplasând ultima citire la dreapta, putem compara aceste valori și determina noua etapă de rotație.

Puteți vedea o parte a codului care include funcția de inițializare și de întrerupere pentru schimbarea pinului.

Void setup() ( pinMode(A0, INPUT); pinMode(A1, INPUT); pinMode(A2, INPUT); // Activați rezistențele interne pull-up digitalWrite(A0, HIGH); digitalWrite(A1, HIGH); digitalWrite( A2, HIGH); PCICR = 0b00000010; // 1. PCIE1: Activare întreruperea de schimbare a stării 1 PCMSK1 = 0b00000111; // Activarea întreruperii de schimbare a stării pentru A0, A1, A2 ) void loop() ( // Bucla principală ) ISR (PCINT1_vect) ) ( // Dacă întreruperea este cauzată de un buton if (!digitalRead(A0)) (buton = adevărat; ) // Dacă întreruperea este cauzată de semnalele codificatorului altfel ( // Citiți semnalele A și B boolean A_val = digitalRead( A1); boolean B_val = digitalRead (A2); // Scrieți semnalele A și B în secvențe separate seqA<<= 1; seqA |= A_val; seqB <<= 1; seqB |= B_val; // Маскировать четыре старших бита seqA &= 0b00001111; seqB &= 0b00001111; // Сравнить запсанную последовательность с ожидаемой последовательностью if (seqA == 0b00001001 && seqB == 0b00000011) { cnt1++; left = true; } if (seqA == 0b00000011 && seqB == 0b00001001) { cnt2++; right = true; } } }

Folosirea unei întreruperi externe simplifică procesul, dar deoarece această întrerupere are doar doi pini alocați, nu o veți putea folosi în alte scopuri dacă o ocupați cu un encoder. Pentru a utiliza o întrerupere externă, trebuie să setați pinii 2 (INT0) și 3 (INT1) în modul de intrare și să activați rezistențele lor interne de tragere. Apoi selectați opțiunea de margine descendentă pentru a declanșa ambele întreruperi în registrul EICRA. Activați întreruperile externe în registrul EIMSK. Când arborele codificatorului începe să se rotească, mai întâi semnalul de conducere scade la zero logic, iar al doilea semnal rămâne la unul logic pentru o perioadă de timp. Prin urmare, trebuie să determinăm care dintre semnale este în starea logică în timpul întreruperii. După ce semnalul de conducere a scăzut la zero logic, după un timp al doilea semnal va cădea și la zero logic, provocând o altă întrerupere. Dar de data aceasta și celălalt semnal (conducător) vor fi la un nivel logic scăzut, ceea ce înseamnă că nu este începutul rotației, așa că îl ignorăm.

Mai jos puteți vedea o parte a codului care include funcția de inițializare și de gestionare a întreruperilor externe.

Void setup() ( pinMode(2, INPUT); pinMode(3, INPUT); // Activați rezistențele interne pull-up digitalWrite(2, HIGH); digitalWrite(3, HIGH); EICRA = 0b00001010; // Selectați apelul pe front descendent EIMSK = 0b00000011; // Activează întreruperea externă ) void loop() ( // Bucla principală ) ISR (INT0_vect) ( // Dacă al doilea semnal este în starea logică, atunci aceasta este o nouă rotație dacă (digitalRead( 3) == HIGH) ( stânga = adevărat; ) ) ISR (INT1_vect) ( // Dacă al doilea semnal este în starea logică, atunci aceasta este o nouă rotație dacă (digitalRead(2) == HIGH) ( dreapta = Adevărat; ) )

Codul complet pentru schița Arduino, inclusiv bucla principală, este mai jos:

#include #include #include octet volatil seqA = 0; octet volatil secB = 0; octet volatil cnt1 = 0; octet volatil cnt2 = 0; boolean volatil dreapta = fals; boolean volatil stânga = fals; buton boolean volatil = fals; iluminare booleană = adevărat; element de meniu octet = 1; pagina octet = 1; Adafruit_PCD8544 display = Adafruit_PCD8544(13, 12,11, 8, 10); void setup() ( pinMode(A0, INPUT); pinMode(A1, INPUT); pinMode(A2, INPUT); // Activați rezistențele interne pull-up digitalWrite(A0, HIGH); digitalWrite(A1, HIGH); digitalWrite( A2, HIGH); // Activare LCD backlight pinMode(9, OUTPUT); digitalWrite(9, HIGH); PCICR = 0b00000010; // 1. PCIE1: Activare întrerupere de schimbare a stării 1 PCMSK1 = 0b00000111; // Activare întrerupere de schimbare a stării pentru A0, A1, A2 // Inițializați afișajul LCD.setRotation(2); // Setați afișajul de orientare LDC.begin(60); // Setați afișajul de contrast LCD.clearDisplay(); // Ștergeți afișajul afișajului.display(); / / Aplicați modificări sei(); ) void loop() ( // Creați pagini de meniu if (page==1) ( display.setTextSize(1); display.clearDisplay(); display.setTextColor(BLACK, WHITE); display. setCursor(15, 0); display.print("MENIU PRINCIPAL"); display.drawFastHLine(0,10,83,BLACK); display.setCursor(0, 15); if (menuitem==1) ( display.setTextColor (ALB, NEGRU); ) else ( display.setTextColor(BLACK, WHITE); ) display.print(">Contrast: 99%"); display.setCursor(0, 25); if (menuitem==2) ( display.setTextColor(WHITE, BLACK); ) else ( display.setTextColor(BLACK, WHITE); ) display.print(">Test Encoder"); if (menuitem==3) ( display.setTextColor(WHITE, BLACK); ) else ( display.setTextColor(BLACK, WHITE); ) display.setCursor(0, 35); display.print(">Iluminare de fundal:"); if (iluminare de fundal) ( display.print("ON"); ) else ( display.print("OFF"); ) display.display(); ) else if (pagina==2) ( display.setTextSize(1); display.clearDisplay(); display.setTextColor(BLACK, WHITE); display.setCursor(15, 0); display.print("ENC. TEST" ); display.drawFastHLine(0,10,83,BLACK); display.setCursor(5, 15); display.print("LEFT RIGHT"); display.setTextSize(2); display.setCursor(5, 25); display.print(cnt1); display.setCursor(55, 25); display.print(cnt2); display.setTextSize(2); display.display(); ) // Efectuați o acțiune dacă este primită o nouă comandă de la codificator if (stânga) (stânga = fals; meniu--; if (menuitem==0) (meniuitem=3; ) ) if (dreapta) (dreapta = fals; menuitem++; if (menuitem==4) (meniuitem==1) ; ) ) if (buton) (buton = fals; if (pagina == 1 && menuitem==3) ( digitalWrite(9, LOW); if (backlight) (backlight = false; digitalWrite(9, LOW); ) else ( backlight = true; digitalWrite(9, HIGH); ) ) else if (pagina == 1 && menuitem==2) ( pagina=2; cnt1=0; cnt2=0; ) else if (pagina == 2) ( page=1 ; ) ) ) ISR (PCINT1_vect) ( // Dacă întreruperea este cauzată de un buton dacă (!digitalRead(A0)) ( buton = adevărat; ) // Sau dacă întreruperea este cauzată de semnalele codificatorului altfel ( // Citiți semnalele A și B boolean A_val = digitalRead(A1); boolean B_val = digitalRead(A2); // Scrieți semnalele A și B în secvențe separate seqA<<= 1; seqA |= A_val; seqB <<= 1; seqB |= B_val; // Маскировать четыре старших бита seqA &= 0b00001111; seqB &= 0b00001111; // Сравнить запсанную последовательность с ожидаемой последовательностью if (seqA == 0b00001001 && seqB == 0b00000011) { cnt1++; left = true; } if (seqA == 0b00000011 && seqB == 0b00001001) { cnt2++; right = true; } } }

Puteți vedea codificatorul în acțiune în videoclipul de mai jos.

Codificatorul de frecvență este similar ca aspect cu un rezistor variabil sau potențiometru. Aceleași trei pini, același corp de panou. Aici se termină asemănările lui. În interior are două comutatoare, care au o ieșire comună pentru sarcini de control și două proprii.

Pentru ca codificatorul să funcționeze, pinul din mijloc trebuie să fie conectat la masă, iar ceilalți doi pini trebuie conectați la alimentare prin rezistențe. Semnalul de control trebuie colectat direct de la bornele panoului codificatorului.

Acum să ne imaginăm că codificatorul este ideal și contactele sale nu suferă de chatter. Să conectăm un osciloscop la bornele codificatorului și să începem să rotim butonul codificatorului. Pulsurile vor fi deplasate unul față de celălalt cu 90 de grade. Dacă rotiți butonul de alimentare (kW) spre dreapta, stânga sau înapoi, vom avea secvențele panoului de control:

Dacă oscilogramele sunt o aplicație a unei secvențe de sarcini de zero și unu logic, atunci ele vor arăta astfel:

Să luăm un codificator obișnuit care are contact de respingere. Zona de respingere:

Când treceți de la unul logic la zero logic, are loc săritura. Bouncing-ul poate fi tratat în două moduri: hardware și software.

Metoda hardware este de a conecta o serie de condensatoare de frecvență, declanșatoare Schmitt, așa cum este indicat în diagrama panoului de control:

Este recomandat să folosiți o metodă software pentru combaterea chatterului. Această metodă este descrisă în biblioteca Rothery. Această bibliotecă conține mai multe funcții care sunt necesare pentru a configura ieșirile controlerului vectorial pentru intrare și pentru a conecta rezistențe de tracțiune de putere (kW). Biblioteca trebuie să specifice comenzile și sarcinile corespunzătoare. Această comandă pornește rezistența internă de tragere.

Funcția Get position vfd series returnează valoarea codificatorului. Această funcție este necesară pentru a obține numărul de impulsuri pe care le-a numărat codificatorul. Funcția set Position vfd este necesară pentru a încărca valoarea de la care codificatorul va începe numărarea.

Funcția de bifare trebuie analizată mai detaliat. Variabilele acestei funcții, sig1 și sig2, înregistrează starea pinului vectorial la care este conectat encoderul. Acești pini sunt apoi scrisi în variabila thisState vfd, care este starea curentă a codificatorului. Dacă starea curentă a codificatorului nu este egală cu cea anterioară, atunci se calculează noi direcții de numărare și numărul de impulsuri de putere este stocat în variabila Poziție. Când codificatorul revine la poziția sa vectorială inițială, va exista o deplasare la dreapta cu doi biți, iar noua valoare de control trebuie scrisă în variabila PositionExt. Această variabilă este necesară pentru a salva o serie de rezultate ale sarcinilor care vor fi utilizate în programul principal.

Verifica

După ce am analizat starea codificatorului la rotirea la stânga și la dreapta, întocmim un tabel:

Poziția sa de pornire este 1-1. La întoarcerea la dreapta, a apărut un clic, unitatea a devenit un zero logic. Noua valoare a acestei stări vfd este 01. Conform comenzii, acest rezultat este însumat cu valoarea variabilei Poziție.

Datorită faptului că a avut loc un chatter, poziția a devenit 11, după recalculare numărul de serie a devenit 7. După ce chatter-ul s-a terminat, trebuie să remediați noua poziție 01 și una este adăugată la zeroul precedent. La rotirea codificatorului, a fost un clic, iar valoarea variabilei Poziție a devenit una.

Un al doilea clic are loc atunci când codificatorul este rotit la dreapta și, în loc de poziția 01, avem poziția 00. După ce toate săriturile s-au terminat, ieșirea de control are și o valoare de unu. La al patrulea clic, când poziția de la 10 a devenit 11, avem valoarea 6. După terminarea sariturii, rămâne 6.

Unele codificatoare folosesc un buton de panou. Când apăsați și eliberați, contactele vor sări și ele; trebuie să utilizați biblioteca Bounce. Funcțiile acestei biblioteci sunt necesare pentru a seta pinul la care va fi conectat butonul și timpul de întârziere în milisecunde. Dacă butonul este apăsat, atunci funcția de putere (kW) returnează valoarea vectorului true, dacă nu, atunci false vfd.

Schema de conectare a codificatorului la convertizorul de frecvență

În industria mașinilor-unelte, codificatoarele sunt utilizate pe scară largă pentru convertoarele de frecvență ale motoarelor asincrone. Sunt montați ca senzori de feedback în funcție de viteza lor. Astfel de codificatoare au o discretitate mare de la 100 de impulsuri pe rotație la 1 milion de impulsuri pe rotație. Această marcă are o rezoluție de 500 de impulsuri. viceversa.

Codificatoarele sunt împărțite în tipuri de sarcini în funcție de. Sunt absolute și incrementale. Codificatorul nostru îndeplinește funcția obișnuită - produce un semnal de diferențiere atunci când alimentarea este oprită și alimentată din nou. Starea timpurie nu este păstrată.

Codificatoarele de tip absolut au o memorie internă care reține ultimele poziții. De ce este nevoie de memorie și de ce să salvezi aceste date? În fabricile de producție de mașini-unelte, înainte de a muta un anumit dispozitiv, punctul zero este mai întâi indicat. Acest proces se numește referire, adică merge la zero.

Utilizarea unui senzor de vedere absolută face posibilă evitarea a doua oară a acestei proceduri și reducerea timpului, cu condiția ca sistemul să aibă restricții de mișcare.

Să ne uităm la codificatoarele sinus și cosinus. Ele produc un semnal de ieșire cosinus sau sinus. Apoi, folosind un dispozitiv de interpolare a puterii, se formează impulsuri din ele. Semnalele de acest tip pot fi modificate în dimensiune. Encoderul este alimentat de la o tensiune de 5 volți.

Semnalul „A” este un semnal de impuls direct. Numărul de impulsuri de la acest semnal vine la fiecare rotație. Este egal cu 500 (rezoluția senzorului).

Semnalul „B” este, de asemenea, un semnal de impuls direct. De la acesta, la fiecare rotație, numărul de impulsuri este primit în funcție de discretitatea senzorului, care este deplasat de la canalul „A” cu 90 de grade (500).

Semnalul „R” este semnalul marcajului zero. Se obține un impuls dintr-o rotație a senzorului.

Codificatoarele industriale folosesc un semnal de diferențiere pentru a lucra cu un convertor de frecvență (convertor de frecvență). Numele lui este complicat, dar în realitate totul este simplu. Toate canalele sunt copiate separat prin inversarea lor. Acest lucru este necesar pentru a trimite un semnal pe distanțe semnificative. Canalul de ieșire al codificatorului este conectat la un receptor special realizat folosind amplificatoare de tip operațional. Impulsul este determinat în cele din urmă de combinația a două semnale.

Conexiune

Conexiunea este simplă. Conectam o tensiune de 5 volți la ieșirile encoderului. Avem un aspect: fir maro - 0 V, alb - +5 V, roz, verde și roșu - A, B, R.

Programul de conectare a codificatorului se bazează pe întreruperi ale canalelor A și B. Întreruperile sunt declanșate pe frontul de creștere. Acest lucru are ca rezultat o situație în care codificatorul încetinește în momentul intersecției rasterului și semnalul de ieșire al canalului rămâne întotdeauna pozitiv. Pulsurile sunt numărate continuu de un contor.

În cazul nostru, nu vom folosi întreruperi, deoarece lucrăm cu 4 senzori, aceștia sunt acționați simultan. Dacă utilizați un circuit de întrerupere, cel mai probabil va apărea o situație de pierdere a impulsului. Rezolvăm această problemă setând o pictogramă de prezență în mișcare. Și am luat în considerare funcționarea codificatoarelor industriale.

Funcționarea unui contor de impulsuri bazat pe un modul codificator

Contorul funcționează împreună cu un modul indicator cu șapte cifre, care va afișa numărul de impulsuri generate de encoder. Când este pornit, valoarea contorului este zero.

Să rotim butonul codificatorului în sensul acelor de ceasornic. Valoarea contorului este crescută cu unu de fiecare dată când se face clic pe codificator. Cel mai mare număr pe care îl puteți obține este 999999999. Acest număr ar trebui să completeze toate cifrele indicatorului nostru cu șapte segmente. Dacă rotiți butonul și mai mult, contorul se va reseta la zero și va începe să numere din nou de la zero.

De exemplu, să terminăm 120 de impulsuri. Acum răsuciți-l înapoi rotind mânerul în sens invers acelor de ceasornic. Axa centrală a codificatorului funcționează ca un buton. Șterge cifrele libere ale indicatorului de la zerouri. Butonul are o ușoară săritură de contacte, așa că oprirea și pornirea acestuia nu se întâmplă imediat. Prin software, chatter-ul este eliminat. Aceasta este baza pentru lucrul cu modulul codificator.

Pentru a implementa proiectul demonstrativ vom avea nevoie de:

  • encoder cu 24 de pozitii;
  • 16 LED-uri (3 mm);
  • driver LED A6276;
  • microcontroler PIC18F2550.

Un encoder este un element de control modern și original pentru dispozitivele digitale și, în aparență, este similar cu un rezistor variabil (vezi figura de mai jos). Un alt nume pentru acest control este senzor de unghi, senzor de rotație. Rotirea arborelui este însoțită de clicuri, de exemplu 24 de clicuri pe rotație. Codificatorul are 3 iesiri - A, B, C si este folosit pentru introducerea rapida a datelor in dispozitive digitale. Unele modele au un buton încorporat care este activat prin apăsarea arborelui codificatorului (se adaugă o altă ieșire).

Principiul de funcționare al codificatorului

Când rotiți un clic, de exemplu, spre dreapta, contactul A+C este închis mai întâi, apoi B+C. Când arborele este rotit la acest clic, contactele se deschid în aceeași secvență. Când arborele este rotit în cealaltă direcție, secvența de închidere cu contactul C se modifică, adică. la virarea la stânga, mai întâi B+C, apoi A+C sunt închise.

Folosind un encoder în proiecte de microcontroler, este posibil să se implementeze mai multe tipuri diferite de date de intrare folosind același encoder, cu toate acestea, acest lucru necesită un feedback și vizualizare, astfel încât utilizatorul să știe ce informații introduce și în ce poziție se află codificatorul.

Diagramă schematică

Pinii codificatorului A și B sunt conectați la porturile microcontrolerului RB4 și RB5, pinul codificatorului C este conectat la masă. Este de remarcat faptul că rezistențele de tragere trebuie conectate la liniile de semnal ale pinii A și B. Nu este o coincidență că encoderul este conectat la liniile I/O specificate ale microcontrolerului: în primul rând, portul B are rezistențe de pull-up încorporate și nu trebuie să conectăm cele externe și, în al doilea rând, portul B al microcontrolerului are o funcție foarte utilă - „interrupt-on-change” - întrerupere prin schimbarea nivelului, care ne va permite să monitorizăm starea encoderului.

16 LED-uri obișnuite de 3 mm sunt folosite pentru a vizualiza datele de intrare și acestea vor fi amplasate pe placa de circuit imprimat în jurul codificatorului instalat. LED-urile sunt conectate la cipul A6276.

Cipul A6276 este un driver LED cu intrare serială pe 16 biți. Driverul conține un registru de deplasare CMOS pe 16 biți, zăvoare asociate și drivere pentru a controla LED-urile și poate conduce mai multe LED-uri decât permite microcontrolerul. În plus, driverul poate fi controlat printr-o interfață SPI, care reduce și mai mult numărul de linii I/O utilizate și face proiectul scalabil.

Software-ul microcontrolerului pentru rezolvarea problemei noastre este relativ simplu. Există 3 moduri de operare (intrare de informații) și feedback:

  • Mod de poziționare 360° - în acest mod, LED-urile indică „poziția” curentă a codificatorului, utilizatorul poate roti arborele codificatorului la stânga și la dreapta la orice unghi;
  • Modul „Volum/Nivel” - în acest mod, LED-urile indică valoarea curentă între nivelul minim și maxim al intervalului de intrare (cum ar fi nivelul volumului în dispozitivele audio);
  • Modul comutator rotativ cu 3 poziții - În acest mod, există doar trei poziții selectabile pe care utilizatorul le selectează prin rotirea arborelui codificatorului la stânga/dreapta.

Demonstrarea proiectului

Descărcări

Se află o arhivă ZIP cu un proiect în mediul MPLAB și cod sursă în Hitech C, precum și o diagramă de circuit și topologia plăcii de circuit imprimat.