[elektro] rotary encoder, mit csinálok rosszul?
nemeth.tibor798 at t-online.hu
nemeth.tibor798 at t-online.hu
Mon Jan 2 15:34:20 CET 2017
Hali!
Bár őskövületnek érzem magam, de mivel több mint 20 éve működik a
módszer, leírom a lényeget. Én még mindig ASM-ban nyomulok, munkás
nagyon, de legalább tudom mit csinálok.
A két encoder bit 1 portra megy, a portot csak egyszer olvasom és
eltárolom majd feldolgozom. Bár nem teljesen értem a C-t, de ha jól
látom a programodban többször van If (ENCx_PORT) és ez gondolom port
olvasást jelent. Nos semmi garancia rá, hogy két olvasás között nem
változik, már úgy értem egy interrupton belül.
A feldolgozásra nagyon gyalog, de szerintem nagyon hatékony,
ugrótáblás módszert használok. Van két régi bitem és két aktuális. Ez
a 4 bit egy ugrótáblába megy be ami 16 elemű. Az egyidőből származó
bitek szomszédosak.
Gondolom ez C-ben sem gond, nekem ASM van:
Itt W alsó 4 bitje játszik.
ANDLW 0FH
ADDWF PCL,1
GOTO NNOOPP
GOTO DECPOSITION
GOTO INCPOSITION
GOTO ERRORCOUNT
GOTO INCPOSITION
GOTO NNOOPP
GOTO ERRORCOUNT
GOTO DECPOSITION
GOTO DECPOSITION
GOTO ERRORCOUNT
GOTO NNOOPP
GOTO INCPOSITION
GOTO ERRORCOUNT
GOTO INCPOSITION
GOTO DECPOSITION
GOTO NNOOPP
A megfelelő címkéken van a növelő, csökkentő, semmittevő és
hibaszámláló rutin.
Eredetileg PIC16C54-en volt egy 4 dimenziós problélmám, az a PIC csak
ezt a feladatot látta el, mivel annak még nem volt megszakítása,
egyszerűen polloztam, elég sűrűn. A pozíciókat nyomta ki soroson. A
rutinokban elhelyezett NOP-okkal megoldottam, hogy minden ágon azonos
legyen a végrehajtási idő. Ez azért kellett mert abban soros harder
sem volt, igy a bit-idők voltak kitöltve az encoderek feldolgozásával.
Modernebb PIC-ben B port change mexakítást használom, Itt meg kellett
tanulnom, hogy ha a port egyéb lábait is használni akarom, akkor arra
erősen ügyelni kell, mert a port olvasása törli a hardverbiteket (a
változást jelző flipflopot) és szerencsétlen egybeesés esetén elmarad
az interrupt.
Persze nem árt ha a hardver tiszta jeleket produkál, de a fenti
módszer jól tűri, ha az él körül pereg a bit, számlál szépen
oda/vissza. Ha a kettő bit egyszerre változik, azt ez sem tudja
lekezelni, de az egyértelműen hiba. No és persze olyan is volt, hogy
egy nem túl jól kivitelezett kapcsistáp teleszórta zavarral én meg az
encoder szidtam. Szóval ez is egy lehetőség.
Üdv.
Németh Tibor
Idézet (Gabor Jordan <jordang.elektro at gmail.com>):
> ÜDV,
>
> Rotary encoder, PIC18F67K90 B3 és B4 lábain csücsül, felhúzva
> 47k-val kívülről.
>
> A lenti megszakítás (XC8) kezelné le, de nem jó. Kb. 10ből 8szor jól
> lép, de 2szer vagy rossz irányba, vagy többet. Az ENC1 lefutóél
> csinál megszakítást és nézem az ENC2 láb hogyan áll. Mindig is így
> csináltam és ment. Optikai enkóderrel most is megy. Így is
> (lassabban) meg úgy is, ha kiveszem a késleltetéseket. Hiba nélkül.
> Gondolom a mechanikusnál a prell-el vagy kontakt-al van gond.
> Szkópon nem is túl szép a kapcsolás, látszik a prell, de lemegy még
> a késleltetések előtt (legalábbis amit látok). Mégsem jó, hiába
> játszom az időzítésekkel.
>
> Más tipusú enkoderrel jó volt (bourns), de amit most használni
> akarok, nem jó. Van több darab, cseréltem is, de nem jó.
>
> Hogy illik megbízhatóan olvasni ezeket?
>
> 1 szintű megszakítást használok, a megszakítás kezelést elvileg nem
> szakítja meg másik megszakítás (legalábbis az XC9 azt mondja ne
> kapcsolgassam a kódban a GIE-t, ő megteszi).
>
> Köszönöm,
>
> ÜDV JG
>
> *****
>
> if (INTCON3bits.INT3IF==1) // interrupt from rotary encored
> {
> INTCON3bits.INT3IF=0;
> __delay_us(50);
> if (ENC1_PORT==0)
> {
> __delay_us(50);
> if (ENC1_PORT==0)
> {
> __delay_us(50);
> if (ENC1_PORT==0)
> {
> if (ENC2_PORT)
> {
> //LCDPutCmd(01);
> //LCDPutStr("vissza");
> pwm = pwm - 16;
> }
> else
> {
> //LCDPutCmd(01);
> //LCDPutStr("oda");
> pwm = pwm + 16;
> }
> update = 0x01;
> }
> }
> }
> }
>
> *******
>
> ----------------------------------------- elektro[-flame|-etc]
More information about the Elektro
mailing list