Rotary Encoder

Fra HTX Arduino
Spring til navigation Spring til søgning
Billede af Rotary Encoder modul

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.

Principskitse af Rotary Encoder

Forklaring til aflæsning af Rotary Encoder

Når man drejer på Rotary Encoderen, så giver den to faseforskudte signaler ud, som vist her:

Tidsdiagram for Rotary Encoder med tælleskridt

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:

Tidsdiagram for Rotary Encoder med enkelt tælling

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:

Tidsdiagram for Rotary Encoder med fejltælling

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

Keyes-moduler på Holstebro HTX
Simple Digitale Input Switch modul - Reedrør - Hall sensor - Optisk Skift - Photo Gate - Vibration sensor - Vibration switch - Tilt sensor - Kviksølv kontakt - Linje følger
Digitalt kodede Input IR Modtager - Humidity -Digital Temperatur
5 benede Input Rotary Encoder -XY Joystick
Digitale 4 benede Input Magic Cup Light - LED 3-farve - RGB - RF-link - Afstand
Justerbare analoge/digitale Input Reed Magnetsensor - Temperatur Niveau - Metal detektor - Flamme - Hall Kontakt - Almindelig Mikrofon - Følsom Mikrofon
Simple digitale Output LED 2-farve - Aktiv Buzzer - Blink LED - IR LED - Laser - Relæ modul - Passiv Buzzer
Analoge input Analog Temperatur - LDR - Finger Pulsmåler - Lineær Magnetfelt