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 support@ccsinfo.com

Microchip Mtouch capacitive touch sensor

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



Joined: 29 Oct 2008
Posts: 13

View user's profile Send private message

Microchip Mtouch capacitive touch sensor
PostPosted: Mon Dec 08, 2008 6:20 pm     Reply with quote

Hi all,

inspired by Microchip Mtouch app. notes and especially AN1171 and Nuts&volt technical paper (june 2008), I start to write a driver for the Build-in Mtouch µC 16F722, 16F723 and 16F726.

So, here is the code and the questions on the bottom Wink

Code:


//******************************************************************
// Filename:  Cap_touch726.c
//
// Purpose: Illustrate the use of the Capacitive Sensing Module
//  This program scans 8 pads on a PCB. Each pad is sensed by the Capacitive
//  Sensing Module at a fixed interval.  The frequency of each pad at rest is averaged.l
//  When a pad is touched, the frequency on the Cap. sensing module changes due to the
//  extra capacitance from the finger.  The change in frequency is noted and the LEDs
//  light up to indicate which button was pressed.

//******************************************************************
#include <16F726.h>

#fuses INTRC,NOWDT,NOPROTECT,NOLVP,PUT,NODEBUG,BROWNOUT

#define INT_TIMER1G                0x8C80

//*********************register definitions ************************
#byte OSCCON = 0x90
#byte OPTION = 0x81
#byte T1CON = 0x10
#byte T1GCON = 0x8f
#byte CPSCON0 = 0x108
#byte INTCON = 0x0b
#byte CPSCON1 = 0x109
#byte PIE1 = 0x8c
#byte PIR1 = 0x0c
#byte TMR1L = 0x0e
#byte TMR1H = 0x0f

// T1CON bits
#bit TMR1ON = T1CON.0

// INTCON bits
#bit GIE = INTCON.7
#bit PEIE = INTCON.6
#bit T0IE = INTCON.5
#bit T0IF = INTCON.2

// PIE1 bits
#bit TMR1GIE = PIE1.7

// PIR1 bits
#bit TMR1GIF = PIR1.7

//******************************************************************
//   KEYPAD BIT STRUCTURE
//      Used for bit indicators for button presses
//******************************************************************
struct capacitive_keypad {
      char PAD0 : 1;
      char PAD1 : 1;
      char PAD2 : 1;
      char PAD3 : 1;
      char PAD4 : 1;
      char PAD5 : 1;
      char PAD6 : 1;
      char PAD7 : 1;
   } keypad;
   
//******************************************************************
//   SENSOR COUNT DEFINITIONS
//******************************************************************
#define   MAXSENSORS          8
#define   NUM_AVG_PASSES      3
#define   NUM_STAB_PASSES     5
#define   HYSTERESIS_VALUE    30

//******************************************************************
//*   I/O DEFINITIONS
//******************************************************************
#define CONFIG0         PIN_A6
#define CONFIG1         PIN_A7
#define INT_MTOUCH      PIN_A3
//******************************************************************
//*   SRAM DEFINITIONS
//******************************************************************
unsigned int   timer1_val[MAXSENSORS];
unsigned int   timer1_raw[MAXSENSORS];
unsigned int   btn_average[MAXSENSORS];
unsigned int   trip_val[MAXSENSORS];
   
char stabilize_pass;
char average_pass;
char btn_pressed;
char sensor_index;

#define   OUTPUT0         PIN_C0
#define   OUTPUT1         PIN_C1
#define   OUTPUT2         PIN_C2
#define   OUTPUT3         PIN_C3
#define   OUTPUT4         PIN_C4
#define   OUTPUT5         PIN_C5
#define   OUTPUT6         PIN_C6
#define   OUTPUT7         PIN_C7

//*********************************************************************
//*   FUNCTION PROTOTYPES
//*********************************************************************
void init(void);
void interrupt_sensor(void);
void reset_timer1(void);
void select_next_sensor(void);

//****************************************************************************//
//*   INITIALIZE FUNCTION
//****************************************************************************//
void init()
{
   char x;
     
   OSCCON = 0x30;   //16 MHz PLLEN
     
//****************************************************************************//
//* Initialize for timers (Timer0 time base)
//****************************************************************************//   
   OPTION = 0b11000101;          // Timer0 INIT CLK ON FOSC/4
   T0IF = 0;                     // Clear Timer0 interrupt flag
   T0IE = 1;                     // enable Timer0 interrupt
   
   T1CON  = 0b01000101;          // Timer1 enable, system clock, 1:1 prescale,
   T1GCON = 0b11100001;          // Timer1 gate init

//****************************************************************************//
//*   SETUP CAP SENSE MODULE
//****************************************************************************//
   CPSCON0 = 0b10001100;         // Cap Sense control settings
   CPSCON1 = 0;                  // init to channel select = 0 (4 LSb's)
 
//*********************************************************************
//*   SETUP CAP SENSE VARIABLES
//*********************************************************************
   stabilize_pass = NUM_STAB_PASSES;
   average_pass = NUM_AVG_PASSES;
   
   trip_val[0] = 120;
   trip_val[1] = 120;
   trip_val[2] = 120;
   trip_val[3] = 120;
   trip_val[4] = 120;
   trip_val[5] = 120;
   trip_val[6] = 120;
   trip_val[7] = 120;

   for(x = 0; x < MAXSENSORS; x++)
   {
      btn_average[x] = 0;
   }
   
//****************************************************************************//
//* Gate Setup
//****************************************************************************//
   TMR1GIF   = 0;                  // clear gate interrup flag
   TMR1GIE   = 1;                  // enable gate interrup
   
   PEIE      = 1;                  // enable peripheral intpts
   GIE       = 1;                  // enable global intpts
   
//****************************************************************************//
//* Initialize for interrup pin output
//****************************************************************************// 
   output_low(INT_MTOUCH);        // clear output interrupt pin
}

