Wat is een rotary encoder?
Een draaiknopje, waarbij 2 signalen, A en B, worden uitgestuurt als er aan het knopje wordt gedraaid. Dit werd bijvoorbeeld vroeger gebruikt in balletjesmuizen, om de beweging van de muis op te nemen, tegenwoordig vind je het vaak terug voor (digitale) volumeregeling op stereo's, en ook worden rotary encoders vaak gebruikt in robot's en dergerlijke, om draaisnelheid en richting in de gaten te houden.
Wat zijn die signalen dan, hoe weet je of ie voor of achteruit draait?
De signalen worden bij de simpele rotary encoders gegenereerd door een gemeenschappelijke pen C (die je aan de massa hangt) te verbinden (er zitten 2 schakelaartjes in) met 2 uitgangssignalen (die van een pull-up weerstand van ongeveer 5 à 10 KOhm voorzien zijn). Daardoor krijg je op A en B 2 signalen, die 90° in fase verschoven zijn. De aansluiting gebeurt dus door pen C aan de massa te hangen, en pen A en B via een weerstand naar de voedingsspanning die je gebruikt te verbinden. De signalen lees je dan af aan pen A en B.
Duurdere encoders zijn optisch, en werken zoals in een balletjesmuis (schijf met gaatje's, ledje aan ene kant en fototransistor aan de andere kant), bij deze heb je geen last van dender (zie verder beneden).
Er zijn 2 type's van rotary encoders, de ene zullen in 'idle' toestand (als je niet aan het draaien bent, met grijze streep aangeduid op onderstaande figuur) altijd geen verbinding geven (dus een '1'), de andere zijn bij 'idle' toestand beide signalen A en B op '1' of op '0' hebben (de onderste van de 2 op onderstaande figuur). Kijk dus even na in de datasheet hoe jou rotary encoder werkt.

Hoe uitlezen?
Heel simpel, gebruik een microcontroller, of een specifiek IC. Met een specifiek IC hang je gewoon A en B aan het IC, en je krijgt de pulsjes en een signaal dat de draairichting aangeeft, zie hiervoor de datasheet.
Met een microcontroller kan je het best interrupts gebruiken. Een van de signalen (neem A uit de tekening) hang je aan een ingangspin die interrupts kan genereren bij verandering (interrupt on change), het ander signaal (
hang je aan een gewone ingangspin. Als je een interrupt krijgt, controleer je of A en B gelijk zijn, zo ja draai je naar rechts toe in de tekening (A verandert, daarna zijn ze gelijk), als ze verschillen draai je naar links toe.
Ik wil een voorbeeldje
Onderstaand voorbeeld is voor PIC's, type maakt niet uit (interrupt on change moet aanwezig zijn op RB4), deze is geschreven in mikroBasic, en toont de waarde op een LCD scherm. Als je met microcontrollers bezig bent, zou je moeten in staat zijn het onderliggende ID te snappen (belangerijkste is de interrupt procerdure):
(let niet op "visual basic" hieronder, is enkel om de code gekleurd te krijgen)
Wat zijn mogelijke problemen?
Maximaal toerental? Zonder de delay_ms(5) is de interrupt routine 44 instuctie's lang. Bij een kloksnelheid van 8MHz, bij PIC's delen door 4 voor de werkklok, duurt 1 instructie 0,5µs. Een interrupt duurt dus 22µs, de rest van je code moet ook nog draaien, dus mag de interrupt maar (als voorbeeld) de helft van de processortijd innemen, dus maximaal elke 44µs de interrupt. Dan mogen we maar 22727 interrupts per seconde hebben, bij een rot.enc. die per toer 30 pulsen geeft komen we op een maximaal toerental van 757 toeren per seconde.
Ontdendering Alle mechanische contacten (zoals in de simpele rotary encoders, duurdere optische modellen hebben dit niet) hebben last van dender. Als je een mechanisch contact sluit, zal er niet meteen perfecte elektrische verbinding zijn, er zal enkele keren wel/niet contact zijn tot hij stabiel op zijn instelling is, dat noemt men dender. Ook rotary encoders hebben dit, maar wel in beperkte mate (degene die bedoeld zijn om als knopje te dienen, hebben er last van, die om toerentallen op te pikken hebben nauwelijks/geen merkbare dender), in de datasheet staat meestal vermeld hoelang er dender is, en eventueel hoe je deze aanpakt.
Oplossing voor dender? Er zijn 2 mogelijke oplossingen, hardwarematig en softwarematig. Hardwarematig worden er gewoon enkele componentjes toegevoegd om de dender weg te werken. Het eenvoudigste is een RC filtertje, deze vertraagt de signalen in zoverre dat de snelle veranderingen tijdens het denderen volledig afgevlakt worden, google helpt je aan alle mogelijke verdere uitleg. Softwarematig zijn er ook een paar mogelijkheden, de eenvoudigste is het om gewoon een delay toe te voegen nadat je gedetecteerd hebt dat er een contact veranderd is. In de datasheet van een bepaalde rotary encoder staat dat deze maximaal 2ms dender geeft, door na elke overgang 3ms te wachten voor je de volgende begint te detecteren, voorkom je dat je de dender oppikt.
Aangezien men in het robot bouwen voor bewonderaars (beginners)-topic wat vraag naar rotary encoders heeft, heb ik even een voorstelletje gemaakt voor een HowTo.
Graag uw commentaren hieromtrent, is het niveau te eenvoudig (of te moeilijk), ontbreken er essentiële delen (of zijn er nog zaken die erbij horen), wat vinden jullie van het concept?
Een draaiknopje, waarbij 2 signalen, A en B, worden uitgestuurt als er aan het knopje wordt gedraaid. Dit werd bijvoorbeeld vroeger gebruikt in balletjesmuizen, om de beweging van de muis op te nemen, tegenwoordig vind je het vaak terug voor (digitale) volumeregeling op stereo's, en ook worden rotary encoders vaak gebruikt in robot's en dergerlijke, om draaisnelheid en richting in de gaten te houden.
Wat zijn die signalen dan, hoe weet je of ie voor of achteruit draait?
De signalen worden bij de simpele rotary encoders gegenereerd door een gemeenschappelijke pen C (die je aan de massa hangt) te verbinden (er zitten 2 schakelaartjes in) met 2 uitgangssignalen (die van een pull-up weerstand van ongeveer 5 à 10 KOhm voorzien zijn). Daardoor krijg je op A en B 2 signalen, die 90° in fase verschoven zijn. De aansluiting gebeurt dus door pen C aan de massa te hangen, en pen A en B via een weerstand naar de voedingsspanning die je gebruikt te verbinden. De signalen lees je dan af aan pen A en B.
Duurdere encoders zijn optisch, en werken zoals in een balletjesmuis (schijf met gaatje's, ledje aan ene kant en fototransistor aan de andere kant), bij deze heb je geen last van dender (zie verder beneden).
Er zijn 2 type's van rotary encoders, de ene zullen in 'idle' toestand (als je niet aan het draaien bent, met grijze streep aangeduid op onderstaande figuur) altijd geen verbinding geven (dus een '1'), de andere zijn bij 'idle' toestand beide signalen A en B op '1' of op '0' hebben (de onderste van de 2 op onderstaande figuur). Kijk dus even na in de datasheet hoe jou rotary encoder werkt.

Hoe uitlezen?
Heel simpel, gebruik een microcontroller, of een specifiek IC. Met een specifiek IC hang je gewoon A en B aan het IC, en je krijgt de pulsjes en een signaal dat de draairichting aangeeft, zie hiervoor de datasheet.
Met een microcontroller kan je het best interrupts gebruiken. Een van de signalen (neem A uit de tekening) hang je aan een ingangspin die interrupts kan genereren bij verandering (interrupt on change), het ander signaal (
Ik wil een voorbeeldje
Onderstaand voorbeeld is voor PIC's, type maakt niet uit (interrupt on change moet aanwezig zijn op RB4), deze is geschreven in mikroBasic, en toont de waarde op een LCD scherm. Als je met microcontrollers bezig bent, zou je moeten in staat zijn het onderliggende ID te snappen (belangerijkste is de interrupt procerdure):
(let niet op "visual basic" hieronder, is enkel om de code gekleurd te krijgen)
Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
| '* ' * Project name: Rotary encoder ' * Description: Rotary encoder decoderen met interupts ' * Test configuration: ' MCU: PIC16F877A ' Oscillator: HS, 8.000 MHz ' Aansluiting: A naar RB4, B naar RB1 ' SW: mikroBasic v5.0 or higher ' * NOTES: ' LCD op PORTD ' * program Rotary_encoder dim temp as byte dim txt as string[3] sub procedure interrupt ' Interrupt service routine If PORTB.4 = 1 then 'als je rot. enc. idle beide verbonden of beide niet verbonden heeft, 'moet je deze 4 regels gebruiken. ' If PORTB.1 = 1 then ' temp = temp + 1 ' A en B zijn gelijk ' else ' temp = temp - 1 ' A en B zijn niet gelijk ' end if else If PORTB.1 = 1 then temp = temp - 1 ' A en B zijn niet gelijk else temp = temp + 1 ' A en B zijn gelijk end if end if delay_ms(5) 'enkel nodig bij mechanische rot.enc., ontdendering INTCON.RBIF = 0 ' interrupt flag clearen end sub main: LCD_init(PORTD) 'LCD scherm inschakelen TRISB = %11111111 'PORTB.1 and .4 are inputs INTCON = %10001000 ' Enable interrupt on change while 1=1 'endless loop delay_ms(100) bytetostr(temp,txt) 'omzetten van getalletje om op LCD te zetten LCD_out(1,1,txt) wend end. |
Wat zijn mogelijke problemen?
Maximaal toerental? Zonder de delay_ms(5) is de interrupt routine 44 instuctie's lang. Bij een kloksnelheid van 8MHz, bij PIC's delen door 4 voor de werkklok, duurt 1 instructie 0,5µs. Een interrupt duurt dus 22µs, de rest van je code moet ook nog draaien, dus mag de interrupt maar (als voorbeeld) de helft van de processortijd innemen, dus maximaal elke 44µs de interrupt. Dan mogen we maar 22727 interrupts per seconde hebben, bij een rot.enc. die per toer 30 pulsen geeft komen we op een maximaal toerental van 757 toeren per seconde.
Ontdendering Alle mechanische contacten (zoals in de simpele rotary encoders, duurdere optische modellen hebben dit niet) hebben last van dender. Als je een mechanisch contact sluit, zal er niet meteen perfecte elektrische verbinding zijn, er zal enkele keren wel/niet contact zijn tot hij stabiel op zijn instelling is, dat noemt men dender. Ook rotary encoders hebben dit, maar wel in beperkte mate (degene die bedoeld zijn om als knopje te dienen, hebben er last van, die om toerentallen op te pikken hebben nauwelijks/geen merkbare dender), in de datasheet staat meestal vermeld hoelang er dender is, en eventueel hoe je deze aanpakt.
Oplossing voor dender? Er zijn 2 mogelijke oplossingen, hardwarematig en softwarematig. Hardwarematig worden er gewoon enkele componentjes toegevoegd om de dender weg te werken. Het eenvoudigste is een RC filtertje, deze vertraagt de signalen in zoverre dat de snelle veranderingen tijdens het denderen volledig afgevlakt worden, google helpt je aan alle mogelijke verdere uitleg. Softwarematig zijn er ook een paar mogelijkheden, de eenvoudigste is het om gewoon een delay toe te voegen nadat je gedetecteerd hebt dat er een contact veranderd is. In de datasheet van een bepaalde rotary encoder staat dat deze maximaal 2ms dender geeft, door na elke overgang 3ms te wachten voor je de volgende begint te detecteren, voorkom je dat je de dender oppikt.
Aangezien men in het robot bouwen voor bewonderaars (beginners)-topic wat vraag naar rotary encoders heeft, heb ik even een voorstelletje gemaakt voor een HowTo.
Graag uw commentaren hieromtrent, is het niveau te eenvoudig (of te moeilijk), ontbreken er essentiële delen (of zijn er nog zaken die erbij horen), wat vinden jullie van het concept?
[ Voor 23% gewijzigd door naftebakje op 16-10-2006 23:01 ]
Als de boer zijn koeien kust, zijn ze jarig wees gerust. Varkens op een landingsbaan, leiden nooit een lang bestaan. Als de boer zich met stront wast, zijn zijn hersens aangetast. Als het hooi is in de schuur, zit het wijf bij den gebuur.