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.