//****************************************************************************// 
// ISR() Interrupt Service Routine
// 
// Reads values of TMR1 corresponding to each button/sensor
// and makes decision if button/sensor has been touched.
//****************************************************************************// 
#int_timer0                      // Timer0 Interrupt
void timer0_isr()
{
   if (T0IF==1)
      {
         T0IF = 0;               // clear interrup flag
      }
}

#int_timer1g                     // Timer1 Gate Interrupt
void timer1_gate_isr()
{
   if(TMR1GIF==1)
   {
      TMR1GIF = 0;               // clear interrup flag
      TMR1ON = 0;                // TIMER1 off
     
      timer1_val[sensor_index] = make16(TMR1H,TMR1L);
      timer1_raw[sensor_index] = timer1_val[sensor_index] * 16;
     
      //stabilize the btn_average value
      if(stabilize_pass > 0x00)
      {
         stabilize_pass--;
         btn_average[sensor_index] = timer1_raw[sensor_index];
         reset_timer1();
         
         if((stabilize_pass == 0) && (sensor_index < (MAXSENSORS - 1)))
         {
            stabilize_pass = NUM_STAB_PASSES;
            select_next_sensor();
         }
         
      }
      else
      {
         //check for button pressed
         if(timer1_raw[sensor_index] < (btn_average[sensor_index] - trip_val[sensor_index]))
         {
            if(!(keypad.PAD0 || keypad.PAD1 || keypad.PAD2 ||
                keypad.PAD3 || keypad.PAD4 || keypad.PAD5 ||
                keypad.PAD6 || keypad.PAD7 ))
                {
                   output_high(INT_MTOUCH);
                   switch(sensor_index)
                   {
                      case 0:   keypad.PAD0 = 1;   break;
                      case 1:   keypad.PAD1 = 1;   break;
                      case 2:   keypad.PAD2 = 1;   break;
                      case 3:   keypad.PAD3 = 1;   break;
                      case 4:   keypad.PAD4 = 1;   break;
                      case 5:   keypad.PAD5 = 1;   break;
                      case 6:   keypad.PAD6 = 1;   break;
                      case 7:   keypad.PAD7 = 1;   break;
                  }
               }
         }
         else if(timer1_raw[sensor_index] > (btn_average[sensor_index] - trip_val[sensor_index])+ HYSTERESIS_VALUE)
         {
                   output_low(INT_MTOUCH);
                   switch(sensor_index)
                   {
                      case 0:   keypad.PAD0 = 0;   break;
                      case 1:   keypad.PAD1 = 0;   break;
                      case 2:   keypad.PAD2 = 0;   break;
                      case 3:   keypad.PAD3 = 0;   break;
                      case 4:   keypad.PAD4 = 0;   break;
                      case 5:   keypad.PAD5 = 0;   break;
                      case 6:   keypad.PAD6 = 0;   break;
                      case 7:   keypad.PAD7 = 0;   break;
                  }
         }
         
         if(timer1_raw[sensor_index] > (btn_average[sensor_index]))
         {
            btn_average[sensor_index] = btn_average[sensor_index] + (timer1_val[sensor_index] - (btn_average[sensor_index] / 16));
         }
         //compute average
         average_pass--;
         if(average_pass == 0)
         {
            btn_average[sensor_index] = btn_average[sensor_index] + (timer1_val[sensor_index] - (btn_average[sensor_index] / 16));
            average_pass = NUM_AVG_PASSES;
            select_next_sensor();
         }
         reset_timer1();
      }
   }
}

//****************************************************************************//
//*   TIMER1 RESET FUNCTION - Reset and restart timer 1
//****************************************************************************//
void reset_timer1()
{
   TMR1L   = 0;   // clear TIMER1 low byte
   TMR1H   = 0;   // clear TIMER1 high byte
   TMR1ON  = 1;   // start TIMER1
}

