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 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_encoder
While 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 0
The file re.vcd will contain the captured waveform, which can be viewed using GTKWave.