Closed imdbere closed 10 months ago
I believe you want to change the last argument you have to rotaryio.IncrementalEncoder()
from a 1
to a 4
(the default). e.g. do this:
encoder = rotaryio.IncrementalEncoder(board.GP7, board.GP8, 4)
or
encoder = rotaryio.IncrementalEncoder(board.GP7, board.GP8)
Thanks, i tried that but setting it to 4 makes the value only change on every 4th increment
Have you tried setting it to 2? It really depends on the encoder what that value should be.
Could you link to the encoder you are using? How are you wiring it? There should be two signal terminals, and a common terminal connected to ground.
I had a rotary encoder project handy, QT Py RP2040 and CNC rotary encoder
This project is running Adafruit CircuitPython 8.2.8 on 2023-11-16; Adafruit QT Py RP2040 with rp2040
# SPDX-FileCopyrightText: 2018 Kattni Rembor for Adafruit Industries
#
# SPDX-License-Identifier: MIT
import board
#import rotaryio
from rotaryio import IncrementalEncoder
import usb_hid
from adafruit_hid.mouse import Mouse
r = IncrementalEncoder(board.MOSI, board.MISO, count=1)
mouse = Mouse(usb_hid.devices)
old_position = r.position
while True:
position = r.position
delta = position - old_position
if delta:
print(f"{position%4} {delta:+2d}")
old_position = position
if delta != 0:
mouse.move(wheel=-delta)
I don't reproduce the mentioned problem. Let me describe what I do see:
count=4
(the default), each click of the wheel is 1 "position" changecount=1
, each click of the wheel is a 4 "position" changeThere are all kinds of encoder wheels in the world; those that have detents can have them every 1, 2, or 4 quadrature counts apart. Most or all of the encoder wheels that Adafruit sells that have detents are 4 counts per detent, which is why the default is 4.
I don't know the exact model of the encoder anymore unfortunately and i tried all the settings, like i said a divisor of 1 leads to the correct total counted clicks, just the way its counted is wrong (2 position changes every two clicks).
I think the problem is that the library counts every falling edge twice while not counting rising edges at all, which probably makes no difference if the encoder has more than 1 count per detent. Maybe this graphic will help:
Thanks for you help!
It really depends on the encoder, which is why DanH asked for details. The number of felt detents does not always correlate to number of pulses. See this datasheet for the common EC11 series of rotary encoders: https://www.mouser.com/datasheet/2/15/EC11-1370808.pdf Notice the "number detents" vs "number of pulses" columns.
Do you have another non-RP2040 board to try, such as a SAMD21 or SAMD51 (or Espressif or nRF)? The internal implementation is different for those processor families. If you get different results, then that says something is different about the RP2040 implementation. We have done testing of this and it didn't seem off (for instance the rotary encoder on the MacroPad, which uses an RP2040).
Like mentioned i don't know the exact model but measuring the output seems to match this diagram in the datasheet, so basically half a cycle per detent. I do have some ESP32s laying around which i could give a try if that helps
These details apply to RP2040; other microcontroller families may use other methods for quadrature counting
The IncrementalEncoder on the RP2040 uses all quadrature edges (different than either of the images you showed).
Each transition 00 -> 01 -> 11 -> 10 -> 00 increases an internal counter by 1, and any transition in the reverse direction decreases it by 1. (invalid glitches like 00 -> 11 or 01 -> 10 do not change the count; non-changes like 00 -> 00 do not change the count)
When the internal counter reaches the division value in positive direction, the position property increases by 1. When it reaches it in the negative direction (e.g., -1, -2 or -4) the position property decreases by 1.
It might be helpful to eliminate your encoder entirely. I grabbed an Adafruit Macropad because it has an RP2040 microcontroller, display, and keys; and created a program that watches the first two keys and treats them like a quadrature encoder.
import board
from rotaryio import IncrementalEncoder
e = IncrementalEncoder(board.KEY1, board.KEY2, 1)
v = e.position
print(f"{0:+1d} {v}")
while True:
new_v = e.position
if v != new_v:
delta = new_v - v
print(f"{delta:+1d} {new_v}")
v = new_v
you can probably create a similar setup on your Pico with some spare switches.
If I go through these steps starting with no keys pressed:
+0 0
+1 1
+1 2
+1 3
+1 4
+1 5
+1 6
+1 7
+1 8
-1 7
-1 6
-1 5
-1 4
-1 3
-1 2
-1 1
-1 0
-1 -1
-1 -2
-1 -3
-1 -4
If I change the divisor from 1 to 2 or 4, then position changes by just 1/2 or 1/4 as many:
+0 0
+1 1
+1 2
-1 1
-1 0
-1 -1
Thanks for the detailed response, will do some debugging and then come back to you, if it is counted like you described there must be an error in my setup š¤
Please show us how you have wired the project. I think that would be more helpful in figuring out what is going on, vs substituting a different microcontroller.
Repeating Dan's earlier message:
There should be two signal terminals, and a common terminal connected to ground.
example of wiring an encoder with circuitpython (this one also wires the "press in to click" function available on some encoders)
if one of the signal terminals is interchanged with ground, that might cause what you are seeing
I checked my circuit again and I indeed had the ground wire switched with one of the signal wires (didn't have a pinout or a datasheet unfortunately š). Feeling quite stupid now, thanks for your all your help and sorry for the caused effort!
You're welcome. it could happen to anybody :)
CircuitPython version
Code/REPL
Behavior
Hi, I am using CircuitPython with a generic incremental encoder and i have the following problem: Whenever i turn the encoder it seems to not react to one of the increments and then add two to the next one. So the outputted position increases like 0, 2, 4 etc. while only reacting to every second increment. This means the total amount of increments is correct, but it makes it not really usable for things like an input for a UI.
I did some further measurements and it seems like the library is only counting a step when either of the pins goes from HIGH to LOW, and not doing anything when they go from LOW to HIGH. Is this intended behaviour? Thanks :)
Description
No response
Additional information
No response