Teensy 3.0 capactive touch

Status
Not open for further replies.

rockfirstlast

New member
How do you initialize a pin for built-in capacitive touch?

pinMode(1, ???? )

I know everything is really new, but is there any example documentation for the new touchRead feature? Thanks!
 
A time bounded variant of touchRead()

Greetings all,

First off, I'm quite impressed with the resolution of touchRead measurements. 1/20 of a pF is way more sensitivity than I would have expected!

Due to my control-systems perspective, I'm wary a measurement that can take a variable time to return. So, I decided to code up a time bounded variant of Paul's touchRead() function. TouchReadTimeLim() takes an additional parameter, a maximum number of microseconds for the measurement. If the measurement reaches the max time before completion, it returns a negative value, usually -1, but occasionally the negative of a somewhat sane looking capacitance measurement. I've left all the other capacitance measuring parameters exactly as in touchRead().

@Paul,
I don't know what your preferred form is for patches; so please forgive me if pasting in longish chunks of code in a forum post isn't what you want. Please let me know if you'd like me to send you the modified files.

I modified two files, touch.c and core_pins.h and wrote a simple test script, TestTouchReadTimeLim. I'll paste the mods and the test code at the end of this post. I'm using the beta12 software on a Windows7 machine.

For testing, I put a short wire on a pin that does touchRead plus a 22 pF cap to ground (in addition to the capacitance from a solderless breadboard.) Here's a test run using 250 uSec for the timeout parameter:

1931 -- 22 pF cap + wire
1940
1939
1963
1932
1942
2217 -- 22 pF cap + wire + me touching wire's insulation
2219
2284
2307
2233
2287
-1 -- 22 pF cap + wire + me touching wire itself adds enough capacitance to trigger the timeout
-1
-1
-1
-1

====================
Code added to the end of touch.c:

/* **************************************************************
* touchReadTimeLim: a time-bounded version of Paul's touchRead()
* Larry Pfeffer, ursine @t gmail d0t c0m
* 27Jan2012: tested OK with sketch touchReadTestTimeBound
*
* To make it accessable, I've added a function
* prototype for touchReadTimeLim(...)to file core_pins.h,
* below the prototype for touchRead() itself:
*
* int touchReadTimeLim(uint8_t pin, unsigned Tmax); // Experimental LEP
*
************************************************************** */


#include <limits.h> /* for ULONG_MAX. Eventually move to top of
*file with other includes */

#include <stdlib.h> /* For abs(), if not included elsewhere.
*Ditto re moving to top of file */


unsigned long unwrapMicros(unsigned long curr, unsigned long prev)

/* Utility function to calculate the delta T between results
* of two calls to micros(). Robust to one rollover of the
* micros() counter.
*
* Eventually this function could be moved into some file/lib
* separate from touchRead* and renamed unwrapUL(?)
*/

{
if (curr >= prev) {
return (curr - prev);
} else {
/* the casts below may not be absolutely neccessary,
* but using them is a bit of extra insurance. */

return (unsigned long)( (ULONG_MAX - (unsigned long long)prev)
+ ((unsigned long long)curr + 1) );

} // ends if/else
}


int touchReadTimeLim(uint8_t pin, unsigned Tmax) // Tmax in uSec

// Like touchRead, but always returns within Tmax microseconds
{
uint32_t ch;
unsigned long Tstart;

Tstart = micros(); // First thing, record start time

if (pin >= NUM_DIGITAL_PINS) return 0;
ch = pin2tsi[pin];
if (ch == 255) return 0;

*portConfigRegister(pin) = PORT_PCR_MUX(0);
SIM_SCGC5 |= SIM_SCGC5_TSI;
TSI0_GENCS = 0;
TSI0_PEN = (1 << ch);
TSI0_SCANC = TSI_SCANC_REFCHRG(3) | TSI_SCANC_EXTCHRG(CURRENT);
TSI0_GENCS = TSI_GENCS_NSCN(NSCAN) | TSI_GENCS_PS(PRESCALE) | TSI_GENCS_TSIEN | TSI_GENCS_SWTS;

delayMicroseconds(10);

/* Must unwrap the result from micros()
* to avoid getting wrong results when -- rarely but possibly --
* micros() rolls over during the measurment.
*/

/* while we haven't yet reached the timeout:
* note that the unwrap gives a deltaT,
* so must compare to Tmax, not to (Tstart + Tmax) */

while (unwrapMicros(micros(), Tstart) < (Tmax))
{
if (TSI0_GENCS & TSI_GENCS_SCNIP) { // if not ready
delayMicroseconds(1); // wait
} else {
delayMicroseconds(1); // not sure delay still necc.

// Normal return
return *((volatile uint16_t *)(&TSI0_CNTR1) + ch);
}
} // ends while micros()

// If we timeout, return negative of probably garbage value
// note extra -1, so timeout result is neg even if register
// reads zero when read before the measurment completes.

return -1 - abs(*((volatile uint16_t *)(&TSI0_CNTR1) + ch));
}

====================
One line of code added to core_pins.h, just below the prototype for touchRead():

int touchReadTimeLim(uint8_t pin, unsigned Tmax); // Experimental LEP

====================
The test sketch:


/* TestTouchReadTimeLim: a sketch to test function touchReadTimeLim, which
* is a time-bounded variant of touchRead.

#include <limits.h>

/* Note: for this test, core_pins now has declaration of touchReadTimeLim" */

//int touchReadTimeLim(uint8_t pin, unsigned long int Tmax); // should go into a header file when working

#define CAP_PIN (A8) /* change to whatever pin you use */
#define TOUCH_MAX_USEC (250) /* Paul's touchRead comment says 250 uSec for approx 33 pF */

void setup() {
Serial.begin(115200);
}

int touchReadAvg(int pin, int nSamp, long int maxT)
{
int i;
int runningSum = 0;
int cap;

for(i=0; i<nSamp; i++) {
cap = touchReadTimeLim(pin, maxT);
if (cap >= 0) {
runningSum = runningSum + cap;
} else {
// Serial.print("Timeout in touchReadTimeLim: ");
// Serial.println(cap);
return -1; // error return if any sample times out
}
}
return runningSum/nSamp;
}


void loop()
{
//Serial.println(touchReadAvg(CAP_PIN, 32, TOUCH_MAX_USEC)); // with averaging

Serial.println(touchReadTimeLim(CAP_PIN, TOUCH_MAX_USEC)); // without averaging

delay(500);
}
====================
 
Cannot upload files for touchReadTimeLim

Nuts, the forum software ate my code's indenting.

@Paul,
I tried to attach the files, but I'm getting invalid file type errors for .c, ,h and .ino files. Am I doing something wrong, or are those file types blocked for some reason? :confused:

Larry
 
If you put your code inside [ CODE] and [ /CODE] (remove spaces though), then the indentation should stick.
I never uploaded a file here except images, so I can't help with that, sry

(below the quick-reply box is a button 'Go Advanced' which will show more options like the
Code:
 tags[/SIZE]
 
Last edited:
touchReadTimeLim code, this time with formatting preserved

Here are the three chunks of code for touchReadTimeLim -- this time with their indentation preserved. :)
If you have any comments or corrections, please let me know.

Thanks,

Larry

====================
Code added to the end of touch.c:

Code:
/* **************************************************************
 * touchReadTimeLim: a time-bounded version of Paul's touchRead() 
 * Larry Pfeffer, ursine @t gmail d0t c0m 
 * 27Jan2012: tested OK with sketch touchReadTestTimeBound
 * 
 * To make it accessable, I've added a function 
 * prototype for touchReadTimeLim(...)to file core_pins.h, 
 * below the prototype for touchRead() itself: 
 *
 * int touchReadTimeLim(uint8_t pin, unsigned Tmax); // Experimental LEP 
 *
 ************************************************************** */


#include <limits.h> 	/* for ULONG_MAX.  Eventually move to top of 
				 *file with other includes */

#include <stdlib.h> 	/* For abs(), if not included elsewhere. 
				 *Ditto re moving to top of file */


unsigned long unwrapMicros(unsigned long curr, unsigned long prev)

 /* Utility function to calculate the delta T between results 
  * of two calls to micros().  Robust to one rollover of the 
  * micros() counter.
  *
  * Eventually this function could be moved into some file/lib 
  * separate from touchRead* and renamed unwrapUL(?)
  */

 {
   if (curr >= prev) {
     return (curr - prev);
   } else {
		/* the casts below may not be absolutely neccessary, 
		 * but using them is a bit of extra insurance. */

       return (unsigned long)( (ULONG_MAX - (unsigned long long)prev) 
			+ ((unsigned long long)curr + 1) );

   } // ends if/else
 } 
 

int touchReadTimeLim(uint8_t pin, unsigned Tmax) // Tmax in uSec

// Like touchRead, but always returns within Tmax microseconds 
{
	uint32_t ch;
	unsigned long Tstart;

	Tstart = micros(); // First thing, record start time

	if (pin >= NUM_DIGITAL_PINS) return 0;
	ch = pin2tsi[pin];
	if (ch == 255) return 0;

	*portConfigRegister(pin) = PORT_PCR_MUX(0);
	SIM_SCGC5 |= SIM_SCGC5_TSI;
	TSI0_GENCS = 0;
	TSI0_PEN = (1 << ch);
	TSI0_SCANC = TSI_SCANC_REFCHRG(3) | TSI_SCANC_EXTCHRG(CURRENT);
	TSI0_GENCS = TSI_GENCS_NSCN(NSCAN) | TSI_GENCS_PS(PRESCALE) | 	TSI_GENCS_TSIEN | TSI_GENCS_SWTS;

	delayMicroseconds(10);

	/* Must unwrap the result from micros() 
	 * to avoid getting wrong results when -- rarely but possibly --  
	 * micros() rolls over during the measurment.
	 */

	/* while we haven't yet reached the timeout: 
	 * note that the unwrap gives a deltaT, 
	 * so must compare to Tmax, not to (Tstart + Tmax) */

	while (unwrapMicros(micros(), Tstart) < (Tmax)) 
	{
		if (TSI0_GENCS & TSI_GENCS_SCNIP) {	// if not ready
			delayMicroseconds(1);			// wait
		} else {
			delayMicroseconds(1); // not sure delay still necc.

			// Normal return
			return *((volatile uint16_t *)(&TSI0_CNTR1) + ch);
		}
	} // ends while micros()

	// If we timeout, return negative of probably garbage value
	// note extra -1, so timeout result is neg even if register 
	// reads zero when read before the measurment completes.

	return -1 - abs(*((volatile uint16_t *)(&TSI0_CNTR1) + ch));
}


====================
One line of code added to core_pins.h, just below the prototype for touchRead():

Code:
int touchReadTimeLim(uint8_t pin, unsigned Tmax); // Experimental LEP

====================
The test sketch:

Code:
/* TestTouchReadTimeLim: a sketch to test function touchReadTimeLim, which 
 * is a time-bounded variant of touchRead.

#include <limits.h>

/* Note: for this test, core_pins now has declaration of touchReadTimeLim" */

//int touchReadTimeLim(uint8_t pin, unsigned long int Tmax);  // should go into a header file when working

#define CAP_PIN (A8)          /* change to whatever pin you use */
#define TOUCH_MAX_USEC (250)  /* Paul's touchRead comment says 250 uSec for approx 33 pF */

void setup() {
   Serial.begin(115200);
 }

 int touchReadAvg(int pin, int nSamp, long int maxT)
 {
   int i;
   int runningSum = 0;
   int cap;
   
   for(i=0; i<nSamp; i++) {
     cap = touchReadTimeLim(pin, maxT);
     if (cap >= 0) {
       runningSum = runningSum + cap;
     } else {
       // Serial.print("Timeout in touchReadTimeLim: ");
       // Serial.println(cap);
       return -1;  // error return if any sample times out
     }  
   } 
 return runningSum/nSamp;  
 }
 
 
 void loop()                     
 {
   //Serial.println(touchReadAvg(CAP_PIN, 32, TOUCH_MAX_USEC)); // with averaging
   
   Serial.println(touchReadTimeLim(CAP_PIN, TOUCH_MAX_USEC)); // without averaging
   
   delay(500);
 }

====================
 
Nuts, the forum software ate my code's indenting.

@Paul,
I tried to attach the files, but I'm getting invalid file type errors for .c, ,h and .ino files. Am I doing something wrong, or are those file types blocked for some reason? :confused:

Larry

You didn't do anything wrong. I've updated the forum configuration to allow the following file types:
.c
.cpp
.h
.ino
.pde
 
You didn't do anything wrong. I've updated the forum configuration to allow the following file types:
.c
.cpp
.h
.ino
.pde

Robin,

Thanks for making those file types uploadable. I think that'll make it easier for people on this forum to help one another.

Larry
 
Modified files for touchReadTimeLim attached (I hope)

If all goes well, the two modified files in the Arduino_1.0.3 and Paul's beta12 teensy3 software, namely touch.c and core_pins.h should be attached to this forum post. Also included is the Arduino sketch that produced the test results in my first post in this thread.

Larry
 

Attachments

  • TestTouchReadTimeLim.ino
    1.2 KB · Views: 264
  • core_pins.h
    25.7 KB · Views: 800
  • to.c
    4.4 KB · Views: 286
Status
Not open for further replies.
Back
Top