//****************************************************************************//
//*   SELECT NEXT CPS CHANNEL
//****************************************************************************//
void select_next_sensor()
{
   sensor_index++;            // cycle index state 0-7 w/rollover
   if(sensor_index >= MAXSENSORS)
   {
      sensor_index = 0;
   }
   CPSCON1 = sensor_index;    // Select external pin CPS0..CPS7
}

//****************************************************************************//
//*     MAIN FUNCTION
//****************************************************************************//
void main(void)
{
   Init();
   sensor_index = 0;          // Start program ready to scan first channel

   while(true)                // Loop forever
        {

      // React to button presses in application main-loop
      if (keypad.PAD0)
         {
            output_high(OUTPUT0);
         } else {
            output_low(OUTPUT0);
         }
      if (keypad.PAD1)
         {
            output_high(OUTPUT1);
         } else {
            output_low(OUTPUT1);
         }
      if (keypad.PAD2)
         {
            output_high(OUTPUT2);
         } else {
            output_low(OUTPUT2);
         }
      if (keypad.PAD3)
         {
            output_high(OUTPUT3);
         } else {
            output_low(OUTPUT3);
         }
      if (keypad.PAD4)
         {
            output_high(OUTPUT4);
         } else {
            output_low(OUTPUT4);
         }
      if (keypad.PAD5)
         {
            output_high(OUTPUT5);
         } else {
            output_low(OUTPUT5);
         }
      if (keypad.PAD6)
         {
            output_high(OUTPUT6);
         } else {
            output_low(OUTPUT6);
         }
      if (keypad.PAD7)
         {
            output_high(OUTPUT7);
         } else {
            output_low(OUTPUT7);
         }
   }
}


and the questions:

/ I need to configure OPTION2 register to choose VCAP pin (in my case, VCAP on RA0) but Vcap configuration should be a fuse.
How to add a fuse on CCS which doesn't exist?

/ How to add an interrupt on CCS device.h file? Because

Code:
#define INT_TIMER1G                0x8C80

and
Code:
#int_timer1g

don't work...

I'm not an expert. So, don't hesitate to add comments on my code.

Franck
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Dec 08, 2008 7:22 pm     Reply with quote

Quote:
How to add a fuse on CCS which doesn't exist?

Vs. 4.083 has fuses for VCAP. Here is part of the .H file:
Code:
//////// Standard Header file for the PIC16F726 device ////////////////

//////// Fuses: VCAP_A0, VCAP_A5, VCAP_A6, NOVCAP,NOBROWNOUT
////////


Quote:
How to add an interrupt on CCS device.h file?

I don't see an entry for INT_TIMER1G in the .H file for vs. 4.083.
This thread has an example of using #int_default as a work-around.
However, read Ttelmah's comment.
http://www.ccsinfo.com/forum/viewtopic.php?p=106973

Another possible work-around is, if you have the IDE version of the
compiler, then you could edit the Device data (using the Device Editor)
and add the new interrupt. I don't have the IDE version, so I can't
test it for you. Someone mentioned that the Device Editor has a button
to generate a new, updated .H file that will incorporate your changes,
once you have made them.

Again, if your version doesn't have the VCAP fuses, you could use the
Device Editor to add them.
Fram_fr



Joined: 29 Oct 2008
Posts: 13

View user's profile Send private message

PostPosted: Wed Dec 10, 2008 5:46 am     Reply with quote

PCM programmer,

Thank you very much for your answer.
I updated my CCS release and it's now OK about VCAP fuse.

About interrupt, I will check your solution using #int_default.

Franck Wink
Fram_fr



Joined: 29 Oct 2008
Posts: 13

View user's profile Send private message

PostPosted: Thu Dec 11, 2008 6:05 pm     Reply with quote

Here is a code that should be work now! (not tested on real hardware)

It is possible to configure output level when a pad is touched:
- high output level when OUT_POLARITY pin is set to GND.(standard)
- low output level when OUT_POLARITY pin is set to VCC.(invert)

INT_MTOUCH is set to VCC when a pad is touched.(interrupt pin for main µC)

2 others pins (config0 and config1) are for incoming code (I2C and SPI possibilities...)

Check I/O DEF and pic datasheet for hardware config.
More coming next with I2C and SPI possibilities.

Code:
//****************************************************************************//
// Filename:  Mtouch722_723_726.h
//
// Purpose: Registers and Defines for Mtouch Cap_Sense module
//****************************************************************************//

//*********************register definitions ************************
#byte OSCCON = 0x90
#byte OPTION = 0x81
#byte T1CON = 0x10
#byte T1GCON = 0x8f
#byte CPSCON0 = 0x108
#byte INTCON = 0x0b
#byte CPSCON1 = 0x109
#byte PIE1 = 0x8c
#byte PIR1 = 0x0c
#byte TMR1L = 0x0e
#byte TMR1H = 0x0f

// T1CON bits
#bit TMR1ON = T1CON.0

// INTCON bits
#bit GIE = INTCON.7
#bit PEIE = INTCON.6
#bit T0IE = INTCON.5
#bit T0IF = INTCON.2

