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.

http://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?

Arduino shield pins and ICSP header mismatched height

I have noticed that arduino official shields, such as wifi and wireless shields, have mismatched ISCP header height with male pins. Both point down, but the male pins are 2mm or 0.1″ longer.

My first picture below shows me holding a PCB over a MEGA, showing that the female headers and at the same height as the ICSP male header on arduino.

Arduino header

My second picture below shows three shields, from left to right, official wifi shield, official wireless shield, and a third-party Ethernet shield. As you can see, both official shields have male pins about  2mm or maybe 0.1″ longer than the female ICSP header so the female header is not touch the table top. On the other hand, the third-party shield have same height.

Shield header and pins

This may create loose connection issues when you press the shield against another shield with pass-thru ICSP headers, which are thin pins, not square pins found on arduino. The additional 0.1″ travel on the female header makes the connection so much more trust-worthy. I have some issues with some shields I designed and built with wifi shields. I don’t know if it was caused by this “feature”. From what I understand, all pins should make perfect contact, not some doing it while others have ways to go.
What is your opinion?

To remedy this, I made a tool, by pulling all the pins in a row of female header, indicated in the third picture. Then I slip it over the male headers, and I just have to trip the protruding portion of the male header in half, effectively removing about 2mm length.trimming tool-1

 

trimming tool-2

After trimming, there is no more concerns with the connections. I am yet to see the problematic units with the wifi shield shipped back to me so I can apply this modification to it. BTW, there is no clearance issue trimming the male pins, thus dropping the wifi shield 2mm lower towards what’s below it. There is nothing on an arduino or my shield that will come in contact with the bottom of the wifi board. So the 2mm lost of clearance really doesn’t hurt anything.

Format SD card for Arduino projects

Recently I had a project that needed to tally the free and used space on the SD card and display that on an LCD. I have been using the SDFAT library instead of the SD library. The SdFat library is the basis of the SD library, so it has more functionality than SD and works faster in many cases. In the SdFat library, there are functions that count free blocks on the SD card, which is how free space is figured out: free blocks * block size (512 bytes)

Here is the function:

unsigned int sd_free_space_MB(SdFat* sdfp)
{
uint32_t freeMB = sdfp->vol()->freeClusterCount();
freeMB *= sdfp->vol()->blocksPerCluster();
freeMB/=2048;
return freeMB;
}

The freeClusterCount counts number of clusters, and then multiply that with number of blocks per cluster and then divide by 2048 to factor out the 512 byte per block and 1,048,576 bytes per MB, i.e. blocks * 512 / 1,048,576 = blocks / 2,048.

This code ran so slow that it took 10 seconds on a 2GB SD card. I was appalled thinking that is how fast they go. I even wrote a message on the LCD “calculating free space” so the user won’t wonder what’s going on during the 10 second delay. But later I posted my code asking for help on the Arduino forum. fat16lib, the author of the library, helped me greatly. It turned out that my SD card was not formatted optimally. I should have formatted it with the formatter tool that fat16lib pointed out (many many posts ago on the forum):

https://www.sdcard.org/downloads/formatter_4/

After formatting, I only experienced a split second delay before Arduino counts all the blocks. I recommend you to format all your SD cards with this tool. Original Arduino posts are below:

http://forum.arduino.cc/index.php?topic=228128.msg1648437#msg1648437

http://forum.arduino.cc/index.php?topic=228201.msg1648655#msg1648655

Install Arduino on Windows 8

There are several issues that surround installing Arduino and compatible hardware on windows 8 machines. If you find it impossible to install your Arduino on a new win 8 machine, I hope this post helps you.

PC:

You will need to disable driver digital signature on your PC in order to install Arduino’s driver, which are in Arduino/drivers folder. In previous versions of windows, you simply choose to install on a red dialog that looks like this:

In windows 8, you don’t even get to this dialog. You need to manually disable driver digital signature in a very complicated way and restart your machine twice to do it.

The following tutorial describes how to disable driver digital signature. Make sure you have a second computer or tablet open the page, or print it on paper, because you will be restarting your PC and won’t have access to this page when you are in start screen.

http://www.howtogeek.com/167723/how-to-disable-driver-signature-verification-on-64-bit-windows-8.1-so-that-you-can-install-unsigned-drivers/

If your PC asks for your bitlock recovery key, follow the steps below under “Tablets”

Tablets:

Yes, we now have inexpensive win 8.1 tablets such as Dell Venue Pro 8 and Toshiba Encore etc. They cost $250 and occasionally are on sale for $200. But are they up for the Arduino tasks? Additional hurdles of course.

