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

Description and example code for KY-040 encoder does not reflect operation of actual device #168

Open
ahmogit opened this issue Mar 4, 2023 · 16 comments
Labels
documentation Improvements or additions to documentation

Comments

@ahmogit
Copy link

ahmogit commented Mar 4, 2023

Re this page:

           https://docs.wokwi.com/parts/wokwi-ky-040

Is it your intent that the simulation of the KY-040 exactly match the behavior of the actual device? If that is the intent, then both the description (in the Operation section) and the associated example code (first example under Reading the rotation) are incorrect: The stated description does not reflect the behavior of the actual device, and the associated example code will not work correctly on the actual device.

I would be happy to provide a pull request with corrections that bring the description and the code into agreement with actual device behavior, but first wanted to ask whether it is even your intent that the simulation match the actual device behavior. Perhaps your intent is only that the simulation behave in a functionally similar way, but not mimic the device exactly....?

@urish urish added the documentation Improvements or additions to documentation label Mar 4, 2023
@urish
Copy link
Contributor

urish commented Mar 4, 2023

Thanks for the feedback!

The intent is to have the simulation match as closely at it make sense (i.e. requires a reasonable level of effort and is not computationally heavy). For parts that can't be accurately simulated, we should at least point out any significant differences in the documentation. I'd love to read what you think is inaccurate so we can address it.

@ahmogit
Copy link
Author

ahmogit commented Mar 4, 2023

Here's a summary of the changes required to bring the operational description and the example code into agreement with the behavior that I see with real-world KY-040 parts, and consistent with your own timing diagram (which is correct as shown).

If you agree with what is below, I'll be happy to provide a pull request that corrects the errors. However, if you dispute my analysis, I'll also be happy to go down to the next level of detail and make the case with some carefully-drawn timing diagrams and results obtained using an actual part, just to avoid the time spent in submitting a pull request that you may not agree with.

(But I think you should be able to verify all of the corrections below by simply examining the behavior of an actual KY-040 part using a scope or multimeter. Your timing diagram shows the real-world behavior correctly.)

===========================================================================
Regarding the Operation section, which states the following:

    "Every time the user rotates the knob, it produces a LOW signal on the DT and CLK pins:"

That statement does not agree with the behavior of any quadrature encoder that I have ever worked with, and in particular, does not agree with the behavior of the Taiss KY-040, which is a pretty common Chinese part. All quadrature encoders I've come across toggle the state of both CK and DT pins on every detent movement (i.e. on every "click" of the encoder shaft); but the direction (and final state) alternates: It "produces a LOW signal" (per your statement above) only on every other detent movement, not on every detent movement.

Concrete example that you can check easily yourself with just a power supply and a multimeter or scope: Set the initial detent position such that the state of both CLK and DT happens to be HIGH: In this case, rotating the shaft by one detent position (in either direction) will indeed change the final state of both CLK and DT to LOW, as your document states above. But if the initial detent position happens to be such that CLK at DT are both LOW, then rotating the shaft by one position in either direction will change the state of both CLK and DT to HIGH, contradicting the word "every" in the above statement from your document.

In other words, with the real-world part, every detent click, in either direction, results in a transition of both CLK and DT, but the direction of that transition (hence the final state in the new detent position) depends on the steady-state value of the initial position. It does not always "produce a LOW signal", as stated in your doc.

===========================================================================
Interestingly, the Reading the rotation code example fixes the above interpretational mistake by (correctly) conditionalizing the direction assessment based on


    if (newClk != lastClk) 
    {
            ...
    }
         

which correctly assesses the direction on every CLK transition, not just transitions from HIGH to LOW. Unfortunately, the example code also introduces a new mistake in determining the direction of rotation by assessing the direction like this:

    if (newClk == LOW && dtValue == HIGH) {
      Serial.println("Rotated clockwise ⏩");
    }
    if (newClk == LOW && dtValue == LOW) {
      Serial.println("Rotated counterclockwise ⏪");
    }

But that is not correct: The correct clauses should be:

    if (newClk == LOW) {
       if (dtValue == HIGH) 
          Serial.println("Rotated clockwise ⏩");
       else
          Serial.println("Rotated counterclockwise ⏪");
    }
    

    if (newClk == HIGH) {
       if (dtValue == HIGH)
          Serial.println("Rotated counterclockwise ⏪");
       else
          Serial.println("Rotated clockwise ⏩");       
    }

The above corrected version is consistent with both the observed behavior of an actual Taiss part and with the timing diagram shown in your document. (And of course the above corrected clauses could be improved efficiency-wise by preceding the second clause with "else".)

===========================================================================

Again, if you're not convinced of the above analysis after fiddling around with an actual KY-040 part in view of the manufacturer's datasheet, just let me know, and I'll be glad to provide additional detail and actual test results using a Taiss KY-040.

@urish
Copy link
Contributor

urish commented Mar 5, 2023

Thanks for the detailed explanation!

I did a quick experiment with my logic analyzer and a rotary encoder that I have here (from Ender-3 S1 printer). This is what I'm seeing I make a single detent movement clockwise:

image

