Skip to main content

How to connect a rotary encoder to Arduino, make your own PCB board, and be happy

After I discovered the OpenStage project for cheap DIY microscopy stage automation, I decided to add a twist to it - control the stage positions manually with a rotary encoder, in addition to already-implemented serial port (USB).

I found a nice RGB illuminated rotary encoder from Sparkfun  - it's shaft works as a button, and it is internally illuminated by built-in 3-color LEDs - a perfect device to switch speeds and manually control the stages.

Hooking it up to Arduino seemed easy, and there is a very nice Encoder library to do just that. But when I started to test it, I fell into a deep rabbit hole called 'debouncing'. In short, real-world switches are never perfect and the 'moment' of switching has many messy things happening between the two leads, creating noise in the logic of reading device (Arduino). So, the voltage readout from a real rotary encoder looks like this:

Note the high-frequency chirp in yellow line when it falls from high to low. The yellow and cyan lines are voltages at the two output leads of the encoder. The time interval on a grid is 5 ms, so things happen really fast here.

This chirp is called bouncing and needs, well, debouncing, either in hardware or in Arduino code. BTW, all push-buttons and mechanical switches also require debouncing for stable operation. Software debouncing is a simpler option, but this slows down the processor, which could be doing something more interesting then filtering out noise from encoders and buttons.

The hardware debouncing consists of a simple (RC) circuit, essentially a resistor and a capacitor, which works as a low-pass filter.

I changed the capacitor value to 0.1 uF, so that decay time constant RC = 10e+3 [Ohm] * 0.1e-6 [F] = 1e-3 sec, or 1 ms. With this circuit, the voltage readout from the rotary encoder looks much smoother:

The decay time of the debouncer circuit is 1 ms, as mentioned.

Now, 4 resistors and 2 capacitors add quite a mess to the breadboard, which becomes worse when you add 1 more capacitor + resistor to debounce the knob action of rotary encoder, and 3 more resistors to control the R,G,B LEDs. This whole mess just to filter the signals of a rotary encoder.

To my surprise and dismay, I could not buy a simple debouncing board in the Internet that would contain this circuit on a compact footprint. So I learned the Fritzing software and designed the missing PCB board myself. I then ordered it at AISLER, and 8 days later I had my PCB boards delivered, for only 4 eur a piece.

This filled me with deep satisfaction and accomplishment :-) If you are a DIY geek and have not printed your own PCB board yet - try it, this can make you happy and proud.

Making your own PCB is also a good way to document, pack and store a project for later use.

Source files

The github page contains all PCB design files (in Fritzing) and Arduino code examples.


PCB can be ordered from Aisler in two sizes:
normal (30x50 mm),
small SMD variant (30x35 mm).


Popular posts from this blog

Programming NI DAQmx board in Python: easier than you think!

For my DIY microscope I had a task - generate a train of digital pulses which simulate camera trigger, so that other devices (galvo and laser) are synched. I wanted to do it in Python, so that it seamlessly integrates in my data acquisition and analysis Jupyter notebook.

After some quick search I found a PyDAQmx library which seemed mature and had good examples to begin with.

Installation was smooth: download, unzip, open Anaconda prompt,
python install

After only 30 min fiddling, I was able to solve my problem in just a few lines of code:

Holy crap, it just works, out of the box. Oscilloscope shows nice digital pulses every 100 ms, each 1 ms long. The code is much shorter and cleaner than would be in C, C#, or LabView.

PyDAQmx appears to be a full-power wrapper around native NI DAQmx drivers (yes, they need to be installed), so presumably it can do all that can be done in C or even LabView (this statement needs to be tested).

One can use PyDAQmx to control galvos with fast ana…

Programming of DIY microscopes: MicroManager vs LabVIEW

In the flourishing field of DIY light microscopy, a decision of choosing the programming language to control the microscope is critically important. Modern microscopes are becoming increasingly intelligent. They orchestrate multiple devices (lasers, cameras, shutters, pockel cells) with ever increasing temporal precision, collect data semi-automatically following user-defined scenarios, adjust focus and illumination to follow the motion (or development) of a living organism.
So, the programming language must seamlessly communicate with hardware, allow devices be easily added or removed, have rich libraries for device drivers and image processing, and allow coding of good-looking and smooth GUIs for end users. This is a long list of requirements! So, what are the  options for DIY microscope programming?

There are currently two large schools of microscope programming - Labviewers and Micromanagers. (update: Matlab for microscope control also has a strong community, comparable to labview…

Shack-Hartmann sensor resolution - how much is good?

If you are new to adaptive optics (AO) like me, the selection of right hardware can be daunting. Starting with a wavefront sensor - they range in price, resolution, and many options which are not obvious. By practical trial and error I learned something about resolution, which wasn't obvious to me a year ago.

The Shack-Hartmann wavefront sensor (WFS) is essentially a camera with a lenslet array instead of an objective.
 There are sensors with 15x15 lenses, 30x30 and higher. Naively, you might think "the more the better" - we are digital age kids used to get high-res for cheap.

However, there is a catch. High-res sensor, say, 30x30 lenslets, divides your photon count by 900 per spot. Roughly speaking, when you image a fluorescent bead (or another point source) by a camera with "normal lens" (not a lenslet array), and your peak intensity is 2000, this makes a very nice, high SNR bead image. However, is you switch to Fourier (pupil) plane and image the wavefront u…