Problem: Double counts with KY040 rotary encoder using Nick Gammon’s “Microprocessors: Rotary encoders and interrupts”
The KY040 encoder with Uno, IDE 1.6.5, used with Nick Gammon’s “Rotary encoder example, #1 (May 2011)” or “Reading 4 encoders using pin-change interrupts, #2 (Dec 2016)” almost always causes two counts for each detent, either CW or CCW. The KY040 is wired to Gnd, +5V, SW (push button switch not connected), DT to pin A, CLK to pin B. Switching pins A and B just makes the counting reversed. Adding 0.1 uf caps for debouncing does not help and may make the counts more erratic.
It seems that the code might be triggering on both rising and falling conditions, but I do not understand where the triggering is occurring for the ISR.
Can someone explain why two counts are being registered for this code, and what might be done to limit the count to one per detent? Is this problem specific to the KY040 encoder? That explanation might help me better understand encoder interrupts.
Thanks, Lowell
Switch bounce. As a forum search easily shows, In addition to the caps, you need a resistor.
How many quadrature transititons per detent click are there in your encoder? Some encoders have a detent at every tranisiton, others have two transitions per detent and yet others others have four.
A Pin Change Interrupt occurs on every change of a pin, i.e. on both low-to-high and high-to-low transitions. You can ignore one of these transitions in the ISR code. Or you use only count/2 as the encoder value in further code.
Thanks for the replies. I think DrDiettrich might have identified the problem. It seems that the KY040 (which has resistors on the DT and CLK pins to +V) sends two transitions for each detent, which might be making this particular code call the ISR twice and count twice per detent. I am still working through it. With other code that uses attachInterrupt(), this double counting generally does not occur.
Lowell
If you get it working correctly with two counts/click, as proposed above, just divide counts by two.
I've written a ky040 library that works pretty well. It's interrupt driven with debounce caps.
See GitHub - Billwilliams1952/KY-040-Encoder-Library---Arduino: Arduino library for the KY-040 Encoder