====== Kooder ====== //Vajalikud teadmised: [HW] [[et:hardware:homelab:digi]], [HW] [[et:hardware:homelab:combo]], [LIB] [[et:software:homelab:library:module:encoder]], \\ [LIB] [[et:software:homelab:library:module:lcd_graphic]], [AVR] [[et:avr:timers]], [AVR] [[et:avr:interrupts]]// ===== Teooria ===== [{{ :et:examples:sensor:kooder_optron.jpg?220|Optopaar}}] Kooder on elektro-mehaaniline seade, mis muundab võlli pöördenurga või nurkkiiruse analoogsignaaliks või digitaalkoodiks. Olemas on veel lineaarkoodrid, mis erinevad pöördliikumisele mõeldud koodritest selle poolest, et koodri liikumine toimub mööda sirget. Muus osas on tööpõhimõte sarnane. Olemas on kahte peamist tüüpi koodreid: absoluutsed ja suhtelised (loendavad). Absoluutse koodri väljund näitab jooksvat võlli asendit. Toite katkemise korral on asend peale toite sisselülitamist uuesti tuvastatav. Alloleval pildil olev parempoolne kooderketas on lihtne absoluutkoodri ketas, mida loetakse kolme anduri abil. Moodustuv binaarkood võimaldab ketta asendit mõõta 45 kraadiste sammude täpsusega. [{{ :examples:sensor:encoder:kooder_kettad.png?300|Koodri ketas (vasakul suhteline, paremal absoluutne)}}] Suhtelise koodri väljund annab informatsiooni võlli liikumise kohta, mida saab edasi töödelda. Tüüpiliselt arvutatakse liikumise kiirus ja suund. Suhteline kooder ei võimalda peale toite kadumist võlli konkreetset asendit enam kindlaks teha. Suhteline kooder annab tsüklilist väljundsignaali ainult siis, kui võll pöörleb. Suhteline optiline kooder koosneb avade või lõhedega kettast ja optopaarist. Optopaar on IR-valgusdioodist ja fototransistorist koosnev süsteem, mille vahele on asetatud piludega kooderketas nii, et ketta pöörlemisel avad perioodiliselt katkestavad valguse ning seetõttu vastavalt lülitavad fototransistorit sisse ja välja. Selle tulemusena tekib fototransistori väljundis ristküliksignaal, mida saab kasutada võlli nurkkiiruse leidmiseks. Ühe optopaariga koodrid võimaldavad impulsside sageduse järgi mõõta ainult pöörlemiskiirust. Pöörlemissuuna kohta informatsioon puudub. Lisaks optilistele koodritele on laialt kasutusel Halli efektil põhinevad koodrid. Kooder koosneb vahelduva magnetväljaga andurikettast või püsimagnetist, mis pööreldes genereerib pooljuhis pingeimpulsse. Pingeimpulsid võimendatakse ja muudetakse kontrollerile saadetavaks digitaalseks signaaliks. Koodri signaalide lugemine on analoogne optiliste koodrite signaalide lugemise ja tõlgendamisega. Võlli pöörlemissuuna kindlakstegemiseks on vaja lisada teine optopaar. Kui optopaarid on asetatud nii, et tekiks 90 kraadine faasinihe nende signaalide vahel on tegemist kvadratuur väljunditega. Optopaaride signaalide olekudiagramm on toodud juuresoleval pildil, kus optopaaride väljundeid on tähistatud A ja B. Väljundid loetakse tarkvaraliselt, tavaliselt katkestuste vahendusel, mis genereeritakse signaali tõusva või langeva frondi korral. Pöörlemissuuna saab määrata väljundkoodide võrdlemise abil. Näiteks, kui viimane väärtus on 00 ja uus väärtus 01, siis võll on pöördunud ühe poolsammu võrra kellaosuti liikumise suunas. [{{:et:examples:sensor:koodri_graafika.png?350|Koodri tööpõhimõte}}] ^ ^ Kellaosuti liikumise \\ suunaline pöörlemine ^^ ^ Kellaosuti liikumise \\ vastassuunaline pöörlemine ^^ ^ Faas ^ A ^ B ^ ^ A ^ B ^ | 1 | 0 | 0 | | 1 | 0 | | 2 | 0 | 1 | | 1 | 1 | | 3 | 1 | 1 | | 0 | 1 | | 4 | 1 | 0 | | 0 | 0 | ===== Praktika ===== Kodulaboris on koodrite sisendid seotud taimerite viikudega. Kasutada saab nii Halli anduril põhinevaid, kui ka optilisi koodreid. Elektrilised ühendused on toodud vastava plaadi riistvarakirjelduses Kodulabori teek võimaldab lugeda koodri pulsse. Koodri pulsside loendamine toimub viigu langeva frondi korral genereeritava katkestuse kaudu. Katkestuse toimumise korral suurendatakse vastava koodri pulsside arvu muutujat ühe võrra. Koodri kasutamiseks on Kodulabori teegis olemas funktsioon //encoder_init//, mis seadistab koodri viigud sisendiks ja seab töökorda katkestuse. Funktsioon //encoder_get_pulses// tagastab koodri pulsside arvu ja funktsioon //encoder_reset_pulses// nullib valitud koodri pulsside arvu. Järgnevalt on toodud näide koodrite lugemisest ATmega2561 kontrolleriga. // Koodrite arv #define NUM_ENCODERS 2 // Koodri pulsside arvu määramine sekundis #define ENCODER_TICKS (F_CPU / 8 / 256) // Viikude määramine static pin encoder_pins[NUM_ENCODERS] = { PIN(E, 6), PIN(E, 7) }; typedef struct { unsigned short num_pulses; } encoder_data; static encoder_data encoder[NUM_ENCODERS]; // Katkestuste töötleja void encoder_pulse(unsigned char index) { encoder[index].num_pulses++; } // Katkestused ISR(INT6_vect) { encoder_pulse(0); } ISR(INT7_vect) { encoder_pulse(1); } // Koodrite seadistamine void encoder_init(unsigned char index) { // Viigu sisendiks seadistamine koos pull-up takistite lubamisega pin_setup_input_with_pullup(encoder_pins[index]); // Välise katkestuse võimaldamine, genereeritakse langeva frondi tekkides switch (index) { case 0: bit_set(EICRB, ISC61); bit_clear(EICRB, ISC60); bit_set(EIMSK, INT6); break; case 1: bit_set(EICRB, ISC71); bit_clear(EICRB, ISC70); bit_set(EIMSK, INT7); break; } // Algväärtustamine encoder[index].num_pulses = 0; } // Valitud koodri nullimine void encoder_reset_pulses(unsigned char index) { cli(); encoder[index].num_pulses = 0; sei(); } // Koodri pulsside arvu loendamine unsigned short encoder_get_pulses(unsigned char index) { return encoder[index].num_pulses; } Funktsioonide kasutamist demonstreerib näiteprogramm, mis kuvab koodri pulsside arvu ekraanile. Nupp S2 nullib koodri ja alustab uuesti loendamist. // Kodulabori koodri kasutamise näidisprogramm // LCD-le kuvatakse koodri pulsside arv #include #include #include #include #include // Põhiprogramm int main(void) { unsigned short pulses = 0; char text[16]; // Nupu seadistamine pin_setup_input_with_pullup(S2); // Koodri algväärtustamine encoder_init(1); // Loendamise nullimine ja käivitamine encoder_reset_pulses(1); // LCD ekraani algseadistamine lcd_gfx_init(); lcd_gfx_clear(); lcd_gfx_backlight(true); lcd_gfx_goto_char_xy(3, 1); lcd_gfx_write_string("Kooder"); // Lõputu tsükkel while (1) { pulses = encoder_get_pulses(1); // Teksti moodustamine. sprintf(text, "Pulsse: %5d",pulses); lcd_gfx_goto_char_xy(0, 3); lcd_gfx_write_string(text); // Nupp S2 alla vajutatud? if(button_read(S2)) { // Loendamise nullimine ja käivitamine encoder_reset_pulses(1); // Vana teksti tühikutega ülekirjutamine lcd_gfx_write_string(" "); } // Paus 10 millisekundit sw_delay_ms(10); } }