vash3d / pigpio_encoder

Python module for the KY040 rotary encoder.
GNU General Public License v3.0
14 stars 4 forks source link

pigpio encoder needs 2 encoder steps to trigger callbacks #18

Closed TurBoss closed 3 years ago

TurBoss commented 3 years ago

Hello,

I'm trying to run pigpio_encoder but I'm facing this issue

pigpio encoder needs 2 encoder steps to trigger callbacks

does any one know why? do I need to setup something else

        self.encoder = Rotary(
                        clk_gpio=23,
                        dt_gpio=18,
                        sw_gpio=17
        )

        self.encoder.setup_rotary(
            min=0,
            max=120,
            scale=1,
            debounce=200,
            rotary_callback=self.encoder_activity,
            up_callback=self.encoder_up,
            down_callback=self.encoder_down
        )
        self.encoder.setup_switch(
            debounce=200,
            long_press=True,
            sw_short_callback=self.encoder_short,
            sw_long_callback=self.encoder_long
            )

I'm not calling watch

thanks

TurBoss commented 3 years ago

arduino example runs fine

int pinA = 3;  // Connected to CLK on KY-040
int pinB = 4;  // Connected to DT on KY-040
int encoderPosCount = 0;
int pinALast;
int aVal;
boolean bCW;
void setup() {
  pinMode (pinA, INPUT);
  pinMode (pinB, INPUT);
  /* Read Pin A
    Whatever state it's in will reflect the last position
  */
  pinALast = digitalRead(pinA);
  Serial.begin (9600);
}
void loop() {
  aVal = digitalRead(pinA);
  if (aVal != pinALast) { // Means the knob is rotating
    // if the knob is rotating, we need to determine direction
    // We do that by reading pin B.
    if (digitalRead(pinB) != aVal) {  // Means pin A Changed first - We're Rotating Clockwise
      encoderPosCount ++;
      bCW = true;
    } else {// Otherwise B changed first and we're moving CCW
      bCW = false;
      encoderPosCount--;
    }
    Serial.print ("Rotated: ");
    if (bCW) {
      Serial.println ("clockwise");
    } else {
      Serial.println("counterclockwise");
    }
    Serial.print("Encoder Position: ");
    Serial.println(encoderPosCount);

  }
  pinALast = aVal;
}
volkerjaenisch commented 3 years ago

@TurBoss

Your setup looks fine to me. This may be a bug.

Can you please check two things 1) Disable the debouncing 2) Use only the up or down callback

Cheers, Volker

TurBoss commented 3 years ago

did this same result

        self.encoder.setup_rotary(
            min=0,
            max=120,
            scale=1,
            up_callback=self.encoder_up,
            down_callback=self.encoder_down
        )

thanks for your super fast response :D

TurBoss commented 3 years ago

thats the callbacks

just prints


    def encoder_up(self, var):
        print(f"UP {var}")

    def encoder_down(self, var):
        print(f"DOWN {var}")
volkerjaenisch commented 3 years ago

@TurBoss

Thanks for the testing. I will dig into this later today. Stay tuned.

Cheers, Volker

volkerjaenisch commented 3 years ago

@TurBoss I checked with my rotary and it (the demo.py) works OOTB and as expected (SW=GPIO19, DT=GPIO13, CLK=GPIO6): One rotary step leads to one callback (in both directions). A few probably helpful questions:

Cheers, Volker

TurBoss commented 3 years ago

Hello, thanks for confirming that works ok i ordered KY-040 but apparently they are labeled like HW-040

so looks like not a good model

I'll try to get the HY-040 ones

super thanks

volkerjaenisch commented 3 years ago

you are welcome

TurBoss commented 3 years ago

I'll close this issue

TurBoss commented 3 years ago

Hello,

I just found some code for arduino that mentions the encoder "scale" depending on the model

KY-040 = 2 HW-040 = 1

https://github.com/ClemensGruber/hani-mandl/blob/master/hani-mandl.ino#L101

I don't know if can help

volkerjaenisch commented 3 years ago

@TurBoss

This case is a sort of mistery to me:

[Note: The algorithm is not from my person, I just took over the maintainer role and did some optimizations].

I have looked into the code. The algorithm looks wrong to me. Not generally but in case of the initial startup it is possible that the rotary will need TWO INITIAL rotation steps before the algorithm starts working correctly.

Can you please check if the two rotation steps you noticed are at the start of operation OR if there is always two steps needed.

I will dig into this and make the algorithm better. But I am quite sure that this will not cure the problem you are facing.

Cheers, Volker

volkerjaenisch commented 3 years ago

@TurBoss

Reviewed the Algorithm. Works IMHO correctly, my assumption was not correct.

