Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rotary example #8

Open
bakman2 opened this issue Nov 4, 2021 · 3 comments
Open

rotary example #8

bakman2 opened this issue Nov 4, 2021 · 3 comments

Comments

@bakman2
Copy link

bakman2 commented Nov 4, 2021

Does the rotary example work properly ?

I do get the switch: 1 when pressed, but when rotating, I get the same thing, it does not update the value, just repeating switch 1

@bakman2
Copy link
Author

bakman2 commented Nov 4, 2021

I think something goes wrong with the bitshifting in this part of rotary:

  def _rotated(self, clk, dt):
        # shuffle left and add current 2-bit state
        self.state = (self.state & 0x3f) << 2 | (clk << 1) | dt
        
        # debug
        print('clk: {}, dt: {}, self.state: {}'.format(clk, dt,self.state))
        
        # it will never arrive here....
        if self.state == 180:

output:

clk: 1, dt: 0, self.state: 210
clk: 1, dt: 1, self.state: 75
clk: 0, dt: 1, self.state: 45
clk: 1, dt: 0, self.state: 182
clk: 1, dt: 1, self.state: 219
clk: 1, dt: 0, self.state: 110
clk: 0, dt: 1, self.state: 185
clk: 0, dt: 1, self.state: 229
clk: 1, dt: 1, self.state: 151
clk: 0, dt: 0, self.state: 92
clk: 0, dt: 1, self.state: 113
clk: 1, dt: 1, self.state: 199
clk: 1, dt: 0, self.state: 30
clk: 0, dt: 1, self.state: 121
clk: 1, dt: 1, self.state: 231
...

@bakman2
Copy link
Author

bakman2 commented Nov 6, 2021

I have modified the code and this seems to be working for me instead:

def _rotated(self, clk, dt):
        if (clk == 1) and (dt == 1): 
            self._step(-1)
        elif (clk == 1) and (dt == 0):
            self._step(1)

@mcauser
Copy link
Owner

mcauser commented Jul 29, 2022

Hi @bakman2

In an ideal world, an encoder should produce 4x states per step.

One step clockwise:
01 -> 11 -> 10 -> 00

One step counter-clockwise:
10 -> 11 -> 01 -> 00

This line is combining the clk + dt values with the last 3 executions.
self.state = (self.state & 0x3f) << 2 | (clk << 1) | dt

Could also be written as:
self.state = ((self.state << 2) | (clk << 1) | dt) & 0xff
Shift the state 2 bits left, add clk and dt bits, limit to 0-255

01 -> 11 -> 10 -> 00 == state 0b_0111_1000 == 120
10 -> 11 -> 01 -> 00 == state 0b_1011_0100 == 180

The last CD bits in both 8-bit sequences are 00. This is why it evaluates whether it should +/- step on 120/180.

Looking at your example with state in binary, it shows some missed steps in the sequence

clk: 1, dt: 0, self.state: 210	1101 0010 counter clockwise, mid sequence
clk: 1, dt: 1, self.state: 75	0100 1011 counter clockwise, mid sequence
clk: 0, dt: 1, self.state: 45	0010 1101 counter clockwise, mid sequence
clk: 1, dt: 0, self.state: 182	1011 0110 counter clockwise, missed a 11 in the sequence
clk: 1, dt: 1, self.state: 219	1101 1011 counter clockwise, missed a 00 in the sequence
clk: 1, dt: 0, self.state: 110	0110 1110 clockwise missed a 11 in the sequence
clk: 0, dt: 1, self.state: 185	1011 1001 unexpected 10 after the 1011
clk: 0, dt: 1, self.state: 229	1110 0101 unexpected 0101 in sequence
clk: 1, dt: 1, self.state: 151	1001 0111 missed 00, double 01
clk: 0, dt: 0, self.state: 92	0101 1100 double 01, missed 10 after 11
clk: 0, dt: 1, self.state: 113	0111 0001 missed 10 after 11
clk: 1, dt: 1, self.state: 199	1100 0111 missed 10 after 11
clk: 1, dt: 0, self.state: 30	0001 1110 clockwise, mid sequence
clk: 0, dt: 1, self.state: 121	0111 1001 missed 00 after 10
clk: 1, dt: 1, self.state: 231	1110 0111 missed 00 after 10 

This could be caused by not polling fast enough, or a flakey encoder, loose wiring, all of the above, etc.

In your solution, you're using the CD states 11 and 10 to +/- the step.
This doesn't work as 11 and 10 are in both clockwise and counter clockwise sequences.

I'll try to replicate on some of my old encoders.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants