Home     Contact     Projects     Experiments     Circuits     Theory     BLOG     PIC Tutorials     Time for Science     RSS     Terms of services     Privacy policy  
 Home      Projects     Experiments     Circuits     Theory     BLOG     PIC Tutorials     Time for Science   

7 February 2011
Author: Giorgos Lazaridis
PIC Capacitance Sensor with 4 buttons and Multitouch Function

The Tmr1

The Timer1 is a 16-bit counter, and is used to measure the frequency. The Tmr1H and Tmr1L registers (each one 8 bits, both make the Tmr1H:Tmr1L 16 bit register), are increased by the capacitance sensor module. This means, that the rate of increment depends on the frequency of the capacitance module, which eventually depends on the capacitance of the electrode. Larger capacitance (if for example the electrode is touched), means lower frequency which means slower rate of change for the Tmr1 counter. Here is the setup code:

	movlw b'11000100'	; Setup TMR1 module Control register
	movwf T1CON		; Bits <7:6>: Timer 1 source is Capacitive Sensing Oscillator
				; Bits <5:4>: Prescaller is 1:1
				; Bit 3: LP oscillatos is deactivated
				; Bit 2: No synchronization
				; Bit 0: Timer 1 is stopped

The T1Con register is responsible for the operation of Timer1. In bits 7 and 6 i set the capacitance module as the pulse source for the counter. Then, i set the prescaller to 1:1, which means that no further division will be performed. The LP oscillator is not needed so i turn it off, and also i do not want synchronization. Then, i keep the Timer 1 module stopped for a while. I turn it on after a few more lines of code. The following drawing is from the datasheet of the PIC16F1937. The red route shows how the pulses are delivered from the capacitance module to the Tmr1 registers. The portion on top of this drawing is the gate for the tmr1, so i have fade-it out. I will explain this later.

Everything is pretty straight forward. Let's go to something little bit more stiffer.

The Tmr1 Gate

Look at the drawing above, which illustrates the Tmr1 module. Notice that before the Tmr1H:Tmr1L registers, there is a gating module. The output Q of it, is connected to the Tmr1 registers, at the D input the pulses from the capacitance module arrive, and there is also another input, the "EN" from the word "Enabled". This is the gate of the Tmr1. As long as the "Enabled" input is kept high, the pulses normally arrive to the 16-bit counter. But if the "Enabled" is low, no matter what, the pulses will NOT increase the 16-bit registers. This is one feature that i will use to measure the frequency. And here is the portion of the code in which i set the gate module:

	movlw b'11100001'	; Setup Timer 1 Gate module
	movwf T1GCON		; Bit 7: Gate controls the counting function of TMR1
				; Bit 6: Gate polarity is Active HIGH
				; Bit 5: Gate input is through Toggle FF
				; Bits <4:3>: No single pulse mode
				; Bits <1:0>: Gate source is Timer0 overflow

The T1Gcon is the responsible register for the Tmr1 Gate control. First of all, i enable the gate by setting bit 7, otherwise the gate would have no affect. Then i set the polarity of the gate to active-high. This means that the Gate will be activated on a Low to High pulse, which is exactly what we want, as the Tmr0 overflow sends such a pulse upon overflow. Then i enable the toggle flip flop and disable the Single pulse mode. What this means is that, the gate output will toggle upon each Timer0 overflow. If you do not clearly understand this, don't worry. I explain it later. Finally, i set the gate input to arrive from the Tmr0 overflow, which is the time base. Here is the route of the Gate:

Now, let's see an example of the above setup. Suppose that the Tmr1H:Tmr1L registers are cleared, as well as the Tmr0 register is cleared. And also, suppose that the toggle FF output of the gate is HIGH, which means that the pulses will indeed arrive to the Tmr1 count. From this point, the operation begins. The pulses from the capacitance module are delivered to the Tmr1 16 bit counter, which is increased accordingly. Simultaneously, the pulses from the internal oscillator are delivered to Tmr0 register through he prescaller. Then, after a while (very short while), the Tmr0 register overflows from 0xFF to 0x00. When this occurs, a pulse will be delivered from the Tmr0 module to the Tmr1 Gate input. This pulse will toggle the flip flop, and its output will become LOW. Eventually, the "Enabled" input of the Gate module right before the Tmr1 16 bit register will also become LOW, and no further pulses will be delivered to the Tmr1 registers. This means that the count will stop!