Many windows 8.1 tablets come with a drive with bitlocks. It is to prevent people from stealing your tablet and getting sensitive information from it. With the bitlock in place, your files are safe (#define safe //;)) even if you lose your tablet. On the other hand, to boot to advanced settings, windows needs you to enter the bitlock recovery key at boot time to verify you. It’s a long numerical code and here is a tutorial on how to get it from your tablet. I recommend printing the key on paper.

http://www.eightforums.com/tutorials/21818-bitlocker-recovery-key-back-up-windows-8-a.html

Once you are through entering the key, follow the same procedure as described in the tutorial to disable driver digital signatures, you are then allowed to install Arduino drivers. Congratulations!

 

How to use serial port pins as digital pins

If you are using Arduino MEGA 2560, you have 4 hardware serial ports (USART port to be precise). Not everyone needs to use all of them. You can, if you want, use Serial1,2,3 as regular digital pins, or GPIO (general purpose input and output). All you have to do is to call Serial1.end() before you set RX1 and TX1 with pinMode and digitalWrite/read.

What if you are in my situation: I have a few serial port sonic rangers. They have an enable pin that enables ranging if they are held high for over 20us. It also has a free running mode, with the enable pin internally pulled up. I was using the free running mode until some interference between two rangers were discovered. Now with my shield already designed and a few dozens in service, I need a way to retrofit them to work with a screw terminal block. Arduino header and jumper is not the solution when these units are deployed in the field. Fortunately I routed both TX and RX to the board’s edge and I can solder on some 2-pin block. But I still need RX to function so I can’t call Serial1.end().

This would need some register operation. If you are interested in the whole detail, the doc2549 from atmel has everything in chapter 22 (USART). There are example codes on P211. It’s pretty clear that the Transmit only functions when the TXEN1 bit of the UCSR1B register is set. The following is from that chapter:

 

The USART Transmitter is enabled by setting the Transmit Enable (TXEN) bit in the UCSRnB

Register. When the Transmitter is enabled, the normal port operation of the TxDn pin is overridden

by the USART and given the function as the Transmitter’s serial output. The baud rate,

mode of operation and frame format must be set up once before doing any transmissions. If synchronous

operation is used, the clock on the XCKn pin will be overridden and used as

transmission clock.

 

So all we need to do to get the GPIO function back is to reset that TXEN1 bit as such: cbi(UCSR1B,TXEN1);

I tested this and it worked. I was able to drive the sonic ranger with the TX1 pin and still receive data on the RX1 pin.

Don’t buy these if you have win 8

I recently purchased an Arduino Nano clone from ebay. Around the same time, I was also upgrading from vista to win 8 so I got a new laptop and tablet to replace my 5-yr old vista laptop. I plugged the Nano clone in my win 8 laptop and it didn’t work. The serial port showed up with an exclamation mark on the device manager with the following error message:

This device cannot start. (Code 10)

A device which does not exist was specified

I thought maybe the board was broken. But after using it successfully on a win 7 machine, I was sure it’s working. Then I started doing some research online to find out the cause of the problem and ended up on this page:

http://prolificusa.com/pl-2303hx-drivers/

Wow, let’s back it up! The original Arduino Nano design is supposed to have an FTDI chip instead of a PL2303 chip, right? Yes, according to Arduino website:

http://arduino.cc/en/Main/ArduinoBoardNano

But, this is a clone, not exactly clone but a cheaper version with PL2303 chip. The problem of this chip is that there is NO windows 8 driver. The manufacturer says clearly they don’t have a driver. So far I have found no way to use it on my win 8 machine, so stay away if you just upgraded to win 8, or be careful to ask the ebay seller what chip is on the board. Some sellers say they have FTDI chip, which, after a hurdle, will run on win 8, tested:

Arduino Duemillanove, Sparkfun xbee explorer, and other FTDI chip based TTL USB adapters.

 

 

 

EAGLE library for 16X2 and 20X4 LCDs

These are the parts that I have used for quite some time for all circuit boards I designed that have LCDs. Free for the grab but please check the dimension of your LCD before using them as some suppliers have smaller/larger mounting holes and not all LCDs have the holes at the same locations. Some parts have only 3 mounting holes since the bottom right corner of the LCD would be right above the GPS connector on phi-2 shields. The 16X2 LCD with connectors on bottom left have been used for some projects too.

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

Follow

Get every new post delivered to your Inbox.

Join 48 other followers

%d bloggers like this: