Projects Research & Design Hub

Customizable Capacitance Touch Sensing

Written by Nick Boers

You can add capacitance touch sensing to a wide variety of electronic systems. Nick explains how he designed a touch sensitive holiday decoration with multiple programmable and randomized states whose random number generator is seeded by the recipient’s name.

  • How to he design a touch sensitive holiday decoration with multiple programmable and randomized states.

  • Choosing the components

  • How to program the Microstick with the test cod

  • How to do the PCB layout

  • How to use the batteries and LEDs

  • Microchip Technology’s Microstick II Starter kit

  • Microchip’s PIC24F16KA102 microcontroller

  • KiCad PCB tools

  • 32 0805 size LEDs

  • CR2032 coin cell batteries

My family has a long history of hand-made Christmas tree decorations, making snowflakes with colored beads and snowmen from clay when we were children. Although it had been a long time since we all moved out, my brother revived this tradition two years ago with his own twist by making Christmas decorations for everyone using his favorite medium, LEGO. I decided pretty quickly that it would be a fun little project to make some custom electronic decorations. I wanted it to be touch sensitive, but I had never done touch sensing before. There were several other issues to be worked out as well, but I had some time. It’d be no problem, right?

Time flies, and before I knew it, it was holiday season again. I had to work quickly. I had done some Microchip Technology PIC microcontroller projects on breadboards and perf boards through the year, and even made a few on real PCBs. I knew how long it would take to get finished PCBs back. I had an idea how long it would take to design the board, and I could work on the code while the boards were being made. The biggest question was the touch sensing. I had to show myself I could do that or it would be a nonstarter.


I ordered a Microchip Technology PIC24F16KA102 to try out the touch sensing. I used a PIC because I have experience with PICs and Microchip’s MPLABX development environment. I chose the PIC24F16KA102 specifically because I wanted the low-power sleep mode offered by their XLP technology. It has a charge time measurement unit (CTMU), which from my limited research indicted that it would make the touch sensing pretty easy. Furthermore, it was available in both SMD and a DIP package to fit the Microstick II starter kit board I had. This way I could do my testing and code development without needing the final board or having to solder something together.


Delivery exception: The package with the PIC missed a transfer somewhere, so I didn’t have a device to test. As a result, I focused on preparing some code to do a test with the CTMU when it did show up.

The CTMU is an analog peripheral in some PIC devices that contains a programmable current source that can be connected to any of the analog input pins. The current source can be turned on and off using various trigger sources. A constant current applied to a fixed capacitor for a fixed time will charge the capacitor to the same voltage every time. A touch-sensing pad connected to the PIC is a capacitor, and its capacitance will change when a finger gets close or touches it. When the capacitance changes, the resulting voltage after charging it with the fixed current will also change. It’s that change in capacitor voltage that will count as a touch. For a repeatable measurement, the pin is set to a low output for a short time to ensure the pad voltage is 0 before applying the charging current. The pin is then switched back to an input and the CTMU current source turned on. After a fixed delay, the current source is turned off, and the voltage is read using the ADC module. Then you just need to compare the voltage reading to a detection threshold to decide if the sensor has been touched.

My final sensing routine from my test code using the CTMU is shown in Listing 1. It is derived from Microchip application note titled “Microchip CTMU for Capacitive Touch Applications” (AN1250). Some of the examples I found were calculating the threshold using an average of the last number of readings, but as a simple proof that this would work I decided a fixed threshold that I could adjust would work fine. There will be time to refine the code when boards are being made.

Listing 1
Test code for charge time measurement unit (CTMU)

while(1) {

    AD1PCFG = 0xffff;           // set all ADC pins to digital
    TRISB = 0;

    LATB = PORTB && 0XFFF7;     // drain charge from input pin
    TRISB = 0x0008;             // set touch pad to input
    AD1PCFG = 0xFFDF;           // set touch pad to ADC input
    AD1CHS = 0x0505;            // select ADC channel
    CTMUCONbits.IDISSEN = 1;    // drain charge on ADC
    CTMUCONbits.IDISSEN = 0;
    IFS0bits.AD1IF = 0;         // clear ADC interrupt flag
    AD1CON1bits.SAMP = 1;       // manual sampling
    CTMUCONbits.EDG2STAT = 0;
    CTMUCONbits.EDG1STAT = 1;   // start charging pin
    Nop(); Nop(); Nop(); Nop();	// wait a while
    Nop(); Nop(); Nop(); Nop();
    CTMUCONbits.EDG1STAT = 0;   // stop charging pin
    IFS0bits.AD1IF = 0;
    AD1CON1bits.SAMP = 0;       // start ADC conversion
    while(!IFS0bits.AD1IF);     // wait for conversion
    IFS0bits.AD1IF = 0;         // clear ADC interrupt flag
    AD1CON1bits.DONE = 0;       // clear ADC bits

    if (ADC1BUF0 < 0x0180){     // compare reading to thresold
        LATA = 0x01;            // turn LED on if below threshold
    else {
        LATA = 0x00;            // turn LED off if above threshold

Once the PIC arrived, I plug it into the Microstick and programmed it with the test code. I used a piece of metal from some cut tape crimp connectors as my touch sensor. It didn’t respond to touch at all. I connected my oscilloscope to the sensing pin to see what it was doing. The test setup featured the Microstick II and the cut tape test sensor. With the scope connected, I could see the pin very quickly charged right up to the 3.3-V supply. It was getting too much current, and maybe for too long. I removed some of the nop() instructions being used as delays and reduced the charge current using the CTMU control registers. It worked. Photo 1 shows the sensing pin charging to about 3 V, a little below the battery voltage. Photo 2 shows the response to a light touch to the metal strip I was using as the sensor pad. With a little tweaking of the threshold value, I had it detecting a touch through a sheet of paper. It was good enough. I started on the schematic.

I use KiCad for designing my PCBs. It’s free, runs on multiple operating systems, has lots of features and flexibility, and it doesn’t tie me down to a specific PCB vendor. Refer to the simple circuitry in Figure 1. The PIC24F16KA102 runs from a CR2032 coin cell, with 32 LEDs arranged in 16 paralleled pairs. One of each LED pair will go on the front of the PCB, the other on the back.

Figure 1 Schematic of PCB for decoration
Figure 1
Schematic of PCB for decoration

When I started the PCB layout (see Photo 3), I decided on 0805 size LEDs and resistors since they were the smallest I felt I could mount thousands of in a short time without frustration. I decided on a TSSOP package for the PIC for the small size. I’ve gotten pretty good at hand soldering 144-pin TQFPs, so I figured I’d go with the smaller TSSOP even though it’d take me an extra minute or two over an SOIC. It was about the time I was making that decision that I started to realize the scope of the assembly phase of this project. I would be hand mounting roughly 3,000 SMD parts. Ignoring the microcontroller for now, and assuming about 10 s per part, I’d be spending 10 seconds × 3,000 parts, divided by 3,600 seconds per hour, about 8.3 h just soldering resistors, capacitors, and LEDs. Ouch!

Photo 3 The finished project If I try something like this in the futre, I’ll be sure to give myself more time.
Photo 3
The finished project If I try something like this in the futre, I’ll be sure to give myself more time.

The TSSOP had to go. Some friends and family had heard of this project and thought it would be interesting to try soldering one themselves. Some of them had some soldering experience, but the fine-pitch TSSOP was out of the question. I decided to replace it with an SO and had to modify a bunch of the layout. The touch sensing pad was created with a wide circular trace around the edge on both sides of the board.

Once the electrical layout was done, I added some decoration in the form of silkscreen stars on the top side. The bottom side would not have a silk screen because of my choice in vendor and price point, so I made the stars using unmasked copper so they would end up as shiny hot air levelled solder.

The final design is shown in Photo 3. Happy with the design and nearing the start of the Chinese board shop’s Saturday morning opening, I sent off the files and went out to do some Christmas shopping. I soon realized that I had completely forgotten the reset circuit that should be connected to the *MCLR pin. I rushed home, made my changes and got the new files out before the shop had started. Just in time. The boards would show up in a week. Next I needed to choose my LEDs and resistor values.


I had to select my parts. I’d never done a project powered by a coin cell before. It turns out LEDs use a lot of current when you’re using a coin cell for power. Normally, I’ll run an LED at a few millamps, but looking at two different datasheets for a CR2032 I could see I needed to keep the total maximum current down near 3 mA. I wanted to be able to turn all of the LEDs on some of the time, but I didn’t know how bright an LED would be at 100 µA. LED brightness is typically specified in the 5 to 20 mA range, so I didn’t feel I could rely on the published values. I wanted good brightness, but with 1,500 LEDs to order, I also wanted cheap. I had to do some tests. I ordered a selection of different color LEDs from different manufacturers. Unfortunately, blue wasn’t an option because the forward voltage drop was greater than the 3-V supply, so I was left with red yellow and green.


I choose my LEDs. I measured the amount of current supplied by my multimeter when in diode check mode and found it to be 200 µA. Close enough for the first test. I visually compared the brightness of the different LEDs using the multimeter as a current source. The reds and yellows were all visually no different. The greens were noticeably dimmer. Test two was with a coin cell and some 10- and 5-kΩ resistors. Note that 10 kΩ on the red and yellows drew about 100 µA, as expected. Furthermore, 5 kΩ on the green drew almost 200 µA, but it was then about as bright as the reds and yellows. I’ll just have to be careful to not use too many green LEDs on any given board to keep the current from getting too high.


Parts showed up, but the boards didn’t, so I had to work on the code I should have finished early in the week. The program runs as a simple state machine inside a single loop. The final main loop is shown in Listing 2. The touch sensor is checked, and increments the state if it detects a touch. Each state contains a different flashing sequence. State one selects one random LED channel to be lit on each pass through the loop. This uses the lowest power. Two LEDs at 100 µA each and the microcontroller in deep sleep at 25 µA should run for about 1,000 hours (five weeks) on the 225 mA hours of energy in the battery.

Listing 2
Main loop of the decoration project

while(1) {  
    if (checkTouch() < 0x0180){		// Check for a touch
        LATB = 0xffff;                  // Turn on everything...
        LATA = 0xff;                    // ...including the LEDs on PORT A
        state = state +1;               // Increment the main state
        subState = 0;                   // Reset the sub state to zero
        output = 0;                     // Clear the LED buffer
        if (state > maxState){state =0;}// Loop back to state 0
        timer = 2400;                   // Reset the low power timeout
        if (state == 0){		// Sleep state, one random LED every few cycles
            if (!subState){
                output = (0x1 << (rand()&0xF));
                subState = 5;		// Delay counter for sleep mode so it moves slowly
            subState = subState - 1;
        else if (state == 1){output = rand();}  	// Random number generator

        else if (state == 2){                   // Android inspired busy clock
            if (subState){output = (output << 1) & 0xFEFE;}
            else{output = (output << 1) | 0x0101;}
            if (output == 0){subState = 0;}
            else if (output == 0xFFFF){subState = 1;}

        else if (state == 3){		// “Windmill” inspired by Mike and Tanyas gift to Natalya
            if (!subState){		// Initialize windmill
                output = 0x1111;
                subState = 1;
            output = output << 1;	// Rotate!!
            if (!(output & 0xF)){output = output | 0x1;}   // Insert the next bit when it’s been rotated out

        else if (state == 4){output = output ^ (0x1 << (rand()&0xF));}  // Switch state of randomly selected LED

        LATB = output;      		// Output to the LEDs...
        LATA = output;      		// ...including those on Port A
        timer = timer -1;   		// count down to low power mode

    if (!timer){
        state = 0;          // Set to low power mode if no touch for some period of time
        subState = 0;

    ClrWdt();               // Set the watchdog timer to wake from sleep
    Sleep();                // Go to sleep

There are a few states that use a fixed sequence, and some that use random numbers. After updating the state machine, the watchdog timer is enabled to wake the microcontroller, and it is put to deep sleep to wait for the next loop. A counter gets set during a touch event, and counts down with each pass through the loop. This is used to reset the state machine to the low-power state when it has not been touched for a period of time. To provide some personalization, and uniqueness in each decoration the random number generator is seeded at startup with a simple hash of the name of the person it will be given to.


Assembly began when the boards arrived. The first few took 15 minutes each. I had parts for 40, so I had roughly 10 hours of assembling. It was OK. Day by day, I made progress, and boards were built with different combinations of LEDs. Some were all one color or one color per side, some had different patterns, and some were completely random. Combined with the random number generator seed, every decoration was unique.


I finished the last boards just in time to go visit family for dinner (see Photo 4). The kids liked the blinking lights, the artists liked the concept, and the retired bank programmer who learned on punch cards had a lot of questions about how that one little chip could do all those things. In the end, I was pretty satisfied with how the project turned out in such a short time. I got it done (barely) in time, I learned a few things about touch sensing and sleep modes, and a couple friends did a pretty good job on their first surface-mount soldering. 

Photo 4  Two of the assembled decorations hanging on our tree. Random colors for me, and all green for someone that I know who really likes green.
Photo 4
Two of the assembled decorations hanging on our tree. Random colors for me, and all green for someone that I know who really likes green.

B. Bohn, “Microchip CTMU for Capacitive Touch Applications,” AN1250, Microchip Technology, 2009,

Microstick II Starter kit and PIC24F16KA102 microcontroller
Microchip Technology |


Keep up-to-date with our FREE Weekly Newsletter!

Don't miss out on upcoming issues of Circuit Cellar.

Note: We’ve made the Dec 2022 issue of Circuit Cellar available as a free sample issue. In it, you’ll find a rich variety of the kinds of articles and information that exemplify a typical issue of the current magazine.

Would you like to write for Circuit Cellar? We are always accepting articles/posts from the technical community. Get in touch with us and let's discuss your ideas.

Sponsor this Article

Supporting Companies

Upcoming Events

Copyright © KCK Media Corp.
All Rights Reserved

Copyright © 2024 KCK Media Corp.

Customizable Capacitance Touch Sensing

by Nick Boers time to read: 11 min