PIC16F630 de-bouncer

27 April 2018
This is a small circuit that provides six active-high buttons that are de-bounced. I built it as I was testing out an integrated circuit that seemed particularly sensitive to electrical contact bouncing, and for some time I had been considering building a board that provided an array of buttons complete with pull-downs to avoid floating voltages. It is based around a PIC16F630, using a method of de-bouncing that was used in a past circuit.

From the outset I decided that the input pins should all be on one side of the chip, and for each input pin the corresponding de-bounced output should be directly opposite on the other side of the chip. This simplifies the chip from a hardware component perspective, but does cause complications because the input and output pins are split between the two ports.

Internal vs. external pulling resistors

The PIC16F630 microcontroller has programmatically-enabled internal pull-up resistors, which I have taken advantage of in previous circuits, but since they are only available on PORTA and not PORTC I disabled them and used external pull-down resistors. Adding pull-down resistors to all the pins removes a factor — namely whether an input already has an internal pulling resistor — that needs to be kept track of, and in any case my preference is for active-high rather than active-low.

De-bouncing firmware

The entire source code for the firmware is on Bitbucket. Using Timer0 each input pin is sampled every 0.128ms, and if the last samples are the same — either high or low — the corresponding pin is updated to high or low as appropriate. The input and output pins are not in a convenient order, so the code is a somewhat bulky if-then-else chain rather than a concise calculation, and I suspect that in this case looping over arrays rather than manually unrolling the loop actually increases the size of the compiled code. I possibly could have used lookup tables, but I think doing so involves EEPROM reads, the efficiency of which I have not looked into. In any case the firmware is “fast enough”.

One issue that came up with the firmware was the sampling delay. The PIC16F630 chip has a 4MHz clock, so FOSC/4 should be 1MHz, and prescaling this 1:128 should result in a period of 0.128ms — with 8 samples being taken this means a button press needs to last about 1ms to be registered as valid. However I noticed that “short” button presses were getting suppressed, which was solved by reducing the Timer0 prescale to 1:32. From past experience the only cases where the expected delay of PIC timers, based on interpretation of the data-sheets, has matched wall time has been with projects such as the 8-segment LCD timer where an external timing crystal has been used.

Concluding remarks

Ever since I got hold of these small perfboard prototyping boards (Farnell 2768276) I have made quite a few mini-circuits. The constraints of the board mean that any circuit will take at most maybe 2-3 hours to complete, in contrast to things like the 17-segment LCD display which took a week or so the solder up. These days my interest is often in process — namely soldering is a hobby — rather than outcome, and there is an advantage to tight bounds. It also provides something to write about, which is a story in itself.