Rotary Encoder


Een Rotary Encoder zoals op het plaatje hiernaast is in wezen een twee deks draai schakelaar.
Het tweede dek schakelcontacten is iets verschoven ten opzichte van de eerste zo dat contacten van beide lagen elkaar overlappen. Zie de tekening onder. Met noemt dit type Quadrature of Incremental Encoders.


Dit type Rotary Encoders wordt meestal ingezet als digitale potmeter (volume regeling, scroll muis, etc..). De meest gangbare types hebben 12, 15, 24 of 30 stappen per omwenteling, de stappen worden meestal aangegeven met een mechanisch klik moment. Het type wat hier behandeld wordt heeft 1 klik per volle puls. (Er bestaan ook types met 2 klikken per puls)
In de meeste schakelingen op Knutselaar.eu wordt schakelaar A aangesloten op een Microcontroller ingang met flankgevoelige interrupt mogelijkheid, schakelaar B gaat naar gewone ingang.
Verder is het belangrijk voor een goede werking, om ingangen van het type Schmitt Trigger te gebruiken (werkt beter als TTL), poort B1 en C2 zijn voor de 18F25K22 Schmitt Trigger (ST) ingangen.
Bij bijvoorbeeld de 16F1829 moet men hier de poorten op instellen (INLVLx register (INput LeVeL)).
Wanneer nu aan de Rotery Encoder gedraaid wordt zal op contact A op een bepaald moment een neergaande flank langskomen (de interrupt ingang van de Microcontroller is ingesteld op het detecteren van de neergaande flank). Door op dat moment te kijken wat B is, kan men de draai richting vaststellen (zie bovenstaande tekening). De Rotary Encoders hebben geen begin of eindstand. Het aantal pulsen dat geteld wordt, wordt bepaald door software (firmware).

Rotary Encoder bestellen

Hieronder een voorbeeld code (Proton Basic/Amicus18) hoe een en ander gerealiseerd kan worden.

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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
'****************************************************************
'*  Name    : Rotary Encoder Test                               *
'*  Author  : Knutselaar.eu                                     *
'*  Notice  : Copyright (c) 2013 Knutselaar.eu                  *
'*          : All Rights Reserved                               *
'*                                                              *
'*  Version : 1.0  05-Sep-2013                                  *
'*  Version : 2.0  13-Sep-2013                                  *
'*            Mode selectie d.m.v. druk schakelfunctie van      *
'*            Rotary Encoder toegevoegd.                        *
'****************************************************************
Device 18F25K22
   
    CONFIG_START    
     FOSC = INTIO67              ;interne oscillator A6, A7 poortfuntie
     FCMEN = OFF                 ;Fail-Safe Clock Monitor disabled
     IESO = OFF                      ;internal external switchover mode
     PWRTEN = On                 ;power-up timer  (18F25K22)
     BOREN = On                      ;brown-out reset
     BORV = 285                      ;brown-out reset value (2,85V) (18F25K22)
     WDTEN = OFF                 ;watchdog timer
     WDTPS = 128                 ;1:128 WDT prescalar
     PBADEN = OFF                ;analog port B<4:0>
     STVREN = On                 ;;stack overflow reset
     LVP = OFF                       ;low voltage programming
     XINST = OFF                 ;Instruction set extension and Indexed Addressing mode disabled (Legacy mode)
     Debug = OFF                 ;no debug
CONFIG_END
 
XTAL = 16
              '76543210
    OSCCON =  %01111100   ' 16 mhz,int osc
   
    ANSELA = 0          'all digital A true
    ANSELB = 0          'all digital B true
    ANSELC = 0          'all digital C true
       
    Dim test        As Byte
    Dim change      As Byte
    Dim loopCounter As Byte
    Dim modeTimer   As Byte
    Dim mode        As Byte
    Dim waarde      As sByte  'signed bytes om ook met negatieve getallen te kunnen werken.
    Dim waardeMode1 As sByte
    Dim waardeMode2 As sByte  
    Dim waardeMode3 As sByte
    Dim waardeMode4 As sByte
   
    Symbol RotaryA  = PORTB.1
    Symbol RotaryB  = PORTC.2
    Symbol RotarySw = PORTA.4  'Rotary Encoder druk schakelaar.
    Symbol Speaker  = PORTC.0  'Buzzer
    Symbol LED      =  LATA.5

    Declare LCD_DATAUS 75     ;LCD timing voor wat oudere 16x2 44780 compatible displays (default = 50)

    Symbol IPEN    =   RCON.7       ' IPEN : Disable Interrupt PRIORITY HANDLING
    Symbol GIE     = INTCON.7       ' GIE  : enable interrupts
   
    Symbol INT1IE  = INTCON3.3      ' PORTB.1 (INT1) interrupt enable bit
    Symbol INTEDG1 = INTCON2.5      ' Op (1) of neergaande (0) flank PORTB.1 interrupt select
    Symbol INT1IF  = INTCON3.0      ' PORTB.1 (INT1) interrupt flag
   
    INTEDG1 = 0  ' INT1 interrupt op neergaande flank
    IPEN = 0     ' Interrupt priority uitzetten (PIC16F compatability mode)    
   
    test = PORTB 'Read PORTB (nodig om actuele status te verkrijgen, zie datasheet)
   
    INT1IE = 1   ' PORTB.1 interrupts aanzetten
    INT1IF = 0   ' Clear the PORTB.1 Interrupt FLAG
   
    GIE  = 1     ' Interrupts activeren
   

   
    ON_HARDWARE_INTERRUPT  GoTo ENCODER_INTERRUPT_HANDLER ' Waar heen te gaan bij interrupt.
   
    Clear
   
    Cls
   
    Print At 1,1, "knutselaar.eu"      ' Standaard 2x16 44780 compatible display (zie schema)
   
    mode = 1
    change = 1
   
    GoTo main_loop  
   

