Last active
December 3, 2019 14:26
-
-
Save n3rd/dbaca08a48b74f970307 to your computer and use it in GitHub Desktop.
Raspberry Pi + KY040 Rotary Encoder (+ S/W Volume Control)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/local/bin/python | |
import RPi.GPIO as GPIO | |
class RotaryEncoder: | |
DIRECTION_CLOCKWISE = 1 | |
DIRECTION_COUNTERCLOCKWISE = 3 | |
prv_seq = 0 | |
direction = 0 | |
def __init__(self, pinA, pinB, button, callback): | |
self.pinA = pinA | |
self.pinB = pinB | |
self.button = button | |
self.callback = callback | |
GPIO.setup(self.pinA, GPIO.IN, pull_up_down=GPIO.PUD_UP) | |
GPIO.setup(self.pinB, GPIO.IN, pull_up_down=GPIO.PUD_UP) | |
GPIO.setup(self.button, GPIO.IN, pull_up_down=GPIO.PUD_UP) | |
GPIO.add_event_detect(self.pinA, GPIO.FALLING, callback=self.evt) | |
GPIO.add_event_detect(self.pinB, GPIO.FALLING, callback=self.evt) | |
def evt(self, channel): | |
a = GPIO.input(self.pinA) | |
b = GPIO.input(self.pinB) | |
c = a ^ b | |
seq = c | b << 1 | |
delta = (seq - self.prv_seq) % 4 | |
if delta == 1: | |
if self.direction == self.DIRECTION_CLOCKWISE: | |
self.callback(self.DIRECTION_CLOCKWISE, self.button_press()) | |
else: | |
self.direction = self.DIRECTION_CLOCKWISE | |
elif delta == 2: | |
if self.direction == self.DIRECTION_CLOCKWISE: | |
self.callback(self.DIRECTION_CLOCKWISE, self.button_press()) | |
elif self.direction == self.DIRECTION_COUNTERCLOCKWISE: | |
self.callback(self.DIRECTION_COUNTERCLOCKWISE, self.button_press()) | |
elif delta == 3: | |
if self.direction == self.DIRECTION_COUNTERCLOCKWISE: | |
self.callback(self.DIRECTION_COUNTERCLOCKWISE, self.button_press()) | |
else: | |
self.direction = self.DIRECTION_COUNTERCLOCKWISE | |
self.prv_seq = seq | |
def button_press(self): | |
return GPIO.input(self.button) == GPIO.LOW |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/local/bin/python | |
# KY040 Rotary Encoder + Raspberry Pi (Model A+) | |
# === | |
# + (5V) e.g. GPIO.BOARD 2 | |
# BTN is on GPIO.BOARD 12 | |
# GND e.g. GPIO.BOARD 14 | |
# B (DT) is on GPIO.BOARD 16 | |
# A (CLK) is on GPIO.BOARD 18 | |
import sys | |
import time | |
import RPi.GPIO as GPIO | |
from RotaryEncoder import RotaryEncoder | |
# (!) use BOARD NRs for PINs | |
GPIO.setmode(GPIO.BOARD) | |
GPIO.setwarnings(False) | |
def main_loop(): | |
while True: | |
time.sleep(0.5) | |
def callback(direction, btn_pressed): | |
if direction == RotaryEncoder.DIRECTION_CLOCKWISE and not btn_pressed: | |
print 'CLOCKWISE' | |
elif direction == RotaryEncoder.DIRECTION_COUNTERCLOCKWISE and not btn_pressed: | |
print 'COUNTERCLOCKWISE' | |
elif direction == RotaryEncoder.DIRECTION_CLOCKWISE and btn_pressed: | |
print 'CLOCKWISE + BUTTON' | |
elif direction == RotaryEncoder.DIRECTION_COUNTERCLOCKWISE and btn_pressed: | |
print 'COUNTERCLOCKWISE + BUTTON' | |
if __name__ == '__main__': | |
try: | |
enc = RotaryEncoder(18, 16, 12, callback) | |
print "listening..." | |
main_loop() | |
except KeyboardInterrupt: | |
print >> sys.stderr, '\nExiting by user request.\n' | |
sys.exit(0) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/local/bin/python | |
# depends on: http://pyalsaaudio.sourceforge.net | |
# sudo apt-get install python-alsaaudio | |
# KY040 Rotary Encoder + Raspberry Pi (model A+) | |
# === | |
# + (5V) e.g. GPIO.BOARD 2 | |
# BTN is on GPIO.BOARD 12 | |
# GND e.g. GPIO.BOARD 14 | |
# B (DT) is on GPIO.BOARD 16 | |
# A (CLK) is on GPIO.BOARD 18 | |
import sys | |
import time | |
import alsaaudio | |
import RPi.GPIO as GPIO | |
from RotaryEncoder import RotaryEncoder | |
# (!) use BOARD NRs for PINs | |
GPIO.setmode(GPIO.BOARD) | |
GPIO.setwarnings(False) | |
class Volume: | |
def __init__(self): | |
self.mixer = alsaaudio.Mixer(control='PCM') | |
def get_volume(self): | |
return self.mixer.getvolume('playback')[0] | |
def set_volume(self, percentage): | |
if percentage < 0: | |
percentage = 0 | |
elif percentage > 100: | |
percentage = 100 | |
self.mixer.setvolume(percentage) | |
time.sleep(.2) | |
def volume_up(self): | |
self.set_volume(self.get_volume() + 5) | |
def volume_down(self): | |
self.set_volume(self.get_volume() - 5) | |
def callback(self, direction, btn_pressed): | |
if direction == RotaryEncoder.DIRECTION_CLOCKWISE: | |
self.volume_up() | |
elif direction == RotaryEncoder.DIRECTION_COUNTERCLOCKWISE: | |
self.volume_down() | |
def main_loop(): | |
while True: | |
time.sleep(0.5) | |
if __name__ == '__main__': | |
try: | |
vol = Volume() | |
enc = RotaryEncoder(18, 16, 12, vol.callback) | |
main_loop() | |
except KeyboardInterrupt: | |
print >> sys.stderr, '\nExiting by user request.\n' | |
sys.exit(0) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment