04-07-2024, 01:53 PM
In case anyone else wants to do this, I initially started by trying to modify the Moode script that does the volume but I couldn't get it working satisfactorily. in the end I achieved this by writing a separate Python script which calls the mpc commands for prev/next, and setting it as a service, with an adequate sleep time so as not to absolutely nail the CPU.
The debounce time and part of the script that ignores inputs if there are less than two consecutive clicks each direction help to make my cheap KY-040 encoder work smoothly.
See below:
The debounce time and part of the script that ignores inputs if there are less than two consecutive clicks each direction help to make my cheap KY-040 encoder work smoothly.
See below:
Code:
import RPi.GPIO as GPIO
import subprocess
import time
# GPIO pins (BCM numbering)
clk = 23
dt = 24
# Set up GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(clk, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(dt, GPIO.IN, pull_up_down=GPIO.PUD_UP)
# Initial states
clkLastState = GPIO.input(clk)
directionCounter = 0 # Counts consecutive moves in the same direction
lastDirection = None
debounceTime = 0.04
def read_rotary():
global clkLastState, directionCounter, lastDirection
clkState = GPIO.input(clk)
dtState = GPIO.input(dt)
if clkState != clkLastState:
if dtState != clkState:
currentDirection = "next"
else:
currentDirection = "prev"
if currentDirection == lastDirection:
directionCounter += 1
else:
directionCounter = 1 # Reset counter on direction change
# Act only if there have been two consecutive clicks in the same direction
if directionCounter >= 2:
if currentDirection == "next":
subprocess.run(['mpc', 'next'])
else:
subprocess.run(['mpc', 'prev'])
# Reset after action
directionCounter = 0
lastDirection = None
else:
# Update lastDirection for next comparison
lastDirection = currentDirection
time.sleep(debounceTime) # Debounce delay
clkLastState = clkState
# Polling loop
try:
while True:
read_rotary()
time.sleep(0.01) # Short sleep to reduce CPU usage
except KeyboardInterrupt:
GPIO.cleanup() # Clean up GPIO on CTRL+C exit