I have pushed a new version. This version has a new debug switch def init(self, clk_gpio=None, dt_gpio=None, sw_gpio=None, debug=False):

Would you be so kind and run the demo.py and post the screen output here.

Please then do these two tests:

KY-040 : Left rotation (with my annotations):
:D
D:C
DC:d
DCd:c
<- End of rotation step
General rotation    
Counter value:  1
Up rotation
Counter value:  1
:D
D:C
DC:d
DCd:c
 <- End of rotation step
General rotation
Counter value:  2
Up rotation
Counter value:  2
:D
D:C
DC:d
DCd:c
 <- End of rotation step
General rotation
Counter value:  3
Up rotation
Counter value:  3
:D
D:C
DC:d
DCd:c
 <- End of rotation step
General rotation
Counter value:  4
Up rotation
Counter value:  4
:D
D:C
DC:d
DCd:c
 <- End of rotation step
General rotation
Counter value:  5
Up rotation
Counter value:  5
KY-040 : Right rotation:
:C
C:D
CD:c
CDc:d
 <- End of rotation step
Down rotation
Counter value:  0
:C
C:D
CD:c
CDc:d
 <- End of rotation step
Down rotation
Counter value:  0
:C
C:D
CD:c
CDc:d
 <- End of rotation step
Down rotation
Counter value:  0
:C
C:D
CD:c
CDc:d
 <- End of rotation step
Down rotation
Counter value:  0
:C
C:D
CD:c
CDc:d
 <- End of rotation step
Down rotation
Counter value:  0

I have the strong suspicion that your rotary may have a finer (halfstep) gridding.

Cheers, Volker

TurBoss commented 3 years ago

hello, I ordered this ones https://www.amazon.es/gp/product/B08YJZRPP2?psc=1 from amazon they where advertised as KY-040 but labeled as HW-040

I'm going to test debug

Thanks

TurBoss commented 3 years ago

did the tests running demo.py

5 right steps:

:D
D:C
DC:d
DCd:c
General rotation
Counter value:  1
Up rotation
Counter value:  1
:D
D:C
DC:d
DCd:c
General rotation
Counter value:  2
Up rotation
Counter value:  2
:D
D:C

and 5 left steps

DC:c
DCc:d
DCcd:C
C:D
CD:c
CDc:d
General rotation
Counter value:  1
Down rotation
Counter value:  1
:C
C:D
CD:c
CDc:d
General rotation
Counter value:  0
Down rotation
Counter value:  0

Thank you!

volkerjaenisch commented 3 years ago

@TurBoss

Thank you for the test data.

Cheers, Volker

volkerjaenisch commented 3 years ago

@TurBoss

Assuming that you posted the data of 5 rotations.

Can you please mark in the log where you feeled the rotation step ending?

Cheers, Volker

TurBoss commented 3 years ago

ops forgot to restart with left steps

volkerjaenisch commented 3 years ago

hello, I ordered this ones https://www.amazon.es/gp/product/B08YJZRPP2?psc=1 from amazon they where advertised as KY-040 but labeled as HW-040

They look on amazon exactly like the ones I use:

Cheers, Volker

volkerjaenisch commented 3 years ago

ops forgot to restart with left steps

Please also indicate where you feeled the end of the rotation stop.

Cheers, Volker

TurBoss commented 3 years ago

this is right and left separated steps

this is 5 setps right

$ python3 demo.py 
-------------------
:D
D:C
------------------- 
DC:d
DCd:c
General rotation
Counter value:  1
Up rotation
Counter value:  1

------------------- 
:D
D:C
------------------
DC:d
DCd:c
General rotation
Counter value:  2
Up rotation
Counter value:  2
------------------
:D
D:C

and 7 left

-------------
:c
c:d
-------------- 
cd:C
cdC:D
---------------
D:c
Dc:d
--------------  
Dcd:C
C:D
--------------
CD:c
CDc:d
Down rotation
Counter value:  0
--------------
:C
C:D
-------------
CD:c
CDc:d
Down rotation
Counter value:  0
-------------

Thanks

volkerjaenisch commented 3 years ago

@TurBoss Thank you! I assume that the dashed lines are the grid points.

This shows clearly that your rotary has a half-step grid.

I can write a driver for this, but it will be quite less accurate than the full step KY-040.

Background: The current code decides on a sequence of four signal changes. On a half-grid there is only a sequence of two signal changes available for the decision. This reduces the accuracy from 100% (KY-040) to 25% (Your device).

My advice is to buy KY-040 full-step and be happy with the current driver.

Cheers, Volker

TurBoss commented 3 years ago

okay thank you I'll buy new ones !

:)

TurBoss commented 3 years ago

hey! just got it working correctly with new encoder!! :-)

thank you!