The following code shows one way to read an incremental mechanical rotary enoder (the sort used for volume control in audio systems). These rotary encoders have two switches A and B which return a quadrature output, i.e. they are 90 degrees out of phase.
 The common
(centre) terminal should be connected to a Pi ground.
The common
(centre) terminal should be connected to a Pi ground.
The A and B terminals may be connected to any spare gpios.
Here A to gpio18 (P1-12), common to ground (P1-20), B to gpio7
(P1-26).

#include <stdio.h>
#include <pigpio.h>
/*
   Rotary encoder connections:
   Encoder A      - gpio
18   (pin P1-12)
   Encoder B      - gpio
7    (pin P1-26)
   Encoder Common - Pi ground (pin P1-20)
*/
#define ENCODER_A 18
#define ENCODER_B  7
static volatile int encoderPos;
/* forward declaration */
void encoderPulse(int gpio, int lev, uint32_t tick);
int main(int argc, char * argv[])
{
   int pos=0;
   if (gpioInitialise()<0) return 1;
   gpioSetMode(ENCODER_A, PI_INPUT);
   gpioSetMode(ENCODER_B, PI_INPUT);
   /* pull up is needed as encoder common is grounded
*/
   gpioSetPullUpDown(ENCODER_A, PI_PUD_UP);
   gpioSetPullUpDown(ENCODER_B, PI_PUD_UP);
   encoderPos = pos;
   /* monitor encoder level changes */
   gpioSetAlertFunc(ENCODER_A, encoderPulse);
   gpioSetAlertFunc(ENCODER_B, encoderPulse);
   while (1)
   {
      if (pos != encoderPos)
      {
         pos =
encoderPos;
         printf("pos=%d\ ",
pos);
      }
      gpioDelay(20000); /* check pos 50
times per second */
   }
   gpioTerminate();
}
void encoderPulse(int gpio, int level, uint32_t tick)
{
   /*
            
+---------+        
+---------+      0
            
|        
|        
|         |
   A        
|        
|        
|         |
            
|        
|        
|         |
  
+---------+        
+---------+         +-----
1
      
+---------+        
+---------+           
0
      
|        
|        
|         |
   B  
|        
|        
|         |
      
|        
|        
|         |
   ----+        
+---------+        
+---------+  1
   */
   static int levA=0, levB=0, lastGpio = -1;
   if (gpio == ENCODER_A) levA = level; else levB =
level;
   if (gpio != lastGpio) /* debounce */
   {
      lastGpio = gpio;
      if ((gpio == ENCODER_A) &&
(level == 0))
      {
         if (!levB)
++encoderPos;
      }
      else if ((gpio == ENCODER_B)
&& (level == 1))
      {
         if (levA)
--encoderPos;
      }
   }
}
cc -o rotary_encoder rotary_encoder.c -lpigpio -lrt
-lpthread
sudo ./rotary_encoderWhile the program is running you can capture the waveform using the notification feature built in to pigpio. Issue the following commands on the Pi.
pigs no
pig2vcd  </dev/pigpio0 >re.vcd &
pigs nb 0 0x40080 # set bits for gpios 7 (0x80) and 18
(0x40000)
Twiddle the rotary encoder forwards and backwards for a few
seconds.  Then enter
pigs nc 0The file re.vcd will contain the captured waveform, which can be viewed using GTKWave.

