NexxDigital - računala i operativni sustavi

Načelo rada, sklopni krug i izvorni kod biblioteke za rad s inkrementalnim koderom već sam razmatrao u jednom od članaka. Danas ćemo govoriti o praktičnoj primjeni enkodera. Kao primjer, odabrao sam program generatora kvadratnog vala s radnim frekvencijskim rasponom od 1 - 100 Hz. Izvorna ideja sugerirala je raspon od 1 - 1000 Hz, no u praksi se pokazalo da je sortiranje kroz tisuću vrijednosti zamorno čak i s enkoderom.

Priprema

Napravite novi projekt u praznom radnom prostoru

Projekt > Stvori novi projekt…

Tip predloška C > glavni

Kopirajte izvorne datoteke biblioteke u mapu projekta za rad s koderom
koder.h i koder.c

Povezujemo datoteku encoder.c s našim projektom
Desnom tipkom miša u prozoru radnog prostora iu otvorenom izborniku Dodaj > Dodaj datoteke…

Kopirajte datoteku bits_macros.h u mapu projekta.


Uključujući datoteke zaglavlja

Na početku datoteke main.c popunjavamo sljedeće retke
#uključi
#uključi
#include "enkoder.h"
#include "bits_macros.h"

Postavite postavke projekta

Projekt > Opcije

tip mikrokontrolera
Opće opcije > Cilj > Konfiguracija procesora > ATMega8535

Dopuštanje upotrebe imena bitova definiranih u datotekama zaglavlja
Opće opcije > Sustav > Omogući bitne definicije...

Optimizacija veličine koda
C/C++ prevodilac > Optimizacije > Velika veličina

Vrsta izlazne datoteke
Povezivač > potvrdni okvir Izlazna datoteka Nadjačaj zadanu postavku i promijeni proširenje u hex
Linker > Format > Other odaberite Intel Standard

Pritisnite OK. Spremamo projekt i radni prostor.
Sada imamo prazan projekt s povezanim i konfiguriranim.

Zadatak

Natjerajte mikrokontroler da generira kvadratni val s frekvencijom od 1 do 100 Hz. Vrijednost frekvencije mora se postaviti pomoću kodera. Okretanje enkodera za jedan položaj treba odgovarati promjeni frekvencije generatora za 1 Hz.

Shema za naš primjer

Na izlaz je spojena LED dioda na kojoj će se generirati meandar kako bi se nekako vidio rezultat programa. Malo je vjerojatno da mnogi ljudi imaju osciloskop pri ruci.

Programski algoritam

Pravougaoni val se generira korištenjem 16-bitnog mjerača vremena T1, koji radi u CTC načinu rada - poništavanje nakon podudaranja. Flash memorija mikrokontrolera pohranjuje niz koji sadrži konstantu za svaku vrijednost tražene frekvencije. Varijabla pTimerValue koristi se za pristup elementima niza. U prekidima mjerača vremena T1, vrijednost konstante se čita i upisuje u registar usporedbe.

Izlaz PD5 (OC1A) se koristi za generiranje signala. Ima alternativne funkcije - može promijeniti svoje stanje u suprotno ako su registar za brojanje i registar za usporedbu jednaki.

U glavnom programu, u beskonačnoj petlji while, mikrokontroler ispituje međuspremnik enkodera i, ovisno o njegovoj vrijednosti, smanjuje ili povećava varijablu pTimerValue.

Na samom početku maina je kod za inicijalizaciju periferije i potrebne varijable.

Struktura programa

Radi jasnoće, opisao sam strukturu programa u obliku dijagrama.

Ovo je tipična struktura za izradu jednostavnih programa. Prekidi se prirodno javljaju na proizvoljnoj točki u petlji.

  • Inicijalizacija.
  • Beskonačna petlja (tzv. superpetlja) u kojoj se očekuje događaj, obično u obliku zastavica za prozivanje ili neke vrste međuspremnika.
  • Paralelni rad perifernih uređaja koji uzrokuju prekide. U njima se izvršava neki kod (po mogućnosti kratak) i postavljaju se zastavice.

Za jednostavne zadatke, ovaj pristup je dovoljan za oči. Za složenije postoje i drugi načini organiziranja programa. Budite strpljivi, doći će im uskoro.

Izračun konstanti za mjerač vremena T1

Izračunajmo vrijednost konstante za frekvenciju od 1 Hz. Već sam dao sličan izračun, ali neće biti suvišno podsjetiti ga se.

Taktna frekvencija mikrokontrolera je 16 MHz (vidi dijagram). Faktor predskalera timera je 256. Omogućuje vam da dobijete prekide s bilo kojom frekvencijom iz našeg raspona.

Period jednog otkucaja mjerača vremena bit će jednak 1 / (16 MHz / 256) = 16 µs

Na izlazu PD5 moramo primiti signal frekvencije od 1 Hz. Pin mijenja svoje stanje za svaki prekid timera, što znači da frekvencija prekida mora biti 2 puta veća. Za naš slučaj - 2 Hz.

