Changing sensitivity of touchRead()

Status
Not open for further replies.

ianhattwick

New member
As discussed in this old thread, you can change the sensitivity of the capacitive sensing performed by touchRead. To do this, like Paul suggested, you can go in and change some defined constants in the touch.c file -> hardware/teensy/cores/teensy3/touch.c. I went ahead and wrote a new function to allow for changing those values directly from my teensy code and thought I'd share.

There are three things that need to happen to do this:

1) Replace the defined values with variables. In touch.c the defined variables which set touchRead sensitivity are CURRENT, NSCANS, and PRESCALE. I commented out each occurrence of those defines (one for each teensy core, if you look at the touch.c code) and replaced them with new variables:
uint8_t CURRENT;
uint8_t NSCAN;
uint8_t PRESCALE;

To make it easy, here is the code from the first #if to the last #endif - the only change is the new variables:

Code:
#if defined(__MK20DX128__) || defined(__MK20DX256__)
// These settings give approx 0.02 pF sensitivity and 1200 pF range
// Lower current, higher number of scans, and higher prescaler
// increase sensitivity, but the trade-off is longer measurement
// time and decreased range.
uint8_t CURRENT = 2;
uint8_t NSCAN = 9;
uint8_t PRESCALE = 2;
//#define CURRENT   2 // 0 to 15 - current to use, value is 2*(current+1), default 2
//#define NSCAN     9 // number of times to scan, 0 to 31, value is nscan+1, default 9
//#define PRESCALE  2 // prescaler, 0 to 7 - value is 2^(prescaler+1), default 2
static const uint8_t pin2tsi[] = {
//0    1    2    3    4    5    6    7    8    9
  9,  10, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255,  13,   0,   6,   8,   7,
255, 255,  14,  15, 255,  12, 255, 255, 255, 255,
255, 255,  11,   5
};

#elif defined(__MK66FX1M0__)
uint8_t CURRENT = 2;
uint8_t NSCAN = 9;
uint8_t PRESCALE = 2;
//#define CURRENT   2
//#define NSCAN     9
//#define PRESCALE  2
static const uint8_t pin2tsi[] = {
//0    1    2    3    4    5    6    7    8    9
  9,  10, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255,  13,   0,   6,   8,   7,
255, 255,  14,  15, 255, 255, 255, 255, 255,  11,
 12, 255, 255, 255, 255, 255, 255, 255, 255, 255
};

#elif defined(__MKL26Z64__)
uint8_t CURRENT = 9;
uint8_t NSCAN = 2;
//#define NSCAN     9
//#define PRESCALE  2
static const uint8_t pin2tsi[] = {
//0    1    2    3    4    5    6    7    8    9
  9,  10, 255,   2,   3, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255,  13,   0,   6,   8,   7,
255, 255,  14,  15, 255, 255, 255
};

#endif

2) Add the function to change the variables from your teensy sketch:
Code:
void setTouchReadSensitivity(uint8_t t_current, uint8_t num_scans, uint8_t t_prescale){
	//check the new values are in range
        if(t_current>15) t_current=15; 
	if(num_scans>31) num_scans=31;
	if(t_prescale>7) t_prescale=7;

        //update the variables
	CURRENT=t_current; //0 to 15 - current to use, value is 2*(current+1), default 2
	NSCAN=num_scans; //number of times to scan, 0 to 31, value is nscan+1, default 9
	PRESCALE=t_prescale; //prescaler, 0 to 7 - value is 2^(prescaler+1), default 2
}

3) Add the function prototype - this is in the hardware/teensy/cores/teensy3/core_pins.h file. I added the new prototype right below the touchRead() prototype, line 1480.
Code:
void setTouchReadSensitivity(uint8_t t_current, uint8_t num_scans, uint8_t t_prescale);

And, voila, the ability to change the sensitivity of the touchRead capacitive sensing on the fly -- just call the function: setTouchReadSensitivity(9,5,2).

I've only just done this today and it seems to work without problems, but YMMV.
 
This is great! Have you found how changing these variables affects sensitivity? I'm working on a device where I'd like to sense through a few mm of plastic, but the default settings don't seem to allow this.
 
I posted code in another thread that use interrupts for touch sensor, and initialization is self calibrating so you don't need to do trial and error with different parameter values. The code prints out the threshold/base value, so you can code ON/OFF base on this value.
 
Up to this point I've been doing the trial and error approach (hi doughboy!) and am still working on the first final implementation. I'll post here with what my final results are.

Your post looks great, doughboy - certainly better than manually changing the touch.c file. I'd still rather set the touch settings once and then not have them auto-calibrate - for my applications, I'm not looking for binary input but continuous at range - and I generally implement a continuously updating baseline based on how the Cypress capsense works. Maybe the best thing would be to create a reimplementation of the touch functions as you did.
 
the isr code will auto recalibrate as needed (on the fly at runtime). you can move touch plates, change size, etc. and the code will auto recalibrate. The base value is different with my circuit on breadboard vs soldered, but I did not have to change the code. it auto adjusts.
I simply implemented the recommended logic as described in the datasheet.
 
Last edited:
Status
Not open for further replies.
Back
Top