And when I make a single detent movement counterclockwise:

image

Each channel has a pull-up resistor (otherwise, the signal is always low, and does not change when I move the knob).

From what I see, it looks like there are two transitions on each channel for every detent movement: first, it goes LOW, then HIGH.

However, if I make what I perceive as partial movement (carefully applying force to the knob so that is hangs between two clicks), it does make a single transition (either goes to HIGH or to LOW). When the encoder is connected to the printer, however, it doesn't register this as a movement - it requires two transitions (so HIGH to LOW and then back HIGH), before the UI responds (e.g. moves to the next item in the menu).

I guess either different people may have different definitions of what a detent movement is, or different rotary encoders give different kind of feedback. I don't have a Taiss KY-040 at hand to tell whether this is a matter of definition or difference between rotary encoder, but I will try to obtain a unit. In any case, we should probably adapt the docs to reflect that.

@ahmogit
Copy link
Author

ahmogit commented Mar 5, 2023

Interesting.

Couple of questions:

  • Is the encoder that you examined identified in any way as being a KY-040 part? (Can you supply a photo of it?)

  • When you did your test with the logic analyzer, was the encoder completely isolated from the printer, or were any lines still connected to the printer? The reason for the question is that unless the encoder was completely isolated, it is possible that the printer logic was unintentionally "participating" in the experiment in some fashion. I would be inclined to some degree of skepticism in interpreting the results unless the part was examined "bare", i.e. completely, totally isolated.

As to the definition of "detent movement": I can't speak for anyone but myself, but what I mean by a "detent movement" is a monotonic angular rotation of the shaft, starting from one stable shaft position and ending at an adjacent stable shaft position, in either direction, with no attempt to retard the movement during the transition.

For example, define three stable adjacent shaft positions A, B, and C, located respectively at (say) 12-o'clock, 1-o-clock, and 2-o'clock positions. Then what I mean by a single "detent movement" is a monotonic rotation from A to B or from B to C or from C to B or from B to A.

I've not come across any mechanical shaft encoders that behave as you are showing, but that certainly doesn't mean there aren't any. (One precision optical encoder I worked with many years ago may have possibly behaved as you show, but I am not sure of that and may simply be mis-recalling.)

In any case, your document explicitly claims to describe the behavior of the KY-040, and I can say for sure that the Taiss KY-040's that I have do behave as stated in my previous post. I just checked carefully again, to be sure I was not mis-interpreting or mis-reporting, but there is no ambiguity: Each detent movement (as defined above) toggles the state of both CLK and DT. There is no "return to HIGH" or "return to LOW" at the final detent position: It's just a straightforward toggle, nothing more.

And that toggle behavior is fully constent with the attached document, which appears to be excerpted from the datasheet for a KY-040 manufactured by Keyes.

Annoyingly, I could not quickly put my hands a datasheet claiming to be published by Taiss, but in any case, I buzzed out my Taiss unit and the schematic is exactly as shown for the Keyes KY-040, including the two on-board 10k pullups. The Taiss units appear to be physically identical to the photos shown of the Keyes part.

Anyway... it will be interesting to hear what you find if you are able to put your hands on a part that is definitely represented as being a KY-040.

KEYES_KY-040.pdf

P.S. Btw, as an amusing aside from issue we're discussing: Both the Keyes and Taiss KY-040's have 30 detent positions, despite the fact that they are both routinely mis-advertised (e.g. Amazon, eBay, AliExpress, etc.) as having 20 positions. (Your document also mentions 20 positions up at the top.)

@urish
Copy link
Contributor

urish commented Mar 5, 2023

Is the encoder that you examined identified in any way as being a KY-040 part? (Can you supply a photo of it?)

Nope, I didn't take apart the LCD assembly, and the only thing I could find online was this photo:

LCD assembly

It does seem similar in appearance of the encoder inside the KY-040.

When you did your test with the logic analyzer, was the encoder completely isolated from the printer, or were any lines still connected to the printer?

I tested by connecting to the connector at the back of the LCD assembly, while it was disconnected from the printer.

In any case, I just ordered an KY-040 compatible encoder (it says LB-Link instead of Keyes), to remove another bit of uncertainty. I will update once it arrives.

@ahmogit
Copy link
Author

ahmogit commented Mar 5, 2023

It does seem similar in appearance of the encoder inside the KY-040.

That actually looks like it may be an EC-11 rather than a KY-040, but it's hard to tell, they do look similar.

The EC-11's I've got operate like the KY-040's as well. Here's a datasheet for the Alps line of EC-11s:

https://www.mouser.com/datasheet/2/15/alps_alps-s-a0008379064-1-1733314.pdf

See the timing diagram at the top of p. 7. That diagram explicitly defines what they mean by "stable detent position", and it makes clear that the operation I refer to above as "detent movement" (i.e. moving from one stable detent position to an adjacent stable detent position) results in a toggle of both lines, not a "return to HIGH" or "return to LOW".

@urish
Copy link
Contributor

urish commented Mar 12, 2023

Update: still waiting for the KY-040 compatible board. Should be shipped this week, according to store.

@ahmogit
Copy link
Author

