CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Capacitance Measurement through integration

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
crystal_lattice



Joined: 13 Jun 2006
Posts: 164

View user's profile Send private message

Capacitance Measurement through integration
PostPosted: Sat Apr 12, 2008 2:27 pm     Reply with quote

Hi there, has anyone used a normal IO pin to measure capacitance before??

I recently stumbled upon a guy's web site which has a circuit to "measure" capacitance and use this switch LED's on. I would like to implement a similar idea on a PIC to enable me to make a capacitance keypad for harsh environments.

Unfortunately i am not familiar with the AVR micro and was wondering if someone could maybe shed some light on how to implement it on a PIC. I have included the AVR code as the original website seems to be down at the moment. (http://www.elm-chan.org/works/capsens/report_e.html)

Kind Regards

Code:


/*------------------------------------------------*/
/* Touch sensor test program R0.1a (C)ChaN, 2007  */
/* ATtiny2313 Internal osc 8MHz                   */
/*------------------------------------------------*/

#include <avr/io.h>
#include <inttypes.h>
#include <avr/pgmspace.h>
#include <avr/sleep.h>
#include <avr/interrupt.h>
#include "suart.h"
#include "xitoa.h"
#include "cs.h"

#define SYSCLK   8000000UL


/*------------------------------------------------*/
/* Global variables                               */

char line[16];   /* Console input buffer */



/*------------------------------------------------*/


static
void get_line (char *buff, int len)
{
   char c;
   int idx = 0;


   for (;;) {
      c = rcvr();
      if (c == '\r') break;
      if ((c == '\b') && idx) {
         idx--; xputc(c);
      }
      if (((unsigned char)c >= ' ') && (idx < len - 1)) {
            buff[idx++] = c; xputc(c);
      }
   }
   buff[idx] = 0;
   xputc(c);
   xputc('\n');
}



void get_sens (int *res, int chs)
{
   int ch, loop;

   /* Clear count accumlator */
   for (ch = 0; ch < chs; ch++) res[ch] = 0;

   /* Capture and accumlate integration time for 1/60 second */
   OCR0A = 8000000UL / 1024 / 60;
   TCNT0 = 0;
   TIFR = _BV(OCF0A);
   TCCR0B = 0b101;
   loop = 0;
   do {
      for (ch = 0; ch < chs; ch++) res[ch] += touch(ch);
      loop++;
   } while ((TIFR & _BV(OCF0A)) == 0);
   TCCR0B = 0;

   /* Mean calculation */
   for (ch = 0; ch < chs; ch++) res[ch] /= loop;
}



/*------------------------------------------------*/
/* Online Monitor                                 */

int main (void)
{
   char *cp;
   int n, c, ref[8], val[8];


   PORTB = 0b10111111;   /* Initialize I/O port */
   DDRB  = 0b01000000;
   PORTD = 0b1000000;
   DDRD =  0b0111111;
   PORTA = 0b100;
   DDRA  = 0b011;


   get_sens(ref, 8);   /* Get reference count for each channel */

   if (1) {   /* Standalone mode */
      /* Re-initialize I/O port as sens outputs */
      PORTB = 0b00000000;
      DDRB  = 0b11111111;
      for (;;) {
         get_sens(val, 8);
         for (c = 0; c < 8; c++) {
            n = val[c] - ref[c];
            if (n < 3) PORTB &= ~(1 << (7 - c));
            if (n > 5) PORTB |= (1 << (7 - c));
         }
      }
   }

   /* Interactive mode */
   xfunc_out = (void(*)(char))xmit;
   xputs(PSTR("\nTouch sensor test program\n"));

   for(;;) {
      xputc('>');                  /* Prompt */
      get_line(line, sizeof(line));
      cp = line;

      switch (*cp++) {   /* Pick a header char (command) */
         case '\0' :      /* Blank line */
            break;

         case 's' :      /* Read sensor */
            xputs(PSTR(" ch0 ch1 ch2 ch3 ch4 ch5 ch6 ch7\n"));
            do {
               get_sens(val,8);
               for (c = 0; c < 8; c++) xitoa(val[c] - ref[c], -10, 4);
               xputc('\r');
            } while (bit_is_clear(PINB, 5));   /* repeart until a break detected */
            xputc('\n');
            break;

         default :      /* Unknown command */
            xputs(PSTR("\n???"));
      }
      
   }
}

SherpaDoug



Joined: 07 Sep 2003
Posts: 1640
Location: Cape Cod Mass USA

View user's profile Send private message

PostPosted: Sat Apr 12, 2008 6:30 pm     Reply with quote

Look at Microchip.com application note 512. It shows how to use an RC circuit to measure resistance with minimal hardware. But the RC circuit can just as easily measure capacitance as resistance.
_________________
The search for better is endless. Instead simply find very good and get the job done.
crystal_lattice



Joined: 13 Jun 2006
Posts: 164

View user's profile Send private message

Capacitive Button
PostPosted: Sun Apr 13, 2008 1:03 am     Reply with quote

Hi SherpaDoug, i realize now that my topic heading is a bit missleading. I don't want to make capacitive readings as such, i just want to implement capacitve based switches.

I will read the app note you suggested, but was wondering if anyone has done this type of button implementation with good success?? And maybe willing to share some code...

Kind Regards
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Apr 13, 2008 1:40 am     Reply with quote

http://www.ccsinfo.com/forum/viewtopic.php?t=33266&highlight=touch
crystal_lattice



Joined: 13 Jun 2006
Posts: 164

View user's profile Send private message

Capacitive Button
PostPosted: Sun Apr 13, 2008 3:34 am     Reply with quote

Thanx PCM, but i would like to refrain from using AD ports. I have drawn up some code which i wanna test a bit later on, i was just wondering if anyone has some input regarding any better methods of doing it.

The circuit comprises of a large value pull-up on a pin. The junction of which is attached to a "pad".

Kind Regards

Code:

   int8 first_capture, second_capture,x,max_time,Button_presses;
   
   while(true)
   {
      output_b(0x0);             //Set output low to discharge "cap"
   
      first_capture = input_b(); //capture the state of the pins just after they have been made low, if no
                                 // capacitance present it will imediately be high.
   
      for(x=0;x<max_time;x++)    // delay for a fixed amount of time to give the cap time to charge
      {
      }
   
      second_capture = input_b();   // Check the status of the inputs again, after the "cap" had time to "charge"
                                    //via the pull up resistor.
   
      Button_presses = Second_capture - first_Capture;   // the delata change indicates which buttons were pressed
   
      output_c(button_presses);                          // put the result on a output port for display.
   }
crystal_lattice



Joined: 13 Jun 2006
Posts: 164

View user's profile Send private message

Capacitive buttons/touch sensor
PostPosted: Sun Apr 13, 2008 1:48 pm     Reply with quote

Hi all, i thought i had found the solution to my problem when i found some app notes and a few data sheets microchip's.

They have a pic, the 16F72X series, with built-in capacitance switch inputs. After studying the datasheets and app notes i was convinced to change my original idea to this newly found info.

Unfortunately it is only a future product... only found that out when trying to order samples...

I did find this link quite useful though:
http://www.bytecraft.com/Touch_Sensitive_Switch

My current code is working but needs a bit of tweaking to avoid false triggers and adjust sensitivity. any input is welcome (no pun intended...)

Kind Regards

Code:


while(true)
   {
   
      output_d(0x00);             //Set output low to discharge "cap"
      delay_ms(1);
      set_tris_d(0b11111111);
      delay_us(5);
   
      output_c(input_d()^0xff);  //invert to light LED when "button" pressed
     
      delay_ms(50);
   }
yerpa



Joined: 19 Feb 2004
Posts: 58
Location: Wisconsin

View user's profile Send private message Visit poster's website

PostPosted: Mon Apr 14, 2008 2:32 pm     Reply with quote

I did several touch switch applications about thirteen years ago, using 16C55 chips. The user interface consisted of stainless steel bolts. There were eight touch bolt inputs per 16C55, plus a single reference input driven directly from a 555 timer chip. The 555 also drove each touch bolt through a series resistor with a diode (1n4004) across the resistor. Another series resistor buffered each 16C55 input pin, except for the reference.

The way it worked was as follow: The PIC would look at the reference pin in a tight loop. When it went low, the PIC would then read an input pin in a loop and count how many cycles it took to also go low. If a person touched a bolt, the additional capacitance would cause the input to drop more slowly than the reference pin, indicating a touch. The program was adaptive - it would look at all of the inputs, and determine a median loop timing with the assumption that most of the inputs are off at any given time.

There were four PICs and one 555 per board for a total of 32 inputs. The boards worked very well as long as the wire lengths to the touchbolts were kept below about three feet. I think they are still in service.
crystal_lattice



Joined: 13 Jun 2006
Posts: 164

View user's profile Send private message

Capacitive touch buttons
PostPosted: Tue Apr 15, 2008 12:34 am     Reply with quote

Thanx Yerpa, i'm planning on doing something similar with measuring the cycles that the pin went low. Think this is better as this will give a reference value without a touch and then one can also determine the "exact" capacitance when a touch is present.

Am currently trying to figure out how to make an array of inputs to work...

I found this post: http://www.ccsinfo.com/forum/viewtopic.php?t=32989

but have not tried it yet, still not sure why the values have to be 16Bit??

Kind Regards

PS. these "buttons" will be PCB based so the trace to the PIC from the pad will be minimal.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group