// PIE1 bits
#bit TMR1GIE = PIE1.7

// PIR1 bits
#bit TMR1GIF = PIR1.7

//****************************************************************************//
//   KEYPAD BIT STRUCTURE
//      Used for bit indicators for button presses
//****************************************************************************//
struct capacitive_keypad {
      char PAD0 : 1;
      char PAD1 : 1;
      char PAD2 : 1;
      char PAD3 : 1;
      char PAD4 : 1;
      char PAD5 : 1;
      char PAD6 : 1;
      char PAD7 : 1;
   } keypad;
   
#locate keypad=0x20
   
//****************************************************************************//
//   SENSOR COUNT DEFINITIONS
//****************************************************************************//
#define   MAXSENSORS          8
#define   NUM_AVG_PASSES      3
#define   NUM_STAB_PASSES     5
#define   HYSTERESIS_VALUE    30

//****************************************************************************//
//*   I/O DEFINITIONS
//****************************************************************************//
#define CONFIG0            PIN_A6   // optionnal config. pin
#define CONFIG1            PIN_A7   // optionnal config. pin
#define INT_MTOUCH         PIN_A3   // interrupt pin output
#define OUT_POLARITY       PIN_A2   // output polarity configuration
#define OUTPUT0            PIN_C0
#define OUTPUT1            PIN_C1
#define OUTPUT2            PIN_C2
#define OUTPUT3            PIN_C3
#define OUTPUT4            PIN_C4
#define OUTPUT5            PIN_C5
#define OUTPUT6            PIN_C6
#define OUTPUT7            PIN_C7


Code:
//****************************************************************************//
// Filename:  Mtouch722_723_726.c
//
// Purpose: Illustrate the use of the Capacitive Sensing Module
//  This program scans 8 pads on a PCB. Each pad is sensed by the Capacitive
//  Sensing Module at a fixed interval.  The frequency of each pad at rest is averaged.l
//  When a pad is touched, the frequency on the Cap. sensing module changes due to the
//  extra capacitance from the finger.  The change in frequency is noted and the LEDs
//  light up to indicate which button was pressed.
//
// It is possible to configure output level when a pad is touched:
// - high output level when OUT_POLARITY pin is set to GND.(standard)
// - low output level when OUT_POLARITY pin is set to VCC.(invert)
//
// INT_MTOUCH is set to VCC when a pad is touched.(interrupt pin for main µC)
//
// Check I/O DEF. and pic datasheet for hardware config.
//
//****************************************************************************//
//!#include <16F722.h>
//!#include <16F723.h>
#include <16F726.h>

#include <Mtouch722_723_726.h>

#FUSES INTRC_IO                  //Internal RC Osc, no CLKOUT
#FUSES VCAPA0                    //VCAP on pin A0
#FUSES NOWDT                     //No Watch Dog Timer
#FUSES NOPROTECT                 //Code not protected from reading
#FUSES PLLEN                     //Enable PLL
#FUSES NODEBUG                   //No Debug mode for ICD
#FUSES MCLR                      //Master Clear pin enabled
#FUSES NOBROWNOUT                //No brownout reset
#FUSES NOPUT                     //No Power Up Timer   

//****************************************************************************//
//*   SRAM DEFINITIONS
//****************************************************************************//
unsigned int   timer1_val[MAXSENSORS];
unsigned int   timer1_raw[MAXSENSORS];
unsigned int   btn_average[MAXSENSORS];
unsigned int   trip_val[MAXSENSORS];
   
char stabilize_pass;
char average_pass;
char sensor_index;

//****************************************************************************//
//*   FUNCTION PROTOTYPES
//****************************************************************************//
void init(void);
void timers_isr(void);
void reset_timer1(void);
void select_next_sensor(void);