ahmogit commented Mar 13, 2023

Ok, will be interesting to see exactly how it behaves. Can you post the URL of the site that you ordered it from?

Btw, here is another explanatory blurb which seems to indicate that the encoding operation is as I described in the original post, i.e. that movement from one detent to an adjacent detent (in either direction) toggles both CK and DT, rather than "return to HIGH" at each detent position:

https://components101.com/modules/KY-04-rotary-encoder-pinout-features-datasheet-working-application-alternative

Unfortunately, the document does not state that explicitly, but if the vertical dotted lines in the timing diagram are interpreted as stable detent positions, then the encoding operation accords with my earlier description.

Anyway... that still doesn't mean that there might not be other parts which are (accurately or inaccurately) being marketed and sold as "KY-040", and which use a "return to HIGH" encoding scheme.

@urish
Copy link
Contributor

urish commented Mar 14, 2023

@urish
Copy link
Contributor

urish commented Mar 14, 2023

Just got the part, and it seems like it does toggle twice (high → low → high) for each detent movement:

ky-040-s.mp4

I guess you are getting different results with your encoder?

@ahmogit
Copy link
Author

ahmogit commented Mar 14, 2023

Interesting.

The part you show in your video does not appear to be the same part as shown in the advertisement URL that you posted. The board is clearly different (there is no "LB-link" notation) and the encoder itself also does not appear to be the same as the one shown in the ad photo. See attached annotated photo of the ad.

I've also attached the tag from the Taiss KY-040 parts that I got via Amazon. (I also have some from eBay, but there was no original packaging.) All of those parts behave as I described earlier, and verified in a very simple way using a multimeter to verify the contact resistances to GND and + for adjacent detent positions. If you insist, I will be glad to supply a video showing those measurements, but the test is so straightforward that it hardly seems worth the effort. And in any case, the behavior seen and described in my earlier posts is in full agreement with all the other documentation that I have come across for the KY-040, and provided in the links in the above postings. And my many projects using those parts would not work if the encoding behavior were other than what I described. The shaft encoding used in the parts that I have in my lab is unambiguously toggle-type behavior, not the return-to-HIGH that you show above.

Here's the Amazon ad for at least some of the KY-040's in my collection:

https://www.amazon.com/dp/B07F26CT6B?psc=1&ref=ppx_yo2ov_dt_b_product_details

The parts from eBay did not come in original packaging, but externally at least, they do appear to be mechanically identical to the ones from Amazon.
ad_photo_annotated
taiss_ky-040_upc_tag

@ahmogit
Copy link
Author

ahmogit commented Mar 14, 2023

Btw, how many detent positions does your part have?

@urish
Copy link
Contributor

urish commented Mar 14, 2023

Yes, the part indeed seems different from the one in the picture. It has 20 detent positions. It may be the part from this tutorial, as the plastic color matches and also the number of detents:

image

It seems to me like there as if are two different models out there - one with 30 detent positions, which does not return-to-high, and another one with 20 detent positions which returns to high.

@ahmogit
Copy link
Author

ahmogit commented Mar 15, 2023

There's no question or debate that various manufacturers produce various mechanical encoders of similar appearance, having differing encoding schemes and resolutions, and certainly not limited to 20 or 30 detents. But I seriously doubt that a manufacturer would designate a part as "KY-040" yet having two different encoding schemes for different resolutions.

It's my belief that the device you tested -- which may well be the blue encoder in the tutorial as you say -- is probably not a KY-040.

@drf5n
Copy link
Contributor

drf5n commented Sep 22, 2024

I like the full-quadrature-cycle-per-detent behavior in Wokwi:
https://wokwi.com/projects/409742532877688833

It matches the behavior of my bare no-breakout board blue encoder with its open circuits at the detents, and the encoders I have on breakout boards with VCC pullup resistors on the signal lines making HIGH at the detents.

However, this datasheet says their KY-040 alternates between both signals resting at HIGH and LOW with alternate detents:

If both switches are closed, turning the encoder either clockwise or counterclockwise one
position will cause both switches to open
If both switches are open, turning the encoder either clockwise or counterclockwise one
position will cause both switches to close.

I don't think you can rely on drop-in compatibility of the cheap and popular KY-040 encoder switches. There's probably more than two models, and based on Urish's disassembly photo, they only need differ by the pattern of tabs on the disk in the RHS.

Here's a datasheet for ALPS EC11 encoders that the KY-040 module is likely built from:

https://www.farnell.com/datasheets/1837001.pdf

@ahmogit
Copy link
Author

ahmogit commented Sep 23, 2024

Imo, the confusion here probably results from various secondary market parts-sellers uncritically using the designation "KY-040" to describe any of these small inexpensive mechanical encoders.

It is still my belief that the "real" KY-040, as originally produced by Keyes electronics, has only one encoding mode, which is the half-quadrature mode, regardless of the number of detent positions. (They made several models having different numbers of detent positions.)

My guess is that the full-quadrature-per-detent encoders are not really KY-040 parts, even though they are frequently marketed as such on Amazon, eBay, etc.

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

No branches or pull requests

3 participants