Rotary Encoder
Rotary Encoder modulet har et skaft på toppen, som kan roteres omkring en lodret akse. Dette skaft kan roteres uendeligt. Modulet kan registrere registrere skaftets rotationer.
Rotary encoders bliver brugt til mange processer, som kræver præcis uendelig rotation. Eksempelvis kan det bruges til computer mus med drejehjul, hvor det skal registreres i hvor meget kuglen drejer og i hvilke retninger. Det kan bruges til robotter, for at registrere hvor meget robotens motorer er drejet. Det kan også bruges i kamerar linser, for at undersøge hvor meget kameraret er zoomet ind.
Siden at modulet kan rotere uendeligt, har den ikke rigtigt nogen start eller slutning, men hvis man, i koden, holder styr på rotationen, så kan man bruge modulet bruges til at skrue op eller ned for noget, eksempelvis volumen af lyd eller styrken af lys lys. Rotary Encoder afgiver kun information når der bliver drejet på skaftet, den kan altså ikke fortælle nuværende position. Hvis man skal have en start position, skal man sætte skaftets nuværende position til start og så vil man derefter kunne skrue op eller ned. Modulet kan dog heller ikke gemme informationer, så når programmet bliver genstartet, vil den igen gøre skaftets nuværende position til start position. Så hvis man ønsker en position, som fast skal være start position, så skal man enten, aldrig lukke programmet eller sætte skaftets position tilbage til start før man starter sit program.
Benforbindelser til modul
Signal | pin | Pic-pin | Forklaring |
---|---|---|---|
GND | 1 | 10 | Stel-forbindelse |
+ | 2 | 9 | + 5V forsyning |
SW | 3 | 5 | Kontakt i Rotary Encoder, der trækker mod stel, når den trykkes ind |
DT | 4 | 4 | Data signal - en del af rotations aftastning |
CLK | 5 | 3 | Clock signal - en del af rotations aftastning |
Princip-diagram for Rotary Encoder
Selve rotary encoderen er vist som de to switche U$1 og U$2, hvor der sidder to pull-up modstande R2 og R3 der er monteret på printet. Den sidste del er trykknappen S1, der sidder i drejeakslen, der kan aktiveres ved at trykke akslen indad. På printet er der plads til en pull up, men den er ikke monteret, så den kan man eftermontere (SMD), eller man kan placere den uden for printet. |
Forklaring til aflæsning af Rotary Encoder
Når man drejer på Rotary Encoderen, så giver den to faseforskudte signaler ud, som vist her:
Som det kan ses på tallene under kurverne, så tæller man et skridt hver gang der kommer en kant i signalerne fra enten CLK eller Data. Når Data er faseforskudt så den kommer efter CLK, så tælles der opad, og når faseforskydningen vender, så Data kommer før CLK, så tælles der nedad.
Mellem hvert "klik" på rotary encoderen tælles enten 4 gange op eller 4 gange ned.
Det kan man anvendelsesmæssigt håndtere ved at dividere tallet med 4.
Man kan også tælle lidt simplere, så man kun ændrer noget, hver gang CLK går fra lav til høj, som det er illustreret her:
Som det kan ses tælles der ved de positivt gående kanter på CLK, og der tælles op når Data er høj, og ned når Data er lav.
Dette princip virke umiddelbart enkelt, men det kan også have en ulempe, nemlig at der kan tælles forkert, hvis CLK giver flere positive kanter, men Data står på samme niveau, som det er illustreret her:
Software modulet Rotary.jal
Der ligger en servicerutine i Rotary modulet, hvor man kan få at vide om der er kommet en ny værdi, og den værdi kan aflæses i variablen Rotary_value, der er et signed word, som altså kan antage værdier fra -32768 til 32767.
Ved opstart står Rotary_value på 0.
Modulet kan anvende 4 forskellige principper.
Man kan vælge at arbejde med alle tælleskridt, så der kommer 80 på en omgang, men 4 trin for hvert "klik" på encoderen, eller man kan vælge at aflæse så der kommer 20 på en omgang, men med muligheden for at der opstår fejl.
Man kan også vælge om man vil servicere ved blot at kalde tit nok, eller om man vil lade en interrupt-rutine håndtere aflæsningen. Begge metoder kan kombineres frit uden begrænsninger.
Anvendelse af Rotary Encoder
Når man vil anvende Rotary Encoder modulet, så skal man include Rotary.jal som følger:
include Rotary.jal
Hvis Rotary.jal ligger i \lib inde i c:\jalpack så kan compileren finde modulet.
JAL-filen ligger sammen med et par eksempler inde i en samlet ZIP-fil
Rotary er testet på følgende kombinationer:
PIC | pin |
---|---|
PIC16F684 | CLK=a2 DT=a3 |
PIC16F690 | CLK=a2 DT=a3 - med alle kombinationer af interrupt og fuld/enkelt tælling |
Interface fil til Rotary Encoder
Man kan indstille de beskrevne ting i interfacefilen, samt man kan vælge hvilke indgange man ønsker at anvende til at aflæse encoderen med.
I Rotary_def.jal kan antallet af tælleskridt indstilles ved:
Const rotary_single = false
False giver 4 skridt pr. klik og true giver 1 skridt pr. klik (kan lave fejl).
I Rotary_def.jal kan der indstilles om man skal bruge interrupt ved:
Const rotary_interrupt = true
Placeringen af benene er lidt mere kompliceret, specielt på PIC16F690, hvor man både kan bruge ben i PORTA og PORTB til det - dog med den begrænsning at man skal bruge to ben i samme port.
Man angiver hvilken port det er med følgende angivelse:
alias Rotary_port is porta
Som normalt skal man angive hvilke pins det er ved navnene. Her skal navngives CLK og Data, samt direction-benene for de samme:
alias Rotary_pin_clk is pin_A2 -- clock pin
alias Rotary_pin_dt is pin_A3 -- data pin.
--
alias Rotary_pin_direction_clk is pin_A2_direction
alias Rotary_pin_direction_dt is pin_A3_direction
Til indstilling af interruptet skal man angive hvilke interrupt-indstillinger det er:
alias Rotary_int_clk is IOCA_IOCA2
alias Rotary_int_dt is IOCA_IOCA3
Endelig skal der kunne angives hvilke bit det er i de spejlede variabler inde i rutinerne, og det gøres blot ved at angive bit-nummeret som vist her:
const Rotary_clk_bit = 2
const Rotary_dt_bit = 3
Anvendelsen af Rotary Encoder
Man skal foretage valgene omkring interrupt ud fra om man lave sin kode så modulet serviceres meget ofte, og om man skal have visning på alle nye værdier, samt om man må miste værdier (om man har et fast nul-punkt).
Så skal man vælge om man vil have alle tælleskridt med, eller om man vil have 1 tælleskridt pr. klik, med den ulempe, at man kan få falske tællinger.
Ud over det er anvendelsen ret simpel:
include Rorary.jal
forever loop
if new_rotary_value then
rotary_value -- anvend den nye værdi til noget fornuftigt
end if
--
-- Her kan placeres anden kode i loopet, der skal lave andre ting
--
end loop
Forklaring af Rotary software
Her forklares i detaljer hvordan modulet fungerer inde i software-modulet
Initialisering af softwaren
Initialiseringen kan i Pseudokode udtrykkes som følger:
Læs opsætningen i Rotary_def.jal Sæt Rotary_value til 0 indstil interruptet, hvis det skal anvendes
Funktionen new_rotary_value
Funktionen kaldes ofte, og når der er en ny værdi, så returnerer den true, og man kan aflæse status på tælleren i rotary_value.
Hvis man ikke anvender interrupt, så skal funktionen kaldes så ofte, at man ikke mister tælleskridt. Anvender man interruptet, så vil der blot ligge den værdi man er kommet til.
Konstanterne i interface-filen
Det er mest af alt de indstillinger der er beskrevet tidligere.
Funktionsbeskrivelse
Princippet for at registrere tælling af enkelt skridt kan i pseudokode udtrykkes som følger:
Hvis der er en forkant på CLK så Marker at der er sket en ændring Hvis Data er høj så Tæl en op ellers Tæl en ned
Dette kan ske direkte i servicerutinen, eller hvis det er med interrupt, så sker det ved at registreringen sker i interruptet, og servicerutinen registrerer at det er sket.
På samme måde laves tællingen på alle kanter enten i interruptet eller i servicerutinen.
Som pseudokode er det lidt mere kompliceret:
Hvis der er sket et skift på CLK så Marker at der er sket en ændring Hvis CLK er Høj så Hvis Data er høj så Tæl en op Ellers Tæl en ned Ellers Hvis Data er høj så Tæl en ned Ellers Tæl en op Ellers Hvis der er sket et skift på Data så Marker at der er sket en ændring Hvis Data er Høj så Hvis CLK er høj så Tæl en ned Ellers Tæl en op Ellers Hvis CLK er høj så Tæl en op Ellers Tæl en ned
Koden inde i funktionerne
Koden er ret uoverskuelig, specielt fordi den skal kunne fungere på 4 forskellige måder, ud fra de indstillinger der er lavet i interface-filen.
Det er også således at noget løses i interrupt, mens andet løses i servicerutinen.
Koden ligger sammen med eksempler og en demo inde i en samlet ZIP-fil.
Moduler på Holstebro HTX | |||||||
---|---|---|---|---|---|---|---|
Tastaturer | Displays | AD-konvertering | I/O-ekspander | Serielt | Interface | Færdige | Andre |
RC-tast - AD-tast - M_tast | ALCD - LCD | ADC_holst - ADC mcp3201 - mcp3208 |
input - output | Seriel_holst - Serial hardware Serial hw int cts - Serial software |
Stepmotor - RFID RGB - RF-link - Afstand |
Humidity - Analog temp - Dig temp Accelerometer |
Rotary Encoder |
Oversigt over Hardware Moduler på Holstebro HTX