//****************************************************************************//
//*   INITIALIZE FUNCTION
//****************************************************************************//
void init()
{
   char x;
     
   OSCCON = 0x30;   //16 MHz with PLLEN
     
//****************************************************************************//
//* Initialize for timers (Timer0 time base)
//****************************************************************************//   
   OPTION = 0b11000101;          // Timer0 INIT CLK ON FOSC/4
   T0IF = 0;                     // Clear Timer0 interrupt flag
   T0IE = 1;                     // enable Timer0 interrupt
   
   T1CON  = 0b01000101;          // Timer1 enable, system clock, 1:1 prescale,
   T1GCON = 0b11100001;          // Timer1 gate init

//****************************************************************************//
//*   SETUP CAP SENSE MODULE
//****************************************************************************//
   CPSCON0 = 0b10001100;         // Cap Sense control settings
   CPSCON1 = 0;                  // init to channel select = 0 (4 LSb's)
 
//****************************************************************************//
//*   SETUP CAP SENSE VARIABLES
//****************************************************************************//
   stabilize_pass = NUM_STAB_PASSES;
   average_pass = NUM_AVG_PASSES;
   
   trip_val[0] = 120;
   trip_val[1] = 120;
   trip_val[2] = 120;
   trip_val[3] = 120;
   trip_val[4] = 120;
   trip_val[5] = 120;
   trip_val[6] = 120;
   trip_val[7] = 120;

   for(x = 0; x < MAXSENSORS; x++)
   {
      btn_average[x] = 0;
   }
   
//****************************************************************************//
//* Gate Setup
//****************************************************************************//
   TMR1GIF   = 0;                   // clear gate interrup flag
   TMR1GIE   = 1;                   // enable gate interrup
   
   PEIE      = 1;                   // enable peripheral intpts
   GIE       = 1;                   // enable global intpts
   
//****************************************************************************//
//* Initialize for interrup pin output
//****************************************************************************// 
   output_low(INT_MTOUCH);          // clear output interrupt pin
   
//****************************************************************************//
//* Initialize for pins output
//****************************************************************************//
   if (!input(OUT_POLARITY))        // polarity pin is set to 0
      {
         output_low(OUTPUT0);       // set output pin low
         output_low(OUTPUT1);       // set output pin low
         output_low(OUTPUT2);       // set output pin low
         output_low(OUTPUT3);       // set output pin low
         output_low(OUTPUT4);       // set output pin low
         output_low(OUTPUT5);       // set output pin low
         output_low(OUTPUT6);       // set output pin low
         output_low(OUTPUT7);       // set output pin low
      }
    if (input(OUT_POLARITY))        // polarity pin is set to 1
      {
         output_high(OUTPUT0);      // set output pin high
         output_high(OUTPUT1);      // set output pin high
         output_high(OUTPUT2);      // set output pin high
         output_high(OUTPUT3);      // set output pin high
         output_high(OUTPUT4);      // set output pin high
         output_high(OUTPUT5);      // set output pin high
         output_high(OUTPUT6);      // set output pin high
         output_high(OUTPUT7);      // set output pin high
      }
   
   for(x = 0; x < MAXSENSORS; x++)
   {
      btn_average[x] = 0;
   }   
}

//****************************************************************************// 
// ISR() Interrupt Service Routine
// 
// Reads values of TMR1 corresponding to each button/sensor
// and makes decision if button/sensor has been touched.
//****************************************************************************// 
#INT_DEFAULT                     // Interrupt
void timers_isr()
{
   if (T0IF==1)                  // Timer0 Interrupt
      {
         T0IF = 0;               // clear interrup flag
      }

   if(TMR1GIF==1)                // Timer1 gate Interrupt
   {
      TMR1GIF = 0;               // clear interrup flag
      TMR1ON = 0;                // TIMER1 off
     
      timer1_val[sensor_index] = make16(TMR1H,TMR1L);
      timer1_raw[sensor_index] = timer1_val[sensor_index] * 16;
     
      //stabilize the btn_average value
      if(stabilize_pass > 0x00)
      {
         stabilize_pass--;
         btn_average[sensor_index] = timer1_raw[sensor_index];
         reset_timer1();
         
         if((stabilize_pass == 0) && (sensor_index < (MAXSENSORS - 1)))
         {
            stabilize_pass = NUM_STAB_PASSES;
            select_next_sensor();
         }
         
      }
      else
      {
         //check for button pressed
         if(timer1_raw[sensor_index] < (btn_average[sensor_index] - trip_val[sensor_index]))
         {
            if(!(keypad.PAD0 || keypad.PAD1 || keypad.PAD2 ||
                keypad.PAD3 || keypad.PAD4 || keypad.PAD5 ||
                keypad.PAD6 || keypad.PAD7 ))
                {
                   output_high(INT_MTOUCH);
                   switch(sensor_index)
                   {
                      case 0:   keypad.PAD0 = 1;   break;
                      case 1:   keypad.PAD1 = 1;   break;
                      case 2:   keypad.PAD2 = 1;   break;
                      case 3:   keypad.PAD3 = 1;   break;
                      case 4:   keypad.PAD4 = 1;   break;
                      case 5:   keypad.PAD5 = 1;   break;
                      case 6:   keypad.PAD6 = 1;   break;
                      case 7:   keypad.PAD7 = 1;   break;
                  }
               }
         }
         else if(timer1_raw[sensor_index] > (btn_average[sensor_index] - trip_val[sensor_index])+ HYSTERESIS_VALUE)
         {
                   output_low(INT_MTOUCH);
                   switch(sensor_index)
                   {
                      case 0:   keypad.PAD0 = 0;   break;
                      case 1:   keypad.PAD1 = 0;   break;
                      case 2:   keypad.PAD2 = 0;   break;
                      case 3:   keypad.PAD3 = 0;   break;
                      case 4:   keypad.PAD4 = 0;   break;
                      case 5:   keypad.PAD5 = 0;   break;
                      case 6:   keypad.PAD6 = 0;   break;
                      case 7:   keypad.PAD7 = 0;   break;
                  }
         }
         
         if(timer1_raw[sensor_index] > (btn_average[sensor_index]))
         {
            btn_average[sensor_index] = btn_average[sensor_index] + (timer1_val[sensor_index] - (btn_average[sensor_index] / 16));
         }
         //compute average
         average_pass--;
         if(average_pass == 0)
         {
            btn_average[sensor_index] = btn_average[sensor_index] + (timer1_val[sensor_index] - (btn_average[sensor_index] / 16));
            average_pass = NUM_AVG_PASSES;
            select_next_sensor();
         }
         reset_timer1();
      }
   }
}

