Reading a Rotary Encoder from a Raspberry Pi


I wanted to attach a knob to my Raspberry Pi to act as a vol­ume con­trol for my MPD based jukebox. Tra­di­tion­ally vol­ume con­trol devices are imple­mented with poten­tiome­ters act­ing as inputs for ampli­fiers. A poten­tiome­ter is a hard­ware device with a knob or a slider that, in a word allows for a vari­able volt­age input into a cir­cuit. 1 The prob­lem here is that this is a very hard­ware ori­ented method of set­ting vol­ume, when what I really wanted to do was set the software vol­ume set­ting on the Rasp­berry Pi.Reading a Rotary Encoder from a Raspberry Pi I wanted to be able to change the vol­ume from the oper­at­ing sys­tem (a la alsamix­er) or through the MPD client, and still be able change it up or down by phys­i­cally turn­ing the knob on the device. Essen­tial­ly, I wanted the ALSA PCM ele­ment vol­ume to increase as I turned the knob clock­wise, and decrease as I turned the knob coun­ter­clock­wise, I wanted to actual vol­ume to be inde­pen­dent of the posi­tion of the knob and because a poten­tiome­ter is an absolute input device which returns it’s posi­tion and can­not be turned indef­i­nitely there was no way to make one work for what I needed.

What I needed was a rotary encoder. A rotary encoder, is in essence a pair of switches which change as a shaft is turned, and by read­ing those switch­es, one can tell whether and in which direc­tion the shaft is turn­ing. A rotary encoder can­not tell absolute posi­tion, but it does­n’t need to, plus it can spin infinitely.2 This, of course, was exactly what I need­ed. Unfor­tu­nately there isn’t a lot of infor­ma­tion on get­ting a rotary encoder work­ing with a Rasp­berry Pi.

I did some research and found a number of articles about get­ting a rotary encoder to work with an Arduino. This code could be adapted to the Rasp­berry Pi, but it’s impor­tant to note that an Arduino has a real-­time oper­at­ing sys­tem (that is, it has almost no oper­at­ing sys­tem) so pro­grams can exe­cute with­out the unpre­dictable delays of time-shar­ing/­mul­ti­task­ing, buffer­ing, or garbage col­lec­tion. The Rasp­berry Pi is a Linux machine, which is a time-shar­ing sys­tem, so it can’t make guar­an­tees to the mil­lisec­ond about per­for­mance the same way an Arduino can. This can be a prob­lem because to prop­erly read a rotary encoder, a pro­gram needs to track every change of the switch­es, else one could get back­ward or con­fused read­ings.

For­tu­nately this is a solv­able prob­lem. The Rasp­berry Pi has inter­rupts, which allows us to trig­ger func­tions upon switch read­ing changes, and the wiringPi library makes it easy to use them. So, here’s what I ulti­mately did:

Con­nect­ing a rotary encoder could­n’t be much sim­pler. Rotary encoders only have three pins.3 The mid­dle pin is ground and the oth­ers are con­nected to the switches and pro­duce the A sig­nal and B sig­nal respec­tive­ly. You can con­nect these pins to the Rasp­berry Pi direct­ly. Rotary Encoder pins:

And how to con­nect it to the Rasp­berry Pi:

Using the built in pul­l-up resis­tors on the Rasp­berry Pi for the pins con­nected to A and B means that when the respec­tive switches are closed, the pins will read low (0) and when the switches are open, the same pins will read high (1). There’s no need for any addi­tional resis­tors or capac­i­tors. As the encoder shaft is turned, the switches will alter­na­tively open and close so that they progress through a series of states known as Gray Code. These states are as follows:Reading a Rotary Encoder from a Raspberry Pi schematich

00, 01, 11, 10

By read­ing any two suc­ces­sive states, one can tell which direc­tion the encoder is turn­ing. 00->01 might be clock­wise while 00->10 might be coun­ter-­clock­wise. Using inter­rupts, we can get the Pi to record each change of a pin and to record the direc­tion the encoder is turn­ing.

 

 

 

For more detail: Reading a Rotary Encoder from a Raspberry Pi




© 2015 Powered By Engineering Projects Team, Raspberry Pi Projects

Scroll to top