Rotacinio enkoderio nuskaitymas

Posted: 2016-01-20 in Darbeliai
Žymos:,

Apšvietimo reguliavimui man norisi naudoti rotacinius enkoderius, o ne kokius nors potenciometrus. Panašiai, kaip dauguma grotuvų automobiliuose. Yra vienas didelis ratukas, kurį paspaudus paprastai įvyksta įjungimas/išjungimas, o sukant dešinėn ar kairėn atitinkamai didinamas arba mažinamas garsas. Rotacinis enkoderis sukamas spragsi ir į abi puses gali būti sukamas be galo. Sukimo krypčiai nustatyti yra trys kojelės: bendra (C, common), A ir B. Tų kojelių generuojami impulsai ir padeda nustatyti, kurion pusėn enkoderis sukamas.

Kad būtų kiek aiškiau, įdedu iš internetų paveiksliuką:

Rotacinio enkoderio impulsai | Darau, blė

Tiksliai nežinau, kur pagal šitą paveiksliuką prijungta rotacinio enkoderio C kojelė — ar prie „žemės“, ar prie maitinimo pliuso. Lyg ir prie pliuso turėtų būti, bent jau pagal mano stebėjimus. Priklauso nuo to, kokią nustatysit nuskaitymo elektrodo standartinę reikšmę (kai niekas neprijungta).

Priklausomai nuo sukimo krypties impulsą pirmiau generuoja arba A, arba B elektrodas. Vieno elektrodo impulso kraštas bei kito elektrodo tuometinė būsena maždaug nusako, į kurią pusę sukimas keliauja. Geriau nuskaityti du impulsų kraštus, tai tada tikrai bus aišku.

Manau, kad šiek tiek prakutę su mikrovaldikliais skaitytojai supranta, jog geriausia impulsų nuskaitymą daryti su pertraukimais ties atitinkamais krašteliais. AVR procesoriukai turi du elektrodus su „asmeniniais“ pertraukimais (IRQ0 ir IRQ1), beigi dar gali naudoti bendrus visos elektrodų grupės pertraukimus (Pin Change Interrupt).

Mano pamilti STM32F10x procesoriukai turi kiek daugiau išorinių pertraukimų. Bet taip labai įdomiai. EXTI0 iki EXTI4 yra individualūs pertraukimai, prie kurių gali būti prikabintas bet koks vienas elektrodas su skaičiuku 0 iki 4. Na, ant EXTI0 gali būti pakabintas PA0, PB0, PC0…PG0 (jei jų tiek yra). Ant EXTI1 atitinkamai PA1…PG1. Na ir kiekvienam iš šių pertraukimų yra individualus NVIC kanalas bei individuali apdorojimo paprogramė.

Tuo tarpu pertraukimai nuo EXTI5 iki EXTI9 yra sugrupuoti į vieną NVIC kanalą. Pertraukimai kaip ir atskiri, t.y. kiekvienam iš jų priskiriamas elektrodas, bet kanalas — vienas. Taip pat viena vienintelė visų šių pertraukimų apdorojimo paprogramė. Jei reikia konkrečiai žinoti, kuris elektrodas sukėlė pertraukimą, tą reikia su ifukais nustatyti jau paprogramėje.

Atitinkamai į vieną kanalą yra sugrupuoti ir pertraukimai nuo EXTI10 iki EXTI15.

Čia šiaip, papildoma informacija 🙂 Trumpai tariant, pasistengus su STM32F10x procesoriuku galima sekti šešiolika išorinių petraukimų. Tuo pasinaudodamas parašiau nedidukę rotacinio enkoderio apdorojimo bibliotekėlę. Galvojau, kaip šitą dalyką įgyvendinti, ir vienaip, ir kitaip. Peržiūrėjau krūvas Arduino bibliotekų, šiek tiek STM32 pavyzdukų ir galų gale apsistojau ties tokiu variantu, kuris yra kraupiai paprastas, užima labai mažai kodo ir yra gan efektyvus. Smagumas toks, kad rotacinio enkoderio nuskaitymui pertraukime užtenka iškviesti vieną paprogramę jai nurodant A ir B elektrodus. Dar vienas smagumas, kad tą paprogramę galima kviesti ir bendrose pertraukimų apdorojimo paprogramėse visai nesukant galvos, kuris elektrodas sukėlė pertraukimą.

Paprogramėje naudojamas histerezės principas, t.y. sistemos reakcija į kažkokį įvykį su priklausomybe nuo prieš tai buvusios būsenos. Paprastai sakant, išsaugomos elektrodų reikšmės per vieną impulsą ir panaudojamos per kitą impulsą. Paprasta dvejetainė matematika išsaugant elektrodų būsenas į keturis bitukus ir atitinkamų reikšmių masyvas. Šio metodo trūkumas toks, kad dalis pertraukimų generuoja beprasmes reikšmes, o kai kurios iš jų kartojasi. Bet po kelių bandymų įsitikinau, kad per vieną spragtelėjimą vis tiek kažkas nustatoma, o tai visai gerai — mažiau krūvio sistemai, nuskaitomi praktiškai tik naudingi impulsai. Be to, vienoje pertraukimo paprogramėje galima nuskaitinėti kelis rotacinius enkoderius!

Čia nuotraukėlė iš bandymo. Enkoderis prijungtas prie PA0 ir PA1 elektrodų, rezultatai išvedami į USART1:

ARM, STM32F10x, Rotary encoder | Darau, blė

Pagal aprašymus rotacinio enkoderio elektrodai yra tokie: A — juodas, C — rudas, B — raudonas.

Į biblioteką įdėjau atskirą nuskaitinėjimą enkoderio mygtukui. Būtų buvę galima ir į vieną paprogramę viską sukraut, bet pagalvojau, kad AB ir mygtuko nuskaitymui patogiau turėti atskiras paprogrames.

Programuotojams taip pat paliekamas visas GPIO, EXTI linijų ir NVIC pertraukimų konfigūravimas bei pertraukimo paprogramių užpildymas. Perrašius biblioteką ją galima panaudoti ir su Arduino, nors aš čia tikrai nepersistengiau su universalumu. Tiesiog tas algoritmas tinka bet kokiai aparatūrai.

Parsisiųskite ir naudokite, jeigu yra noro: Small and efficient library with example to read rotary encoder direction for STM32F10x family microcontrollers.

Advertisements

Parašykite komentarą

Įveskite savo duomenis žemiau arba prisijunkite per socialinį tinklą:

WordPress.com Logo

Jūs komentuojate naudodamiesi savo WordPress.com paskyra. Atsijungti / Keisti )

Twitter picture

Jūs komentuojate naudodamiesi savo Twitter paskyra. Atsijungti / Keisti )

Facebook photo

Jūs komentuojate naudodamiesi savo Facebook paskyra. Atsijungti / Keisti )

Google+ photo

Jūs komentuojate naudodamiesi savo Google+ paskyra. Atsijungti / Keisti )

Connecting to %s