//****************************************************************************//
//*   TIMER1 RESET FUNCTION - Reset and restart timer 1
//****************************************************************************//
void reset_timer1()
{
   TMR1L   = 0;   // clear TIMER1 low byte
   TMR1H   = 0;   // clear TIMER1 high byte
   TMR1ON  = 1;   // start TIMER1
}

//****************************************************************************//
//*   SELECT NEXT CPS CHANNEL
//****************************************************************************//
void select_next_sensor()
{
   sensor_index++;            // cycle index state 0-7 w/rollover
   if(sensor_index >= MAXSENSORS)
   {
      sensor_index = 0;
   }
   CPSCON1 = sensor_index;    // Select external pin CPS0..CPS7
}

//****************************************************************************//
//*     MAIN FUNCTION
//****************************************************************************//
void main(void)
{
   Init();
   sensor_index = 0;          // Start program ready to scan first channel

   while(true)               
        {
          // React to button presses in application main-loop
         if (!input(OUT_POLARITY))        // default polarity pin is set to 0
            {
               if (keypad.PAD0)
                  {
                     output_high(OUTPUT0);
                  } else {
                     output_low(OUTPUT0);
                  }
               if (keypad.PAD1)
                  {
                     output_high(OUTPUT1);
                  } else {
                     output_low(OUTPUT1);
                  }
               if (keypad.PAD2)
                  {
                     output_high(OUTPUT2);
                  } else {
                     output_low(OUTPUT2);
                  }
               if (keypad.PAD3)
                  {
                     output_high(OUTPUT3);
                  } else {
                     output_low(OUTPUT3);
                  }
               if (keypad.PAD4)
                  {
                     output_high(OUTPUT4);
                  } else {
                     output_low(OUTPUT4);
                  }
               if (keypad.PAD5)
                  {
                     output_high(OUTPUT5);
                  } else {
                     output_low(OUTPUT5);
                  }
               if (keypad.PAD6)
                  {
                     output_high(OUTPUT6);
                  } else {
                     output_low(OUTPUT6);
                  }
               if (keypad.PAD7)
                  {
                     output_high(OUTPUT7);
                  } else {
                     output_low(OUTPUT7);
                  }
            }
           
         if (input(OUT_POLARITY))        // default polarity pin is set to 1
            {
               if (keypad.PAD0)
                  {
                     output_low(OUTPUT0);
                  } else {
                     output_high(OUTPUT0);
                  }
               if (keypad.PAD1)
                  {
                     output_low(OUTPUT1);
                  } else {
                     output_high(OUTPUT1);
                  }
               if (keypad.PAD2)
                  {
                     output_low(OUTPUT2);
                  } else {
                     output_high(OUTPUT2);
                  }
               if (keypad.PAD3)
                  {
                     output_low(OUTPUT3);
                  } else {
                     output_high(OUTPUT3);
                  }
               if (keypad.PAD4)
                  {
                     output_low(OUTPUT4);
                  } else {
                     output_high(OUTPUT4);
                  }
               if (keypad.PAD5)
                  {
                     output_low(OUTPUT5);
                  } else {
                     output_high(OUTPUT5);
                  }
               if (keypad.PAD6)
                  {
                     output_low(OUTPUT6);
                  } else {
                     output_high(OUTPUT6);
                  }
               if (keypad.PAD7)
                  {
                     output_low(OUTPUT7);
                  } else {
                     output_high(OUTPUT7);
                  }
            }
         }
}
maheshkuruganti
Guest







MTouch Capacitive Sensor
PostPosted: Mon May 11, 2009 2:45 am     Reply with quote

Hi,
I know this is a inactive thread but can you please tell me if the above code works and also if there is a circuit or pcb which I can look at for the above code to be used.Thanks
Fram_fr



Joined: 29 Oct 2008
Posts: 13

View user's profile Send private message

PostPosted: Thu May 21, 2009 4:53 pm     Reply with quote

Sorry, I've no test this code because no hardware for the moment.
The design of the pcb for the capacitive touch is done but not manufactured.

Regards,
Franck
Krunal Thummar



Joined: 02 Aug 2017
Posts: 1

View user's profile Send private message Send e-mail

Re: Microchip Mtouch capacitive touch sensor
PostPosted: Wed Aug 02, 2017 2:33 am     Reply with quote

To : Fram_fr,

From : krunal_c_thummar@yahoo.com // Gujarat-India //

