Objectives :

  1. To familiar with rotary encoder operating condition.
  2. To acquire data from rotary encoder and display it on LCD.


  1. PIC 18F4550 microcontroller board with pre-programmed Pinguino bootloader version 4.x.
  2. USB cable.
  3. 16×02 character LCD.
  4. 8 jumper wires.
  5. 10K ohms variable resistor.
  6. 2 10K ohms resistors.
  7. 470 ohms resistor.
  8. Rotary encoder.


  1. Lab 2 experiment must be done.

Rotary Encoder:

  • Rotary encoder is an electro-mechanical device that converts angular position to digital code.¹
  • It is now commonly seen in device control panel and used as control scale knob, sound volume knob, or any related to adjustable parameter knob.

  • Rotary encoder sends two signals to microcontroller named EncA and EncB.
  • To accurately catch the toggling signals we use “Interrupt” function in microcontroller. “Interrupt” routine is priority routine and programming within interrupt routine must be executed first whenever it detects interrupt event happen.
  • In this case we can let the interrupt detects on falling edge of EncA and EncB.
  • When falling edge detected for EncA, it quickly read the state of EncB (yellow dot line), and read the state of EncA when falling edge of EncB happen(red dot line).
  • Clockwise direction : ↓EncA : EncB => LOW ; ↓EncB : EncA => HIGH;
  • Anti-clockwise direction : ↓EncA : EncB => HIGH ; ↓EncB : EncA => LOW;


  • Connect LCD and rotary encoder hardware as schematic below:


  • Please take note about the pins mapping due to we move LCD pins 0-5 in Lab 2 to pins 2-7 because we need use Pin0 and Pin1 as interrupt pins for rotary encoder.
  • Open Pinguino IDE.
  • From the “HelloWorld.pde” from Lab 2, save a new copy at other directory, rename it as “RotaryEncoderDisplay.pde“.
  • Modify the programming as below:
//Pins for Rotary Encoder
const int encA = 0;

const int encB = 1;

//Universal variables for experiment

float cnt;

float cnt_percentage;

static u8 temp ;

int encB_state = 0;

u8 chk1_state = 0;

//Function for when Pin0 interrupts happen

void enc_chk1(){

if (digitalRead(encB) == HIGH){

chk1_state = 0;



chk1_state = 1;



//Function for when Pin1 interrupts happen

void enc_chk2(){

if (digitalRead(encA) == LOW && chk1_state == 1){

if(cnt != 255){





if(cnt !=0){




//Take 255 as maximum value for this experiment and

//calculate the percentage based on recent count number from encoder.

cnt_percentage = (cnt/255)*100;


void setup()


lcd.pins(2,3, 4, 5, 6, 7, 0, 0, 0, 0); // RS, E, D4 ~ D8

lcd.begin(16, 2);


lcd.print( Audio Volume:);

//Enable Pin0 and Pin1 as interrupt pins.

OnChangePin0(enc_chk1, INT_FALLING_EDGE);

OnChangePin1(enc_chk2, INT_FALLING_EDGE);


void loop()


//User defined function.




lcd.print("Audio Volume:");

lcd.setCursor(0, 1);

lcd.printf(" %f %%", cnt_percentage);

  • Check the video below to see the output.



[1] https://en.wikipedia.org/wiki/Rotary_encoder