But the Tmr0 overflow will also cause an interrupt, the Tmr0 interrupt. So, the program counter will go to 0x04 origin, where the Interrupt Service Routine is located. During this routine, the Tmr1 16-bit value is acquired and compared with a Press and Release threshold level, to determine if the electrode is pressed or released. I will not go into details for this procedure, first because the code is well documented to understand it, and second because you can read another article that i wrote, in which i explain how this works. You can find this article here - PIC Frequency-Change Capacitance Touch Button.

Now lets see what happens when the ISR ends. First, we need to clear the Tmr0 and Tmr1 registers to be ready for the next cycle. But the toggle flip flop of the Tmr1 gate is now LOW, which means that no pulses will arrive to the Tmr1. As there is no immediate way to set the FF again, i do this trick. I put the value 0xFF to Tmr0, and wait until it overflows. The Tmr0IF is NOT cleared, so, when the overflow occurs, the ISR is NOT called again, but a pulse still arrives from the Tmr0 module to the flip flop, toggling its state back to HIGH. Then, i clear the Tmr0IF to re-enable the Tmr0 interrupt, and the PIC is ready to measure the frequency once again.

I hope that you clearly understand how it works. Here is the firmware for further study:

 PIC Touch Button Capacitance module and Tmr0 timebase - Assembly listing - V1.0

And the Hex file:

 PIC Touch Button Capacitance module and Tmr0 timebase - Hex file - V1.0



  Email (shall not be published)


Notify me of new posts via email

