Thank you for your donation!


Cloudsmith graciously provides open-source package management and distribution for our project.


Rotary encoder for switching tracks
#2
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:


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
Reply


Messages In This Thread
Rotary encoder for switching tracks - by hcanning - 04-03-2024, 03:25 PM
RE: Rotary encoder for switching tracks - by hcanning - 04-07-2024, 01:53 PM

Forum Jump: