Package: pyky040
pyKY040High-level Python module for the KY040 rotary encoder and switchon Raspberry Pi and similar boards that useRPi.GPIOFeaturesIncrement callbackDecrement callbackChange callback (increment or decrement)Switch press callbackOptionsScale mode (internal counter is bound between X and Y, and is given as argument in the callback functions)Looped scale mode (from X to Y, then X again)Custom scale stepGPIO polling (easier) oras a device(sturdier)Installationpipinstallpyky040UsageBasic# Import the modulefrompyky040importpyky040# Define your callbackdefmy_callback(scale_position):print('Hello world! The scale position is{}'.format(scale_position))# Init the encoder pinsmy_encoder=pyky040.Encoder(CLK=17,DT=18,SW=26)# Or the encoder as a device (must be installed on the system beforehand!)# my_encoder = pyky040.Encoder(device='/dev/input/event0')# Setup the options and callbacks (see documentation)my_encoder.setup(scale_min=0,scale_max=100,step=1,chg_callback=my_callback)# Launch the listenermy_encoder.watch()# Mess with the encoder...# > Hello world! The scale position is 1# > Hello world! The scale position is 2# > Hello world! The scale position is 3# > Hello world! The scale position is 2# > Hello world! The scale position is 1In a threadAs thewatch()method runs an infinite polling loop, you might want to run it in a thread if you don't want to block the rest of your script, or if you havemultiple encodersto handle.# Import the module and threadingfrompyky040importpyky040importthreading# Define your callbackdefmy_callback(scale_position):print('Hello world! The scale position is{}'.format(scale_position))# Init the encoder pinsmy_encoder=pyky040.Encoder(CLK=17,DT=18,SW=26)# Or the encoder as a device (must be installed on the system beforehand!)# my_encoder = pyky040.Encoder(device='/dev/input/event0')# Setup the options and callbacks (see documentation)my_encoder.setup(scale_min=0,scale_max=100,step=1,chg_callback=my_callback)# Create the threadmy_thread=threading.Thread(target=my_encoder.watch)# Launch the threadmy_thread.start()# Do other stuffprint('Other stuff...')whileTrue:print('Looped stuff...')sleep(1000)# ... this is also where you can setup other encoders!# Mess with the encoder...# > Other stuff...# > Looped stuff...# > Hello world! The scale position is 1# > Hello world! The scale position is 2# > Hello world! The scale position is 3# > Looped stuff...# > Hello world! The scale position is 2Note:The interruption of the module when running in threads is not yet handled, you might have to kill it by yourself 🔪DocumentationEncoder(CLK=x, DT=y, SW=z)Initializes the module with the specified encoder pins.Optionspolling_intervalSpecify the pins polling interval in ms (default 1ms)Encoder(device='...')⚠️ Linux onlyInitializes the module with the specified encoder device.Read moreRequirement:pip install pyky040[device]Encoder.setup()Setup the behavior of the module. All of the following keyword arguments are optional.Callbacksinc_callback (function)When the encoder is incremented (clockwise). Scale position as first argument.dec_callback (function)When the encoder is decremented. Scale position as first argument.chg_callback (function)When the encoder is either incremented or decremented. Scale position as first argument.sw_callback (function)When the encoder switch is pressedScale modescale_min (int/float)Scale minimumscale_max (int/float)Scale maximumloop (boolean)Loop mode (defaults toFalse)step (int/float)Scale step when incrementing or decrementingOptionssw_debounce_time (int/float)Switch debounce time in ms (allow only one interrupt per X ms, dismiss others)Note:better keep using ints and not floats for more precise results.Encoder.watch()Starts the listener. The pins polling interval is1msby default and can be customized (seeEncoder()).Should I use the GPIO polling or the device overlay?The Raspberry Pi firmware allows the encoder to be set up as a device with therotary-encoderoverlay. It tradesthe promise to catch every encoder tickforthe ease of use(because it needs to be installed on the host beforeheand, with root privileges).ApproachPlug & PlayNeeds prior installationCatches every tickGPIO pollingYesNoNoDevice overlayNoYesYesHow to install the encoder as a device?Only tested on Raspbian Buster at this time.# Copy this line in `/boot/config.txt` and reboot
# (replacing {CLK_PIN} and {DT_PIN} by their real values)
dtoverlay=rotary-encoder,pin_a={CLK_PIN},pin_b={DT_PIN},relative_axis=1,steps-per-period=2TROUBLESHOOTINGErratic behaviorIt is known that some pins combinations introduce erratic behavior (interferences?). The library has been tested successfully using the following combinations (BCM numbering).CLKDTSWPiRaspbian264213B (1.2)BusterFeel free to edit the README to provide your working combinations!If you are still experiencing issues, you might want to try toset up the encoder as a deviceinstead.CHANGELOG0.1.4Addeddevicemode0.1.3Fixedlatest_switch_callnot defined before the loop0.1.2Changed__init_args to kwargs for better readability and ease of useEncoder(CLK=x, DT=y, SW=z)Added customizable debounce time (in ms) for the switchsetup(..., sw_debounce_time=300)Added customizable polling interval (in ms)Encoder(..., polling_interval=1)