Dear Sir,
Based on your code, I have implemented this code in 'C' and with microchip PIC16F722A controller. It is working absolutely 100% fine.

Code:

//------------------------------------------------------------------------------------//
//   PIC16F722A Capsense Module Test
 
//   Purpose: Illustrate the use of the Capacitive Sensing Module
//   This program scans 8 pads on a PCB. Each pad is sensed by the Capacitive
//   Sensing Module at a fixed interval.  The frequency of each pad at rest is averaged.
//   When a pad is touched, the frequency on the Cap. sensing module changes due to the
//   extra capacitance from the finger.  The change in frequency is noted and the LEDs
//   light up to indicate which button was pressed.
//   As frequency is reduced, counting of Timer1 counts is also reduced.

//   RB0:RB5,RA4:RA5 as touch pads (Analog inputs)
//   PORTC as LED outputs (Digital outputs)
//------------------------------------------------------------------------------------//

#include<pic.h>
#include<htc.h>
#include<pic16f722a.h>

__CONFIG(FOSC_INTOSCIO & WDTE_OFF & PWRTE_OFF & MCLRE_OFF & CP_OFF & BOREN_OFF & BORV_19 & PLLEN_ON);
__CONFIG(VCAPEN_DIS);
   
//   SENSOR COUNT DEFINITIONS
#define   MAXSENSORS         8         //   8
#define   NUM_AVG_PASSES      3          //   3
#define   NUM_STAB_PASSES      5         //   5   
#define   HYSTERESIS_VALUE   30          //   30

#define   LED_0   RC0
#define   LED_1   RC1
#define   LED_2   RC2
#define   LED_3   RC3
#define   LED_4   RC4
#define   LED_5   RC5
#define   LED_6   RC6
#define   LED_7   RC7

#define output_default_io_polarity      1   //   default io = 1. When pad is touched, output io = 0.
//#define output_default_io_polarity   0   //   default io = 0. When pad is touched, output io = 1.

unsigned int timer1_val[MAXSENSORS];
unsigned int timer1_raw[MAXSENSORS];
unsigned int btn_average[MAXSENSORS];
unsigned int trip_val[MAXSENSORS];
   
unsigned char stabilize_pass = 0;
unsigned char average_pass = 0;
unsigned char btn_pressed = 0;
unsigned char sensor_index = 0;
unsigned char x = 0;
unsigned char button_0 = 0,button_1 = 0,button_2 = 0,button_3 = 0;
unsigned char button_4 = 0,button_5 = 0,button_6 = 0,button_7 = 0;

//   TIMER1 RESET FUNCTION - Reset and restart timer 1
void reset_timer1()
{
   TMR1   = 0;   //   clear TIMER1 resister
   TMR1ON   = 1;     //   start TIMER1
}

//   SELECT NEXT CPS CHANNEL
void select_next_sensor()
{
   sensor_index++;               //   cycle index state 0-7 w/rollover
   if(sensor_index >= MAXSENSORS)
      sensor_index = 0;

   CPSCON1 = sensor_index;         //   Select external pin CPS0.....CPS7
}

//------------------------------------------------------------------------------------//
//   ISR() Interrupt Service Routine
//   Reads values of TMR1 corresponding to each button/sensor
//   and makes decision if button/sensor has been touched.
//------------------------------------------------------------------------------------//

static void interrupt isr(void)         //   Timer0 Interrupt
{
   if(T0IF == 1)    
      T0IF = 0;                  //   clear interrupt flag
      
   if(TMR1GIF == 1)
   {    
      TMR1GIF   = 0;               //   clear interrupt flag
      TMR1ON   = 0;               //   TIMER1 off

      timer1_val[sensor_index] = TMR1;
      timer1_raw[sensor_index] = timer1_val[sensor_index] * 16;
     
      //stabilize the btn_average value
      if(stabilize_pass < NUM_STAB_PASSES)
      {
         stabilize_pass++;
         btn_average[sensor_index] = timer1_raw[sensor_index];
         reset_timer1();
         
         if((stabilize_pass == NUM_STAB_PASSES) && (sensor_index < (MAXSENSORS - 1)))
         {
            stabilize_pass = 0;
            select_next_sensor();
         }
      }
      else
         {
         //check for button pressed
         if(timer1_raw[sensor_index] < (btn_average[sensor_index] - trip_val[sensor_index]))
         {
            switch(sensor_index)
            {
               case 0:   button_0=1;   break;   //   button_0 is touched
               case 1:   button_1=1;   break;
               case 2:   button_2=1;   break;   
               case 3: button_3=1;   break; 
               case 4: button_4=1;   break;   
               case 5: button_5=1;   break; 
               case 6: button_6=1;   break; 
               case 7: button_7=1;   break; 
            }
         }
         else if(timer1_raw[sensor_index] > (btn_average[sensor_index] - trip_val[sensor_index])+ HYSTERESIS_VALUE)
         {
            switch(sensor_index)
            {
               case 0:   button_0=0;   break;   //   button_0 is not touched
               case 1:   button_1=0;   break;
               case 2:   button_2=0;   break;   
               case 3: button_3=0;   break; 
               case 4: button_4=0;   break;   
               case 5: button_5=0;   break; 
               case 6: button_6=0;   break; 
               case 7: button_7=0;   break; 
            }
         }
   
         if(timer1_raw[sensor_index] > (btn_average[sensor_index])) 
            btn_average[sensor_index] = btn_average[sensor_index] + (timer1_val[sensor_index] - (btn_average[sensor_index] / 16)); 
         
         //compute average
         average_pass++;
         if(average_pass == NUM_AVG_PASSES)
         {
            btn_average[sensor_index] = btn_average[sensor_index] + (timer1_val[sensor_index] - (btn_average[sensor_index] / 16));
            average_pass = 0;
            select_next_sensor();
         }
         reset_timer1();
      }
   }
}   

