Debouncing a mechanical rotary encoder

As an active member of the Arduino user community, I felt I should keep up with my library updates. So after some planning and “careful” coding, I’ve added a new digital rotary encoder class to my phi_interfaces library. The phi_interfaces library includes buttons, rotary encoders, analog buttons, joysticks, matrix keypads, serial ports, etc. as input devices and one can use getKey() to sense any of them.

https://liudr.wordpress.com/libraries/phi_interfaces/

The original rotary encoder class already works well. This addition expands the scope, supporting both normally open and normally closed encoders, and also supporting encoders that have twice the detents as they have complete pulses (have some hardware but haven’t tested yet). Also, this addition paves the way of an analog encoder class that will help people using nano/ATMEGA328P-AU save two pins, which has two analog-only pins with no digital functions.

Along the way I met some difficulties that I thought was useful to share. Although it stems from library development, the nature of the problem is actually misunderstanding of hardware.

Hardware I used: Bourns PEC11 series 18 pulses/rev. encoder with 18 detents./rev. (no obsolete, replaced by PEC11R)

So here is what I discovered: the mechanical rotary encoder that I have has a delay between channel A closing and channel B closing about 14 ms, then delay between channel A opening and channel B opening about 8 ms. Not only is opening asymmetric with closing, but they are also faster than my expectation. I started programming the new class expecting to debounce the encoder. I first used 20ms for debouncing, like what I do for tactile switches. That didn’t yield good results. I thought I need longer time, 50 ms, not good, or about the same, only 1/3 detents got detected. I then tried shorter debouncing like 10 ms and still few detents got detected. Running the original rotary encoder code I developed initially, without debouncing, was find, with every detent registered. So I checked the encoder with a logic analyzer. Wow the action was faster than I expected, 14ms and 8 ms. I also looked at the bouncing of the contacts. It was around 0.5 ms after initial contact was made, many bouncing occurred. So if I’m using millis() to debounce, I’d rather not debounce at all.

Here is one part of the pulse when channel A closes then channel B closes, about 14 ms:

Here is another part of the pulse when channel A opens then channel B closes, about 8 ms:

Here is a typical bouncing of the contacts, in the order of 0.5 ms:

An afterthought, I read the spec sheet, which says at 15RPM, close to how fast I was turning the shaft, bouncing is 5ms max. I’ve seen bouncing around that length in time. If I read the spec sheet, I’ve probably avoided the whole learning experience smiley

Here is diagram showing symmetric pulses on the spec sheet:

So, take the spec sheet with a grain of salt.

BTW, I’ve recently designed a system that uses one analog pin to sense a mechanical rotary encoder. The purpose was to save pins. The ATMEGA328P-AU has two analog pins that have no digital functions. Why wasting them if I can hook a rotary encoder to one of them?

phi_prompt 1.0 beta release

I am happy to release the beta version of the phi_prompt library. There are sample codes to get you started while I work on adding a few functions for beginner programmers and finishing the documentation. Except for the init function, everything is the same as the 523 version. Now it’s compatible with arduino 1.0 and uses phi_interfaces library as the physical layer for inputs.

Library download includes phi_prompt, phi_interfaces, sample codes, and modified TinyGPS (by Mike Hart) to run on arduino 1.0:

http://code.google.com/p/phi-prompt-user-interface-library/downloads/detail?name=libraries.zip&can=2&q=#makechanges

GPS logger program version 5 is also available if you have a phi-2 shield 2004 and a GPS module:

http://code.google.com/p/phi-prompt-user-interface-library/downloads/detail?name=Phi_2_project_gps_logger_v5.zip&can=2&q=#makechanges

Phi_prompt is upgrading to arduino 1.0

After some tireless work, my phi_prompt user interface library is upgraded to arduino 1.0 and takes full advantage of phi_interfaces library as physical layer to sense key presses. I was able to revamp my sample codes without much change at all. All call conventions are kept the same. Most change you will need as a project developer with phi_prompt is to include phi_interfaces library instead of the phi_buttons library, and set up keypads to pass to phi_prompt initialization call. An added perk is that in each sample code, I defined two input keypads, i.e. an actual keypad on arduino and a serial keypad either I can use a PC serial terminal or a bluetooth phone. I can operate the menu or any function on my arduino’s buttons, by typing in characters on my PC serial terminal, or with my bluetooth phone (adding a bluetooth shield to arduino of course). It’s super cool. You develop one interface, say a menu system, then you can interact with the menu with local buttons (on arduino), or remotely without any more coding.

Here is a depiction of what you could be doing with this new system:

%d bloggers like this: