baileychic
Advanced Member level 3
How to read incremental rotary (quadrature) encoder?
The rotary encoder has two connections for signals namely A and B.
I have to use 3 pins of microcontroller (PIC16F) to read it.
I have used PIC16F877A and connections are also below.
A -> RB1
B -> RB2
A xor B (using xor gate) -> RB0/INT
I need to use external interrupt to detect change in rotary encoder state and increment or decrement a counter.
This is the code that I have written but the counter is always 0.
Schematic
The rotary encoder has two connections for signals namely A and B.
I have to use 3 pins of microcontroller (PIC16F) to read it.
I have used PIC16F877A and connections are also below.
A -> RB1
B -> RB2
A xor B (using xor gate) -> RB0/INT
I need to use external interrupt to detect change in rotary encoder state and increment or decrement a counter.
This is the code that I have written but the counter is always 0.
Code C - [expand] 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 // LCD module connections sbit LCD_RS at RD4_bit; sbit LCD_EN at RD5_bit; sbit LCD_D4 at RD0_bit; sbit LCD_D5 at RD1_bit; sbit LCD_D6 at RD2_bit; sbit LCD_D7 at RD3_bit; sbit LCD_RS_Direction at TRISD4_bit; sbit LCD_EN_Direction at TRISD5_bit; sbit LCD_D4_Direction at TRISD0_bit; sbit LCD_D5_Direction at TRISD1_bit; sbit LCD_D6_Direction at TRISD2_bit; sbit LCD_D7_Direction at TRISD3_bit; // End LCD module connections sbit EncoderA_bit at RB1_bit; sbit EncoderB_bit at RB2_bit; sbit EncoderINT_bit at RB0_bit; signed char counter = 0; char msg[17]; char txt1[] = " ROTARY ENCODER "; char txt2[] = "COUNT: "; void interrupt() { if((INTE_bit) && (INTF_bit)) { INTF_bit = 0; //counter++; if((EncoderA_bit != RB1_bit)||(EncoderB_bit != RB2_bit)){ if(EncoderB_bit ^ RB1_bit){ counter++; } if(EncoderA_bit ^ RB2_bit){ counter--; } EncoderA_bit = RB1_bit; EncoderB_bit = RB2_bit; } } } void main() { TRISB = 0x07; TRISD = 0x00; PORTB = 0x00; PORTD = 0x00; Lcd_Init(); Lcd_Cmd(_LCD_CURSOR_OFF); Lcd_Cmd(_LCD_CLEAR); Lcd_Out(1,1,txt1); Lcd_Out(2,1,txt2); Delay_ms(100); INTEDG_bit = 0; INTF_bit = 0; INTE_bit = 1; PEIE_bit = 1; GIE_bit = 1; while(1) { ByteToStr(counter,msg); strcat(msg," "); Lcd_Out(2,7,msg); } }
Schematic