|
|
View previous topic :: View next topic |
Author |
Message |
Fram_fr
Joined: 29 Oct 2008 Posts: 13
|
Microchip Mtouch capacitive touch sensor |
Posted: Mon Dec 08, 2008 6:20 pm |
|
|
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
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
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
|
|
Posted: Mon Dec 08, 2008 7:22 pm |
|
|
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
|
|
Posted: Wed Dec 10, 2008 5:46 am |
|
|
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 |
|
|
Fram_fr
Joined: 29 Oct 2008 Posts: 13
|
|
Posted: Thu Dec 11, 2008 6:05 pm |
|
|
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 |
Posted: Mon May 11, 2009 2:45 am |
|
|
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
|
|
Posted: Thu May 21, 2009 4:53 pm |
|
|
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
|
Re: Microchip Mtouch capacitive touch sensor |
Posted: Wed Aug 02, 2017 2:33 am |
|
|
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 // |
|
|
|
|
|
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
|