Write your comments below:
BEFORE you post a comment:You are welcome to comment for corrections and suggestions on this page. But if you have questions please use the forum instead to post it. Thank you.


  • At 20 November 2015, 1:52:18 user sachin wrote:   [reply @ sachin]
    • I am using pic16f722a and i am facing problem in capsensing can you send me this code in c.[/b]its urgently needed.and i want to also understand what exactly happens when suppose a pin is touched.
      can i write code as after initializing timer base.
      if(RB0==1)//cap sensing pin
      {RA0=1;}//glowing led
      if (RB1==1)//same as above
      {RA1=1)//same as above.

      what should happen if a capsense pin is touched is the voltage on that pin is high.i may be asking stupid questions but please reply....

      ................please help urgently my email id is "sachindivekar1989@yahoo.com"

  • At 10 October 2014, 9:55:46 user Oguz wrote:   [reply @ Oguz]
    • Mr.Lazaridis Hi, I just know how to use jalv2. Asm code convert jalv2 kindly to you? Thank you for your help.

      Good work ...


  • At 12 May 2014, 12:05:28 user Tomas wrote:   [reply @ Tomas]
    • Hello Giorgos,

      Thanks for your extensive explanations and example videos. Very well done!

      When reading Microchips app.notes, they say that in general you make sure GND is not close to your sensor plate, but you choose to put a ground plane on the bottom side of the board. Which makes a relatively big capacitor of every button. Relative change will be less as compared to, say, only a grounded ring around your button.

      What made you decide to do so? Was sensitivity to high and did you need to make it less sensitive, or why did you do this?


      Keep up the good work!


  • At 26 February 2013, 21:14:06 user Giorgos Lazaridis wrote:   [reply @ Giorgos Lazaridis]
    • @kibo ???????

  • At 25 February 2013, 1:55:44 user kibo wrote:   [reply @ kibo]
    • hello Giorgos
      ( btfsc zero)Did you think the Zero Status register bit or ...?

      movf CPSCON1,w
      btfsc zero
      goto Cap_Check_Ch_1
      Thank you in advance for your response!

  • At 21 December 2012, 17:36:24 user Giorgos Lazaridis wrote:   [reply @ Giorgos Lazaridis]
    • @sri harsha only assembly listing possible

  • At 21 December 2012, 10:46:05 user sri harsha wrote:   [reply @ sri harsha]
    • [reply @ Giorgos Lazaridis],,,,,
      i know the code is in assembly language but i need the code in C & i am using pic16f1939 i dont know ho to fix the timer in C so please can you send me...

  • At 20 December 2012, 5:46:59 user Giorgos Lazaridis wrote:   [reply @ Giorgos Lazaridis]
    • @sri harsha it is in page 2

  • At 19 December 2012, 13:05:36 user sri harsha wrote:   [reply @ sri harsha]
    • guys,
      can you pls give me the coding process......i am in desperate need so pls......mail me to (sriharshu@gmail.com)

  • At 18 December 2012, 12:46:25 user sri harsha wrote:   [reply @ sri harsha]
    • please give me the embedded C code for this program.I am facing lot of problem reading assembly level code and i am using PIC16F1939 so please tell me how to fix the timer and also how to use two timers in the program


  • At 10 December 2012, 19:18:13 user Giorgos Lazaridis wrote:   [reply @ Giorgos Lazaridis]
    • @Hamed.mazlum mplab

  • At 10 December 2012, 12:54:55 user Hamed.mazlum wrote:   [reply @ Hamed.mazlum]
    • Dear Sir
      what's name of your compiler that you use?

  • At 6 September 2012, 20:36:19 user Chris wrote:   [reply @ Chris]
    • Hi,
      I have never written in ASM before. Could anyone make this work for 8 inputs and 8 outputs please, hardware im ok with its just the ASM part.

  • At 16 June 2012, 5:57:18 user karim wrote:   [reply @ karim]
    • Thank you very much for the video tutorials, They were a tremendous help for understanding the mtouch system. Keep up the good work!

  • At 11 May 2012, 13:38:25 user Giorgos Lazaridis wrote:   [reply @ Giorgos Lazaridis]
    • @Muhammad Awais Tahir The reason for this is probably the threshold setup. Different touch pads have different capacitance, and even if you move them to another position they change their capacitance (due to the cable). First of all, when you change anything to the touchpad (position, wire, etc) you need to restart the program so that it reads the starting capacitance. And second, you may need to change the threshold values of the touch pads (PressThreshold_H,PressThreshold_L and ReleaseThreshold_L)

  • At 10 May 2012, 10:08:12 user Muhammad Awais Tahir wrote:   [reply @ Muhammad Awais Tahir]
    • I'm experiencing a strange behavior. I just kept the CapCheck4 (associated with CPS0) , and removed others just to understand how it works. I've connected an LED to the relevant output port to test the touch. Now, when I connected my touch pad with CPS0 or CPS1 the LED just remains ON whether I touch the pad or not. But, it behaves exactly how it should when I connect the touch pad with CPS2. I'm quite confused on why its working correctly with CPS2 rather than CPS0, and why the port turns ON when I plug the touch pad into CPS0 or CPS1.

  • At 4 May 2012, 15:21:39 user Giorgos Lazaridis wrote:   [reply @ Giorgos Lazaridis]
    • @Muhammad Awais Tahir correct, the insulator is not connected

  • At 4 May 2012, 14:58:54 user Muhammad Awais Tahir wrote:   [reply @ Muhammad Awais Tahir]
    • According to the schematics there's no need to connect the insulator part of the touch pad to the ground. Is that right?

  • At 25 April 2012, 20:06:34 user Giorgos Lazaridis wrote:   [reply @ Giorgos Lazaridis]
    • @mina no mate, i'm sorry i haven't

  • At 25 April 2012, 10:01:05 user mina wrote:   [reply @ mina]
    • @Giorgos Lazaridis
      thanks a lot for your answer but i have a question have you ever used the EUSART of 16f1937 because i need to send data to the PC with rs232 .

  • At 18 April 2012, 12:16:42 user Giorgos Lazaridis wrote:   [reply @ Giorgos Lazaridis]
    • @Muhammad Awais Tahir first of all, it will be extremely sensitive, so you may need to alter the software variables for sensitivity. Additionally, it is good to cover with some sort of coating the button, since PICs are sensitive to ESD, so a direct touch to an input from a heavily charged body could destroy the port, or reduce its lifespan radically.

  • At 18 April 2012, 12:06:09 user Muhammad Awais Tahir wrote:   [reply @ Muhammad Awais Tahir]
    • Thanks for your reply to my previous query. If I make the touch-sensor using PCB, and I do NOT cover it with plexi glass or any other material what difference would it make?

  • At 16 April 2012, 16:18:35 user ion wrote:   [reply @ ion]
    • @Giorgos Lazaridis
      I know that. Was mine too
      Happy easter and keep looking for easter eggs .... maybe you find a rectangular shape one .... but not BOILED :)
      If you did behave, for sure easter bunny will visit you :) ....

  • At 16 April 2012, 16:05:30 user Giorgos Lazaridis wrote:   [reply @ Giorgos Lazaridis]
    • @ion we had easter this weekend, so it might take some more days to arrive.

  • At 16 April 2012, 14:56:46 user ion wrote:   [reply @ ion]
    • @Giorgos Lazaridis
      Thank you
      The package it is with the post office in Grece acording with my tracking
      You will get it soon
      You can track it also, because you have the number and link.

  • At 16 April 2012, 14:42:43 user Giorgos Lazaridis wrote:   [reply @ Giorgos Lazaridis]
    • @ion I knew it :D
      Changing the size to bigger will increase the capacitance radically, due the increment if copper area. That is why i state (somewhere) that it is rather difficult to make proper touch-pads. Anyway, it will not be that simple to change the capacitance channels. It will need a lot of changes in the ISR routine. I really do not remember by heart the code since it is rather old.

  • At 16 April 2012, 14:29:41 user ion wrote:   [reply @ ion]
    • @Giorgos Lazaridis
      Thank you Giorgio.
      In fact i changed the the size of the touch pads.
      I put back the old ones and works OK
      As a questions, if i just change the start point from cpscon1 from 00000000 to 00001100 will be suficient to let me use chanel 12 to 15 ?

  • At 16 April 2012, 8:35:39 user Giorgos Lazaridis wrote:   [reply @ Giorgos Lazaridis]
    • @ion i think that the problem is that you radically changed the shape or size of the touch pad, which changed the quiescence capacitance and this makes the output oscillate. Before you do anything else, try to change the parameters:
      PressThreshold_H equ b'00000000'
      PressThreshold_L equ b'00010110'
      into something bigger, for example the PressThreshold_L make it b'00110110'

  • At 14 April 2012, 0:12:38 user ion wrote:   [reply @ ion]
    • I had this project working fine for a while
      Then, maybe because due to my messy table, something happen.
      I do not know what
      Except CPS3-RB3 which works fine, all other channels flicker fast between 0 and 1.
      I do not have a scope because i am in China now, but i can see on my LCD.
      What do i have to do to move all the channels to CPS12 to 15
      I am not good at all in assembler , so a good working example will be the best.
      Thank you

  • At 11 April 2012, 19:10:46 user Giorgos Lazaridis wrote:   [reply @ Giorgos Lazaridis]
    • @Yash yes it is possible but i do not do circuits on demand, so unfortunately i cannot make this one

  • At 11 April 2012, 17:55:56 user Yash wrote:   [reply @ Yash]
    • Hi

      Great project!
      Is it possible to have a total of 16(max) 'buttons'?
      If so is there any change in the code? and which are the 16 connection points?


  • At 10 April 2012, 15:14:02 user Giorgos Lazaridis wrote:   [reply @ Giorgos Lazaridis]
    • @Muhammad Awais I'm almost sure that this program wont work on the pic you mention. I do not have a clue though regarding the changes that have to be done, since i've never worked with the pic you mention.
      As for the SR latches, do you mean the Tmr0 trigger latch? I use it for this program, and if you do not use it then this will not work at all, since the tmr stops from the latch.

  • At 10 April 2012, 13:44:05 user Muhammad Awais wrote:   [reply @ Muhammad Awais]
    • Have you used the SR Latches in the programming ? If I plan to use a PIC that doesn't have SR latches would that make a difference?

  • At 10 April 2012, 12:23:00 user Muhammad Awais wrote:   [reply @ Muhammad Awais]
    • Thanks for posting this. I'm planning to use PIC16F1519 as it comes with 28 cap touch channels, need I make any significant changes to the programming?

  • At 6 April 2012, 19:14:22 user Rogério Francisco wrote:   [reply @ Rogério Francisco]
    • Hi! could you send me the software for these example using four buttons. Thanks.

  • At 31 March 2012, 4:40:21 user Giorgos Lazaridis wrote:   [reply @ Giorgos Lazaridis]
    • @mina This pic has an internal precision oscillator, so you don't need external crystal.

  • At 30 March 2012, 14:32:53 user mina wrote:   [reply @ mina]
    • i just wanted to ask dont u need a crystal for the PIC ?

  • At 19 February 2012, 10:00:38 user Giorgos Lazaridis wrote:   [reply @ Giorgos Lazaridis]
    • @Jeff I think there are people that have already make this circuit and burned the hex code and worked properly. Why you ask? Did you face problems uploading it?

  • At 19 February 2012, 6:20:55 user Jeff wrote:   [reply @ Jeff]
    • Hii...is the hex code given is correct ?
      and if i do the cicuit and burn that hex code directly to ic..will it work ?

  • At 28 October 2011, 4:58:04 user Kammenos wrote:   [reply @ Kammenos]
    • @veroo post some screenshots in the forum

  • At 28 October 2011, 3:37:08 user veroo wrote:   [reply @ veroo]
    • Hi.

      Dear Kammenos.
      I did your instructions ( click on the menu project>built options> and then appears "No Active Project". After star a new project and paste the program then follow again your instructions ( project>built options>
      project> and "disable case sensitivity" ) but now not appears "Quickbuild" option.

      You can help me.

      Thank your for you help.

  • At 27 October 2011, 5:48:19 user Kammenos wrote:   [reply @ Kammenos]
    • @veroo Click on the menu Project -> Build options... -> Project.
      The "Buld options" dialog appears. Go to the tab labeled "MPASM Assembler" and make sure the checkbox "Disable case sensitivity" is checked. Then, click "Ok".

  • At 27 October 2011, 3:57:22 user veroo wrote:   [reply @ veroo]
    • Hi:

      Dear Kammenos.

      I already download the MPLAB IDE sofware and found the device pic16f1937, and open the .asm file to edit only to practice, but at the moment of compile the file appears me a list of erros in each one it says Symbol not previously defined.

      You can help me.

      Thank you.

  • At 25 October 2011, 4:40:51 user Kammenos wrote:   [reply @ Kammenos]
    • @veroo download the latest MPLAB which has the 16f1937

  • At 23 October 2011, 22:41:52 user veroo wrote:   [reply @ veroo]
    • Hi:
      Very nice job.

      I Have the compiler, but no theres in the list the pic 16f1937, what I can do. And I need a Programmer for this.

  • At 11 October 2011, 22:13:38 user jay wrote:   [reply @ jay]
    • would anyone be willing to program the PIC16F1937 for me? i will be more than happy to pay for your services.

  • At 10 October 2011, 15:44:06 user Kammenos wrote:   [reply @ Kammenos]
    • @jay http://www.pcbheaven.com/picpages/ i use addembly

  • At 10 October 2011, 15:42:15 user jay wrote:   [reply @ jay]
    • what kind of software do you need to program the PIC?

  • At 17 August 2011, 2:33:09 user Giba wrote:   [reply @ Giba]
    • Hi Kammenos,

      I will do the prototype and I will inform you my finds.


  • At 16 August 2011, 18:49:44 user Kammenos wrote:   [reply @ Kammenos]
    • @Giba go here:http://pcbheaven.com/circuitpages/10_buttons_touch_pad_bcd_output
      and change the code to work with 16 buttons

  • At 16 August 2011, 3:08:20 user Giba wrote:   [reply @ Giba]
    • Hi,

      I am student of Electrical Eng. and my team will have that do a keyboard with touch sensor. Could you send us the programm of touch sensor with 16 ports?

  • At 22 May 2011, 20:47:22 user Keith Elliott wrote:   [reply @ Keith Elliott]
    • Thanks for your article, I think that this might work with my capacitance variable humidity sensor for the weather station I am building.

  • At 18 April 2011, 20:00:10 user Kammenos wrote:   [reply @ Kammenos]
    • @Dylan definitely you need a programmer

  • At 18 April 2011, 18:02:45 user Dylan wrote:   [reply @ Dylan]
    • So, is any programming of the PIC required for this? or does it work "out of the box"?

  • At 28 March 2011, 11:20:05 user Kammenos wrote:   [reply @ Kammenos]
    • @John S 16MHz = 16.000.000/4 = 4.000.000 / 64 = 62.500 Hz = 62.5KHz
      I usually make mistakes with numbers, but this time i was correct :D :D :D

  • At 28 March 2011, 11:08:21 user John S wrote:   [reply @ John S]
    • You mentioned

      "The pulses that finally are delivered to the Tmr0 module, have a frequency of 62.5 KHz."

      is it not 6.25KHz for prescalar of 64?? or I'm wrong?


      opps... soory! i'm wrong.


  • At 28 March 2011, 10:31:50 user John S wrote:   [reply @ John S]
    • Thanks for the great explanation. You save my time from reading the pic manual and application note again n again. I have seen some of your youtube videos. Great work! Keep up your work. Thank you..

  • At 3 March 2011, 16:13:26 user Kammenos wrote:   [reply @ Kammenos]
    • no, you have to change it

  • At 3 March 2011, 16:08:35 user matt wrote:   [reply @ matt]
    • does this work if use on PIC18f4580

  • At 13 February 2011, 10:49:06 user Kammenos wrote:   [reply @ Kammenos]
    • Graham, read the 3rd page, in which i explain how they are made.

  • At 13 February 2011, 9:56:43 user Graham wrote:   [reply @ Graham]
    • Hi, I'm going to join in and ask what the touch sensors are physically made of?

      They look like pieces of aluminium foil with plastic on top?

  • At 12 February 2011, 21:00:34 user Kammenos wrote:   [reply @ Kammenos]
    • Manish, the change must be done in hardware to make it toggle. Regarding the LED dimmer, this is not that simple. You need to use the PWM output of the PIC and find a way to make the interface. I will make one more circuit, a capacitance touch sensor without microcontroller, and i will not work any more with touch sensors, unless i really need something. As a matter of fact, i did this research to prepare some interface for my coffee machine.

  • At 12 February 2011, 20:54:33 user Manish wrote:   [reply @ Manish]
    • Very nice design,but with this circuit can we make the toggle switch with some external componant & switch on & off any equipment with the help of relay, If possible please upload the schemetic or videos.& also with this can we make the 1 watt LED light dimmer circuit, if possible plz upload the details. Thanking u........

  • At 10 February 2011, 6:26:41 user Kammenos wrote:   [reply @ Kammenos]
    • oh, read this application note from microchip
      Pages 11 and 12

  • At 10 February 2011, 5:14:30 user venkey wrote:   [reply @ venkey]
    • Dear Kammenos, This matrix i know but how to make pcb pads for cap sens module. Thanks

  • At 9 February 2011, 17:54:44 user Kammenos wrote:   [reply @ Kammenos]
    • venkey, read about matrix here:

  • At 9 February 2011, 14:57:59 user venkey wrote:   [reply @ venkey]
    • Hi, nice project. Please explain ho to multiplex 8x8 with pic16f1937 thanks.

  • At 8 February 2011, 22:36:55 user Vasilis wrote:   [reply @ Vasilis]
    • geia sou file mou.
      poli orees oi kataskeues sou kai mpravo.
      ama itheles tha sou elega na ta anaivazeis kai sta ellinika kai ta video kai tis perigrafes...gt opos xereis edo sti ellada den eimaste sainia sta agglika..
      me endiaferei poli auto me ta Capacitance Sensor eidika to allo poy eida xtes pou epiane piso apo to plastiko.
      ama itheles na ta exigisis ligo sta ellinika tha me voithouse poli.
      se euxaristo poli.

    reddit this Reddit this

     HOT in heaven!

    NEW in heaven!

    New Theory: AC electric motor working principle

     Contact     Forum     Projects     Experiments     Circuits     Theory     BLOG     PIC Tutorials     Time for Science     RSS   

    Site design: Giorgos Lazaridis
    © Copyright 2008
    Please read the Terms of services and the Privacy policy