ENCODER_INTERRUPT_HANDLER:              'Verandering van PORTB.1 gedetecteerd

Context SAVE      ' Start interrupt (opslaan van het punt waar interrupt plaatsvond)

    DelayUS 500                                   'contact dender filter
    If RotaryA = 0 And RotaryB = 0 Then           'RoteryA = 0 houdt in; de neergaande flank
        If waarde < 99 Then waarde = waarde + 1   'grenswaarde 99 kan tot max 127 verschoven worden (sbyte)
        change = 1
    End If
    If RotaryA = 0 And RotaryB = 1 Then
        If waarde > -99 Then waarde = waarde - 1
        change = 1
    End If
   
    INT1IF = 0      'Clear the PORTB.1 Interrupt FLAG

Context Restore  ' Eind interrupt (teruggaan naar het punt waar Interrupt plaatsvond)
     
main_loop:

    Toggle LED
   
    DelayMS 100
        If RotarySw = 0 Then         'rotary encoder ingedrukt.  
        Sound  Speaker, [115,20]
        For loopCounter = 0 To 20
            DelayMS 25
            If RotarySw = 1 Then     'rotary encoder losgelaten
                GoTo changeMode1        
            End If
        Next loopCounter    
        Sound  Speaker, [95,50]       'rotary encoder nog steeds (lang) ingedrukt.        
        GoTo changeMode2            
    End If
   
    If modeTimer < 253 Then           'Timer voor automatisch terug gaan naar mode1.
        modeTimer = modeTimer + 1
    Else
        If mode > 1 Then
            mode = 1
            waarde = waardeMode1
            change = 1
        End If
    End If
   
    If change = 1 Then GoSub updateDisplay
   
    GoTo main_loop
   
changeMode1:

    modeTimer = 0
    mode = mode + 1
    If mode = 5 Then mode = 1
    Select mode
        Case 1
            waarde = waardeMode1
        Case 2
            waarde = waardeMode2
        Case 3
            waarde = waardeMode3
        Case 4
            waarde = waardeMode4      
    End Select
   
    GoSub updateDisplay

    GoTo main_loop
   
changeMode2:

    DelayMS 500
    ' Hier kan nog code toegevoegd worden voor extra mogelijkheden
    ' als de Rotary Encoder langer ingedrukt blijft.

    GoTo main_loop
   
updateDisplay:

    change = 0
    Select mode
        Case 1
            waardeMode1 = waarde
            Print At 2,1, "Mode 1: ", SDEC2 waardeMode1, "        "     'SDEC laat ook negatieve getallen zien.
        Case 2
            waardeMode2 = waarde
            Print At 2,1, "Mode 2: ", SDEC2 waardeMode2, "        "
        Case 3
            waardeMode3 = waarde
            Print At 2,1, "Mode 3: ", SDEC2 waardeMode3, "        "
        Case 4
            waardeMode4 = waarde
            Print At 2,1, "Mode 4: ", SDEC2 waardeMode4, "        "                  
    End Select

Return
   
    End

De code is gemaakt voor onderstaand schema.
Het schema is gebaseerd op het 28PIC moederbordje (connectoren) maar kan natuurlijk ook direct op breadboard opgebouwd worden.


























Opmerking: De door Knutselaar.eu verkochte Rotary Encoder is NIET geschikt om direct in een breadboard te prikken, soldeer de Rotary Encoder hiervoor eerst op gedraaide Pinheaders.




Hit Counter by Digits
  Sinds 05 September 2013