//   MAIN FUNCTION
void main(void)
{   
   OSCCON = 0b00110000;         //   16MHz Internal Oscillator
   
   ANSELA = 0b00110000;         //   CPS6:CPS7 as analog input
   ANSELB = 0b00111111;         //   CPS0:CPS5 as analog input
   TRISA = 0b00110000;            //   RA4:RA5 as input
   TRISB = 0b00111111;            //   RB0:RB5 as input
   TRISC = 0;                 //   PORTC as digital output
     
   //   Initialize for timers (Timer0 time base 4ms)
   OPTION_REG = 0b11000101;      //   Timer0 INIT CLK ON FOSC/4
   T0IF = 0;                  //   Clear Timer0 interrupt flag
   T0IE = 1;                  //   enable Timer0 interrupt
   
   //   SETUP TIMER1
   T1CON   = 0b11000101;         //   Clock source is Capacitive Sensing Oscillator, 1:1 prescale, Timer1 enable,
   T1GCON    = 0b11100001;         //   Timer1 gate init with Timer0
   TMR1GIF = 0;               //   clear gate interrupt flag
   TMR1GIE = 1;               //   enable gate interrupt    
   PEIE = 1;                  //   enable peripheral interrupts
   GIE    = 1;                  //   enable global interrupts
   
   //   SETUP CAP SENSE MODULE
   CPSCON0 = 0b10001100;         //   Cap Sense control settings
   CPSCON1 = 0;               //   init to channel select = 0 (4 LSb's)
     
   //   below values set sensitivity, less value effects more sensitive touch pad
   trip_val[0] = 120;            //   tripping value for pad-0         
   trip_val[1] = 120;             //   tripping value for pad-1
   trip_val[2] = 120;             //   tripping value for pad-2
   trip_val[3] = 120;             //   tripping value for pad-3
   trip_val[4] = 120;             //   tripping value for pad-4
   trip_val[5] = 120;             //   tripping value for pad-5
   trip_val[6] = 120;             //   tripping value for pad-6
   trip_val[7] = 120;            //   tripping value for pad-7
   
   for(x=0;x<MAXSENSORS;x++)      //   initially make all avarage values zero
   btn_average[x] = 0;    
   
   sensor_index = 0;            //   Start program ready to scan first channel
   
   if(output_default_io_polarity==1)   //   make all outputs low or high
      PORTC = 0xFF;
   else
      PORTC = 0x00;
      
   while(1)
   {    
      //   React to button presses in application main-loop
      if(output_default_io_polarity==1)
      {
         if(button_0)      //   if pad-0 is touched
            LED_0=0;      //   make op low
         else
            LED_0=1;
      
         if(button_1)
            LED_1=0;
         else
            LED_1=1;         
      
         if(button_2)
            LED_2=0;
         else
            LED_2=1;              
      
         if(button_3)
            LED_3=0;
         else
            LED_3=1;
            
         if(button_4)
            LED_4=0;
         else
            LED_4=1;
                     
         if(button_5)
            LED_5=0;
         else
            LED_5=1;
      
         if(button_6)
            LED_6=0;
         else
            LED_6=1;
            
         if(button_7)
            LED_7=0;
         else
            LED_7=1;
      }      
      else if(output_default_io_polarity==0)
      {
         if(button_0)       //   if pad-0 is touched
            LED_0=1;      //   make op high
         else
            LED_0=0;
      
         if(button_1)
            LED_1=1;
         else
            LED_1=0;         
      
         if(button_2)
            LED_2=1;
         else
            LED_2=0;              
      
         if(button_3)
            LED_3=1;
         else
            LED_3=0;
            
         if(button_4)
            LED_4=1;
         else
            LED_4=0;
                     
         if(button_5)
            LED_5=1;
         else
            LED_5=0;
      
         if(button_6)
            LED_6=1;
         else
            LED_6=0;
            
         if(button_7)
            LED_7=1;
         else
            LED_7=0;
      }   
   }
}


// krunal_c_thummar@yahoo.com      // Gujarat-India //
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