Koliko otkucaja mjerača vremena stane u 2 Herca? (1/2 Hz)/16 µs = 31250
Ovo je tražena konstanta.

Ostale vrijednosti izračunavaju se na isti način. Za to obično koristim Excel.


Primljene vrijednosti stavljamo u niz

__bljesak nepotpisani int timerValue=
{

spremite ga u zasebnu datoteku - timer_value.h i povežite je s datotekom main.c

#include "timer_value.h"

Da, još uvijek morate dodati nekoliko konstanti u ovu datoteku

#define MAX_TIM_VALUE 99
#define MIN_TIM_VALUE 0

Uvjerimo se da smo pravilno izračunali konstante za tajmer. Pokrenimo ga. Programski kod će biti ovakav.

// programiranje AVR-a u C-u

//site 10/17/09
#uključi
#uključi
#include "enkoder.h"
#include "bits_macros.h"
#include "timer_value.h"

//indeks za pristup elementima niza
volatile unsigned char pTimerValue = 0;

int glavni( poništiti )
{
//inicijalizacija timera T1
TCNT1 = 0;
TCCR1A = (0<TCCR1B = (0<

//postavljanje pina PD5 na izlaz
SetBit(PORTD, PD5);
SetBit(DDRD, PD5);

// ne raditi ništa u beskonačnoj petlji
dok(1);
povratak 0;
}

Mislim da samo dio inicijalizacije timera zahtijeva objašnjenje.

Ponovno postavljanje registra za brojanje
TCNT1 = 0;

Inicijalizacija registara konfiguracije T1 mjerača vremena.
TCCR1A = (0<TCCR1B = (0<

Gdje bitovi WGM13, WGM12, WGM11, WGM10 postavljaju način rada tajmera - STS,
CS12, CS11, CS10 - odredite koeficijent predskalera tajmera -256,

COM1A1, COM1A0 - odredite ponašanje izlaza PD5 (OC1F) - u ovom slučaju, prema signalu timera, promijenit će svoje stanje u suprotno


Inicijalizirajte registar podudaranja početnom vrijednošću.
OCR1A=vrijednost odbrojavanja;

Prevodimo program i učitavamo ga u mikrokontroler. LED dioda treba treptati frekvencijom od 1 Hz.
U programu nema prekida. Nema manipulacije PD5 pinom. Međutim, LED lampica treperi!

Program

Sada trebate "pričvrstiti" koder na ovaj program. Postavimo postavke u datoteci zaglavlja encoder.h - priključak i pinove na koje je spojen koder, vrijednosti konstanti.


#define PORT_Enc PORTA
#define PIN_Enc PINA
#define DDR_Enc DDRA
#define Pin1_Enc 2
#define Pin2_Enc 1

#define RIGHT_SPIN 0x01
#define LEFT_SPIN 0xff

Zaglavlje sadrži tri prototipa funkcija. Prisjetimo se njihove namjene.

void ENC_InitEncoder(void) konfigurira pinove mikrokontrolera na koje je enkoder spojen na ulaz. Ova se funkcija mora pozvati na početku glavne.


void ENC_PollEncoder(void)– postavlja upit enkoderu jednom, analizira trenutno i prethodna stanja i upisuje odgovarajuće konstante (RIGHT_SPIN i LEFT_SPIN) u međuspremnik. Ova funkcija nalazit će se u prekidu mjerača vremena T0.


unsigned char ENC_GetStateEncoder(void)– vraća sadržaj međuspremnika kodera. Ako rotacija za jednu poziciju nije bila fiksna, funkcija će vratiti 0, ako je rotacija bila fiksna, funkcija će vratiti vrijednost odgovarajuće konstante. Ovo će izbrisati vrijednost međuspremnika. Ova funkcija će biti pozvana u glavnom programu - u petlji while.


Proširujemo naš program. Možete pokušati to učiniti sami.

// programiranje AVR-a u C-u
//primjer korištenja enkodera
//site 10/17/09

#uključi
#uključi
#include "enkoder.h"
#include "bits_macros.h"
#include "timer_value.h"

#define TCNT0_const 253
#define TCCR0_const 5

volatile unsigned char pTimerValue = 0;

int glavni( poništiti )
{
ENC_InitEncoder();

// inicijalizacija mjerača vremena t0
TCNT0 = TCNT0_konst;
TCCR0 = TCCR0_konst;

// inicijalizacija timera t1
TCNT1 = 0;
TCCR1A = (0<TCCR1B = (0<OCR1A=vrijednost odbrojavanja;

//omogući prekide mjerača vremena
//t0 - preljevom, t1 - slučajnošću

TIMSK = (1<

//konfigurirajte PD5 za izlaz
SetBit(PORTD, PD5);
SetBit(DDRD, PD5);

__omogući_prekid ();
dok (1){
//čitanje sadržaja međuspremnika kodera
// nakon čitanja se briše

unsigned char stateEnc = ENC_GetStateEncoder();

//ako nije prazno
ako(stateEnc != 0)(
//određivanje smjera rotacije i promjena varijable timerValue
ako(stateEnc == RIGHT_SPIN)(
ako(pTimerValue == MAX_TIM_VALUE) pTimerValue = MIN_TIM_VALUE;
drugo pTimerValue++;
}
ako(stateEnc == LEFT_SPIN) (
ako(pTimerValue == MIN_TIM_VALUE) pTimerValue = MAX_TIM_VALUE;
drugo pTimerValue--;
}
}
}
povratak 0;
}

//ispitivanje enkodera
#pragma vektor=TIMER0_OVF_vect
__prekinutiponištiti timer0_ovf_my( poništiti)
{
TCNT0 = TCNT0_konst;
ENC_PollEncoder();
}

#pragma vektor=TIMER1_COMPA_vect
__prekinuti poništiti timer1_compa_my( poništiti)
{
//ažuriraj vrijednost registra usporedbe
OCR1A=vrijednost odbrojavanja;
}

Čini se da je sve jasno.
Dio koda koji mijenja vrijednost pTimerValue također se može napisati ovako:

ako(stateEnc != 0) (
pTimerValue = pTimerValue + stateEnc;
ako(pTimerValue == (MAX_TIM_VALUE + 1)) pTimerValue = MIN_TIM_VALUE;
inače ako(pTimerValue == (MIN_TIM_VALUE - 1)) pTimerValue = MAX_TIM_VALUE;
}

Kada se enkoder okrene udesno, pTimerValue se dodaje na 1, odnosno povećava se.

Kada se koder okrene ulijevo, pTimerValue se dodaje 0xff, što je jednako oduzimanju 1. Ista operacija, ali rezultat je upravo suprotan.

Enkoder je stvar koja izgleda kao promjenjivi otpornik, ali za razliku od potonjeg nema ograničenja i može se okretati u bilo kojem smjeru beskrajno. Uz pomoć enkodera, vrlo je zgodno organizirati sve vrste izbornika na ekranu, općenito, jedan enkoder koji se može pritisnuti (odnosno, ako može raditi i kao gumb) idealan je za organiziranje jednodimenzionalnih cikličkih izbornici.

Postoje dvije vrste enkodera: apsolutni - odmah izdaje kod kuta rotacije i inkrementalni - izdaje impulse tijekom rotacije. Za potonje, mikrokontroler bi trebao biti uključen u brojanje impulsa i njihovo pretvaranje u kut rotacije.

S gledišta dizajna, enkoderi su mehanički i optički, u prvom se impulsi tijekom rotacije generiraju na paru kontakata kada su zatvoreni kliznim kontaktom osovine, u drugom fotodiode djeluju kao kontakti, a uloga kontaktora je LED dioda koja svijetli kroz disk s prorezima (pozdrav mišu s loptom) .

Iako postoji mnogo informacija o programiranju enkodera na mreži, kao i gotovih biblioteka za to, sve su one nekako nepotrebno glomazne (IMHO) - status polling se obično implementira kao automat stanja u obliku prekidača blok s ugniježđenim if-ovima, koji izgleda pomalo komplicirano (pogotovo kada je napisan u asembleru). Iako bi implementacija mogla biti jednostavnija.

Najpopularniji u nacionalnom gospodarstvu su jeftini mehanički inkrementalni koderi, a mi ćemo ih razmotriti. Proces rotacije osovine enkodera shematski je prikazan na slici (gore - rotacija u smjeru kazaljke na satu, dolje - suprotno od kazaljke na satu):


Ovdje su A i B isti kontakti, razine na kojima mikrokontroler mora obrađivati. Pokretni kontakt zatvara ih s masom ako ne padnu u njegove rupe. Ovdje napominjemo da slika prikazuje samo četiri rupe radi jednostavnosti. Zapravo, ovakvih rupa ima mnogo više (opet se prisjećamo miša s kuglicom i kako izgleda njegov optički kotačić za prekidanje). Zaključci A i B povlače se pomoću otpornika na napon napajanja. Kao rezultat, kada se okreću, dobivaju se dijagrami prikazani na gornjoj slici.

Pustite da oba kontakta u početku padnu u rupu, tada će imati visoku razinu napona (također se povlače na napajanje). Nadalje, kada se okreće u smjeru kazaljke na satu, kontakt A će biti prvi koji će biti zatvoren na tlo, zatim će mu se pridružiti kontakt B. Zatim, nakon što dođe do sljedeće rupe na disku, kontakt A će se otvoriti i dobiti visoku razinu, nakon čega će kontakt Sustići će ga B. Nakon ovih pokreta kontakti se vraćaju u prvobitno stanje, a daljnjom rotacijom ovaj dijagram će se ciklički ponavljati.

Dakle, ispada da je trenutno stanje enkodera opisano dvobitnom vrijednošću. Ali samo po sebi, trenutno stanje nosi malo korisnih informacija, a za analizu rotacije ono se mora razmatrati zajedno s vrijednošću prethodnog stanja. I ovaj par već nedvosmisleno određuje smjer rotacije ručke. Radi praktičnosti, uzmimo četverobitni broj, čija dva visoka bajta sadrže prethodna stanja kontakata A i B, a dva niska bajta sadrže trenutna.

I kada se okreće u smjeru suprotnom od kazaljke na satu

Binarni Decimal
1110 14
0001 1
0010 2
0111 7

Sada algoritam za određivanje smjera rotacije enkodera izgleda vrlo jednostavno: dobivamo vrijednost i uspoređujemo spada li u jedan od skupova (2, 4, 11, 13) i (1, 7, 8, 14). Ako da, onda imamo skretanje u odgovarajućem smjeru. U suprotnom, osovina se ili uopće nije okretala, ili se okretala toliko brzo da je preskočila nekoliko stanja (ako se to često događa, onda treba razmisliti o povećanju frekvencije prozivanja stanja), ili je došlo do "odskakanja" kontakata. Bez ulaženja u razlog, sve ostale vrijednosti se mogu sigurno zanemariti.

Kao primjer, razmotrite rad enkodera u kombinaciji s AVR mikrokontrolerom:


Ovdje se za spajanje koriste dva donja izlaza PB porta mikrokontrolera ATMega8. Par otpornika povlači ove vodove do napona napajanja (jer unutarnji otpornici atmege ovdje možda neće biti dovoljni za stabilan rad), par kondenzatora je instaliran za suzbijanje impulsne buke.

Za takvu shemu povezivanja možete skicirati sljedeću implementaciju u jeziku C:

Static uint8_t encoderGetVal() ( return PINB & 3; ) static uint8_t encoderGetCode() ( static uint8_t prev; uint8_t val = encoderGetVal(); uint8_t code = (prev<< 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); } }

Kod je jednostavan za sramotu - nekoliko if-ova i bez konačnih automata. Funkcija encoderInit() poziva se na početku kako bi se inicijalizirao port i zapamtila početna vrijednost. Funkcija encoderCheck() poziva se u petlji događaja (unutar main() ili na mjeraču vremena). Rukovatelj onEncoderEvent(bool) bit će pozvan kad god se koder rotira i primi oznaku smjera rotacije.

Ali postoji jedna važna točka ovdje: koder je osjetljiva stvar, i ako pokušate obraditi, na primjer, događaje navigacije izbornika na ovaj način, tada će čak i mali okret gumba kodera više puta pozvati onEncoderEvent() rukovatelj, kao rezultat toga, kursor izbornika umjesto da se pomakne na sljedeći/prethodni element, odmah će odletjeti na kraj/početak liste. Osjetljivost enkodera možete prilagoditi promjenom frekvencije poziva encoderCheck() (obično je optimalna frekvencija ~ 10 Hz). Istovremeno, metodu encoderGetCode() treba pozivati ​​što je češće moguće kako bi se uvijek imala trenutna vrijednost zadnjeg stanja kontakata (s frekvencijom od oko ~ 100 Hz).

U asembleru bi ovaj kod mogao izgledati ovako:

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, 1 sbi encoder_port, 0 sbi encoder_ luka, 1 u r0, encoder_pin andi r0, 3 točke sEncoderPrev, r0 ... Encoder_check lds ZL, sEncoderPrev lsl ZL lsl ZL u r0, encoder_pin andi r0, 3 točke sEncoderPrev, r0 ili ZL, r0 ; 1 7 8 14 -> u smjeru kazaljke na satu cpi ZL, 1 breq Encoder_u smjeru kazaljke na satu cpi ZL, 7 breq Encoder_u smjeru kazaljke na satu cpi ZL, 8 breq Encoder_u smjeru kazaljke na satu cpi ZL, 14 breq Encoder_u smjeru kazaljke na satu ; 2 4 11 13 -> suprotno od kazaljke na satu cpi ZL, 2 breq Encoder_suprotno od kazaljke na satu cpi ZL, 4 breq Encoder_suprotno od kazaljke na satu cpi ZL, 11 breq Encoder_suprotno od kazaljke na satu cpi ZL, 13 breq Encoder_suprotno od kazaljke na satu rjmp Encoder_done Encoder_u smjeru kazaljke na satu: ; ; ovdje je kod za rukovatelj rotacijom u smjeru kazaljke na satu; Koder_suprotno od kazaljke na satu: ; ; ovdje je kod rukovatelja rotacijom u smjeru suprotnom od kazaljke na satu; Interval_enc_done.

Često, u uređajima temeljenim na mikrokontrolerima, morate organizirati upravljanje stavkama izbornika ili implementirati neku vrstu prilagodbe. Postoji mnogo načina: koristite gumbe, promjenjive otpornike ili kodere. Inkrementalni koder vam omogućuje da nešto kontrolirate okretanjem gumba bez kraja. U ovom ćemo članku pogledati kako natjerati inkrementalni koder i Arduino u rad.

Značajke inkrementalnog enkodera

Inkrementalni enkoder, kao i enkoderi bilo kojeg drugog tipa, je uređaj s rotirajućom ručkom. Daljinski gledano, podsjeća na potenciometar. Glavna razlika u odnosu na potenciometar je da se ručica kodera okreće za 360 stupnjeva. Nema ekstremnih pozicija.

Koderi dolaze u različitim vrstama. Inkrementalni se razlikuje po tome što se njime ne može saznati položaj ručke, već samo činjenica rotacije u nekom smjeru - lijevo ili desno. Po broju signalnih impulsa već možete izračunati pod kojim se kutom okrenuo.

Na taj način možete poslati naredbu, kontrolirati izbornik, razinu glasnoće, na primjer, i tako dalje. U svakodnevnom životu mogli ste ih vidjeti u auto radijima i drugoj opremi. Koristi se kao višenamjenska kontrola razine, ekvilajzer i navigacija izbornikom.

Unutar inkrementalnog enkodera nalazi se disk s oznakama i klizačima koji su u kontaktu s njima. Njegova je struktura slična potenciometru.

Na gornjoj slici vidite disk s oznakama, one su potrebne za prekid električne veze s pokretnim kontaktom, kao rezultat dobivate informaciju o smjeru vrtnje. Dizajn proizvoda nije toliko važan, pogledajmo princip rada.

Enkoder ima tri informacijska izlaza, jedan je zajednički, druga dva se obično nazivaju "A" i "B", na gornjoj slici vidite pinout kodera s gumbom - možete primiti signal kada pritisnete njegovu osovinu .

Kakav ćemo signal dobiti? Ovisno o smjeru vrtnje, prvo će se pojaviti logična jedinica na pinu A ili B, pa dobivamo fazno pomaknuti signal, a taj pomak nam omogućuje da odredimo u kojem smjeru. Signal se dobiva u obliku pravokutnika, a upravljanje mikrokontrolerom događa se nakon obrade podataka o smjeru vrtnje i broju impulsa.

Na slici je prikazan simbol diska s kontaktima, u sredini je graf izlaznih signala, a desno je tablica stanja. Ovaj uređaj se često crta kao dvije tipke, što je i logično, jer zapravo primamo signal "naprijed" ili "natrag", "gore" ili "dolje", te broj udaraca.

Evo primjera pravog pinouta kodera:

Zanimljiv:

Neispravan enkoder može se zamijeniti s dva gumba bez zabravljivanja i obrnuto: domaći proizvod kojim upravljaju dva takva gumba može se modificirati ugradnjom enkodera.

U videu ispod možete vidjeti izmjenu signala na izlazima - uz glatku rotaciju, LED diode svijetle u slijedu prikazanom na prethodnom grafikonu.

To nije manje jasno ilustrirano u sljedećoj animaciji (kliknite na sliku):

Enkoder može biti optički (signal generiraju emiteri fotodetektora, vidi sliku ispod) i magnetski (radi na Hallovom efektu). U ovom slučaju nema kontakata i ima dulji vijek trajanja.

Kao što je već spomenuto, smjer vrtnje se može odrediti prema tome koji se od izlaznih signala ranije promijenio, ali ovako to izgleda u praksi!

Točnost upravljanja ovisi o razlučivosti enkodera - broju impulsa po okretaju. Broj impulsa može biti od jedinica do tisuća komada. Budući da koder može djelovati kao senzor položaja, što je više impulsa, točnije će biti određivanje. Ovaj parametar se naziva PPR - puls po okretaju.

Ali postoji mala nijansa, naime, slična oznaka LPR je broj oznaka na disku.

I broj obrađenih impulsa. Svaka oznaka na disku proizvodi 1 kvadratni val na svakom od dva izlaza. Impuls ima dvije fronte - stražnju i prednju. Budući da postoje dva izlaza, iz svakog od njih dobivamo ukupno 4 impulsa, čije vrijednosti možete obraditi.

Spojite se na Arduino

Shvatili smo što trebate znati o inkrementalnom koderu, a sada saznajmo kako ga spojiti na Arduino. Razmotrite dijagram povezivanja:

Modul enkodera je ploča na kojoj se nalaze inkrementalni enkoder i pull-up otpornici. Mogu se koristiti bilo koje igle.

Ako nemate modul, već zasebni koder, samo trebate dodati ove otpornike, krug neće biti bitno drugačiji. Da bismo provjerili smjer rotacije i njegovu izvedbu, možemo očitati informacije sa serijskog priključka.

Analizirajmo kod detaljnije, redom. U void setup() izjavili smo da ćemo koristiti serijsku komunikaciju i zatim smo postavili pinove 2 i 8 na način unosa. Sami birate pin brojeve na temelju vaše sheme povezivanja. Konstanta INPUT_PULLUP postavlja način unosa, arduino ima dvije opcije:

    ULAZ - ulaz bez pull-up otpornika;

    INPUT_PULLUP - povezivanje pull-up otpornika na ulaz. Unutar mikrokontrolera već se nalaze otpornici preko kojih je ulaz spojen na power plus (pullup).

Ako koristite otpornike za pull-up na napajanje kao što je prikazano na gornjim dijagramima ili koristite modul enkodera - koristite naredbu INPUT, a ako iz nekog razloga ne možete ili ne želite koristiti vanjske otpornike - INPUT_PULLUP.

Logika glavnog programa je sljedeća: ako imamo jedinicu na ulazu “2”, ona ispisuje H na port monitor, ako nema, ispisuje L. Dakle, pri rotaciji u jednom smjeru, ovako nešto će se okrenuti na monitoru serijskog priključka: LL HL HH LH LL. I obrnuto: LL LH HH HL LL.

Ako pažljivo čitate retke, vjerojatno ćete primijetiti da je u jednom slučaju prvi znak poprimio vrijednost, au drugom slučaju prvi se promijenio drugi znak.

Zaključak

Inkrementalni enkoderi našli su široku praktičnu primjenu u pojačalima za akustične sustave - korišteni su kao kontrola glasnoće, u auto radijima - za podešavanje parametara zvuka i navigaciju izbornikom, u računalnim miševima pomoću kojih svakodnevno listate stranice ( na njegovu je osovinu ugrađen kotač) . I također u mjernim instrumentima, CNC strojevima, robotima, u sinkronima ne samo kao kontrole, već i za mjerenje veličina i određivanje položaja.

Ukratko, enkoderi se mogu nazvati pretvarači kutnog pomaka. Služe za promjenu kuta rotacije predmeta rotacije, na primjer, osovine mehanizma, u signal električne struje. U ovom slučaju ne određuje se samo kut zakretanja osovine, već i njegov smjer vrtnje, kao i brzina vrtnje i trenutni položaj u odnosu na početni položaj.

Koderi su postali najpopularniji kada se koriste u preciznim sustavima gibanja, u tvornicama alatnih strojeva, u industrijskim kompleksima koji koriste robotiku, u mjernim uređajima koji trebaju bilježiti točna mjerenja nagiba, rotacije, rotacije i kutova.

Vrste i princip rada

Koderi su senzori rotacije. Najjednostavniji senzor ima ručku koja se može okretati u smjeru kazaljke na satu ili suprotno od njega. Ovisno o kutu i smjeru rotacije, emitira se digitalni signal koji vas obavještava u kojem se položaju ručka nalazi, odnosno u kojem je smjeru okrenuta.

S enkoderom prikazanim na slici, gumb se također može koristiti kao gumb. Ovo je pomoćna funkcija određene vrste kodera.

Prema vrsti izlaznih podataka, koderi se dijele u dvije velike skupine:
  1. Apsolutno.
  2. inkrementalni.
Apsolutni koderi

Kod apsolutnog enkodera cijeli se krug okretanja dijeli na određeni broj sektora, najčešće iste veličine. Ovi su sektori numerirani. Enkoder tijekom rada daje broj sektora u kojem se trenutno nalazi. Zato se naziva apsolutnim. Kod ove vrste enkodera uvijek je moguće odrediti pod kojim kutom u odnosu na nulti sektor je enkoder zakrenut u određenom trenutku, odnosno kada je zaokrenut daje vrijednosti brojeva sektora, do maksimalnog vrijednost. Zatim se vraća na nulu.

Ako se osovina enkodera okrene u suprotnom smjeru, počet će davati suprotne vrijednosti. U našem slučaju, koristi pet pinova za izlaz vrijednosti rotacije.

Ovaj algoritam ima svoje nedostatke. Tablica 1 prikazuje redoslijed izlaznih vrijednosti n-tog kodera. Vrijedno je obratiti pažnju na posljednja dva retka, prijelaz sa 127 na 128.

stol 1

Ovdje se mijenjaju apsolutno svi bitovi. U idealnom enkoderu svi se mijenjaju u isto vrijeme i nema problema. U praksi, u stvarnom koderu, bitovi se mijenjaju brzo, ali ne istovremeno. I u nekom trenutku, izlaz enkodera je potpuno proizvoljna vrijednost. Budući da se svi bitovi mijenjaju, dakle, koder će imati proizvoljnu vrijednost od nule do svih jedinica.

Desno je prikazan primjer takvog prekidača. Što bi mogla biti prijetnja? Uzmimo primjer. Mikrokontroler uz pomoć motora upravlja osovinom i okreće je pod određenim kutom. U određenom trenutku, pri prelasku sa 127 na 128 ćeliju, dobiva određenu slučajnu vrijednost. Kontroler zaključi da je osovina na sasvim drugom mjestu, za razliku od stvarnog mjesta, te je počne okretati u drugom smjeru, drugom brzinom itd.

Nakon određenog vremena, mikrokontroler prima točnu vrijednost, počinje pokušavati zaustaviti osovinu i okretati je u pravom smjeru. Takav proces može trajati dugo, pod uvjetom da se takva pogreška često pojavljuje. Takve su pogreške nepravilne i teško ih je izračunati.

Sivi kod

Gore opisani problem rješava se uvođenjem Grayeva koda. Značajka Grayeva koda je da kada se enkoder prebaci za jedan, vrijednost Grayeva koda također se mijenja za jedan. Samo se jedna vrsta mijenja. To se može vidjeti u tablici 2 koja uspoređuje binarni kod i Grayev kod.

tablica 2

Prva dva retka su ista, ali srednji bit je već promijenjen u drugom retku. Tada se jedan bit također mijenja. Također je vrijedno napomenuti da se zadnji i prvi Grayev kod razlikuju za jedan bit, odnosno da se Grayev kod može petljati.

Prednost ovog koda je u tome što gore spomenuta pogreška nije moguća. Među nedostacima se može primijetiti da mikrokontroler mora prevesti Grayev kod u binarni kod kako bi razumio u kojoj se poziciji nalazi apsolutni koder.

Inkrementalni koderi

Sljedeći tip je inkrementalni koder, koji ima jednostavniju strukturu. Ali u isto vrijeme, on ne pokazuje točno mjesto svoje olovke. Pokazuje samo smjer vrtnje, a broj podjela vrtnje mora izbrojati mikrokontroler.

Inkrementalni koder ima skup traka koje su prema zadanim postavkama spojene na masu, a kada se okreću, zatvaraju se i otvaraju. Ispada signal prikazan na slici (slično meandru). Koder ima dvije takve kružne trake. Stupci su pomaknuti za jednu četvrtinu, a signali su također pomaknuti za jednu četvrtinu. Ovo je važno jer vam omogućuje određivanje smjera rotacije.

Krug inkrementalnog kodera može se prikazati desnom slikom. Gumbi označavaju periodične veze kodera s uzemljenjem. Budući da enkoder nije spojen na logičku jedinicu iznutra, potrebno je logičke jedinice samostalno preko otpornika povući izvana na izlaz enkodera. U ovom slučaju, kada nijedan krak enkodera nije spojen na masu, krakovi će imati logični.

Ako je koder spojio neki krak na masu, tada će na tom kraku biti logička nula. U mirnom stanju, izlaz kodera je logička jedinica. Kada se enkoder počne okretati u bilo kojem smjeru, tada se prvo jedan izlaz spoji na masu, a zatim drugi. Nadalje, ti se zaključci redom odvajaju od tla i na njima se ponovno formira logička cjelina.

Možete odrediti smjer rotacije po tome koji je od zaključaka ranije bio spojen na tlo. Kada brojite pune cikluse, možete računati broj klikova rotacije kodera.

U stvari, koder ima četiri stanja:
  1. Dvije jedinice.
  2. Nula i jedan.
  3. Nula i nula.
  4. Jedan i nula.

Tri stanja koja nisu jednaka jedinici su nestabilna i koder ne može biti u njima. Mnogi mikrokontroleri implementiraju funkciju brojanja okretaja pomoću mjerača vremena koji imaju specifične ulaze. Tajmer na hardverskoj razini broji koliko klikova iu kojem smjeru je enkoder okrenut te daje vrijednost. Odnosno, brojač povećava bilo koji broj.

Promjenom ovog broja možete odrediti koliko je klikova enkoder okrenut. Brojem klikova možete odrediti kut rotacije. Koder također ima odbijanje kontakta što otežava analizu signala.

Optički koderi

Takav pretvarač izrađen je u obliku diska pričvršćenog na osovinu i izrađen je od stakla. Optički senzor rotacije razlikuje se od ostalih vrsta dodatnim optičkim senzorom koji se pomiče kada se osovina okreće. Istodobno pretvara moment rotacije u svjetlosni tok, koji zatim prima fotosenzor.

Optički pretvarač pamti kutove rotacije. U tom slučaju svaka pojedinačna pozicija odgovara posebnom digitalnom kodu, koji zajedno s brojem okretaja čini mjernu jedinicu kodera. Koder je povezan i radi na isti način kao inkrementalni koder.

Prema prirodi funkcioniranja dijele se na fotonaponski I magnetski . Princip rada magneta temelji se na čijoj je uporabi prvi put otkriveno 1879. godine. U ovom slučaju, potencijalna razlika se pojavljuje samo kada se DC žica nalazi u magnetskom polju.

U pogledu svojstava točnosti i razlučivosti, magnetski tip senzora je inferioran u odnosu na fotoelektrični, ali u smislu dizajna je jednostavniji, manje zahtjevan za radne uvjete i prostor. Magnetski enkoder je uređaj koji detektira prolazak magnetskog pola magneta tijekom rotacije, smješten pored senzorskog elementa. Informacije o odašiljaču izražavaju se u digitalnom kodu.

Fotoelektrični koder je senzor koji se temelji na fotoelektričnom principu. Ovaj se učinak opaža kada svjetlosni tok djeluje na tvar. Ovaj princip je otkriven 1887. Tijekom rada takvog senzora dolazi do stalne pretvorbe snopa svjetlosti u signal električne struje.

Analozi fotoelektričnog kodera su optoelektronički, optički i. Ovi senzori su osjetljiviji na karakteristike proizvodnje, rad i druge čimbenike od ostalih modela. Međutim, to je opravdano njihovom povećanom preciznošću, za razliku od konkurenata.

Inkrementalni koder izvana sličan potenciometar, ali za razliku od potenciometra, nema ekstremnih položaja, može se okretati u oba smjera neograničen broj okretaja. Također treba napomenuti da se inkrementalni enkoder ne okreće glatko kao potenciometar, već u koracima. Može se vidjeti na radiju u autu, osciloskop, glazbeni centar, perilica rublja i druga oprema, gdje se podešavanje nekog parametra provodi u širokom rasponu. Naravno, parametri se mogu mijenjati i pomoću tipki, na primjer, da bi glazba bila glasnija za 20 vrijednosti, kod upravljanja tipkom potrebno ju je pritisnuti 20 puta, a pri kontroli enkodera okrenuti je na određeni kut, ovisno o algoritmu obrade.

Inkrementalni koder su dva kontakta čiji redoslijed zatvaranja ovisi o smjeru vrtnje.


Zapravo inkrementalni enkoder pretvara rotaciju osovine u električne impulse, koji sadrži podatke o smjeru rotacije.

Sastavimo ispitni krug prikazan na gornjoj slici i spojimo ga na pin A i B osciloskop, pull-up otpornici - 4.7K.
Okrenite enkoder u smjeru kazaljke na satu.


Sada suprotno od kazaljke na satu.


Oscilogrami pokazuju da se, ovisno o smjeru vrtnje, mijenja redoslijed zatvaranja kontakata. Ali prednja strana ne ispada uvijek tako lijepa.


Budući da su kontakti mehanički, skloni su odbijanju, odnosno pri zatvaranju zbog elastičnosti materijala dolazi do višestrukog nekontroliranog zatvaranja i otvaranja, što se može vidjeti na gornjem oscilogramu.

Postoje dva načina za rješavanje zveckanja. prvi sastoji se od dodavanja kondenzatora i otpornika, kao što je prikazano na slici ispod.


Budući da je odskakanje kratkotrajna pojava, kondenzator ga lako gasi.


Oscilogram pokazuje da su nakon ugradnje kondenzatora fronte postale manje strme, a odskok je nestao.

Drugi način- softver i sve ovisi o implementaciji prozivanja izlaza enkodera. Ako status kodera nadziran vanjskim prekidima, tada je nakon aktiviranja prekida potrebno napraviti odgodu od 20 - 30 milisekundi, tijekom koje MK neće reagirati na promjenu stanja izlaza, odnosno neće osjetiti odbijanje. Ako Prozivanje izlaza kodera implementirano na mjeraču vremena, tada bi interval između anketa trebao biti veći od trajanja odbijanja, istih 20 -30 milisekundi.

razmotrimo metode za obradu podataka koji dolaze iz kodera.
Prva metoda je da spojimo jedan od krakova enkodera na izlaz vanjskih prekida i konfiguriramo ga za prekid na padajućem rubu. U prekidu provjeravamo stanje druge noge i ako je nula onda dolazi do rotacije u jednom smjeru, inače u drugom. Ispod je kôd koji implementira ovu metodu za AVR.
#uključi ISR(INT2_vect) ( if (PINB & 0X02) ( PORTB |= (1<<0); } else { PORTB &= ~(1<<0); } //антидребезг _delay_ms(20); //сбрасываем флаг прерывания вызванный дребезгом GIFR = (1<Kada okrenete enkoder u jednom smjeru, LED dioda svijetli, kada ga okrenete u drugom smjeru, gasi se.

Druga metoda je da se usporedba sadašnjeg i prethodnog stanja. Izrazimo logičke razine niza impulsa kao nule i jedinice.


Tada dobivamo konačan broj stanja kodera. Prva znamenka je logička razina prvog izlaza enkodera, druga je logička razina drugog izlaza.

Pretpostavimo da je zadnje stanje u kojem se nalazio enkoder jednako tri, ako je sljedeće stanje jednako jedan, onda se okreće u jednom smjeru, ako dva, onda u drugom. Ispostavilo se da je moguće popraviti prijelaz iz jednog stanja u drugo i odrediti smjer rotacije, ali najjednostavnija implementacija je kada se kreće od 11 do 01 i 10. Ispod je kod koji implementira opisani algoritam za AVR,
#definiraj F_CPU 8000000UL #uključi #uključi uint8_t zadnje_stanje = 0; ISR(TIMER0_COMP_vect) ( //oba izlaza enkodera spojena su na pinove 2 i 3 priključka B //čitanje njihovog stanja uint8_t current_state = (PINB & 0x06)>>1; //uzeti u obzir prijelaz samo ako je prethodno stanje 11 //i ako nije jednako novom if ((last_state == 3) && (last_state != current_state)) ( //ako je novo stanje 01 - upali LED if(current_state == 1) ( PORTB |= 0x01; ) //ako je novo stanje 10 - ugasi LED if(current_state == 2) ( PORTB &= ~0x01; ) ) //prilikom izlaska iz prekida, trenutno stanje postaje prošlost last_state = current_state / /postavi timer da se slučajno poništi TCCR0=(1<To je sve.
Koder kupljen



Ako primijetite pogrešku, odaberite dio teksta i pritisnite Ctrl + Enter
UDIO:
NexxDigital - računala i operativni sustavi