Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 10 of 10

Thread: Teensy 3.0 capactive touch

  1. #1

    Teensy 3.0 capactive touch

    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!

  2. #2
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,253
    Just use touchRead(pin) and it will automatically configure the pin for you, just like analogRead() does.

  3. #3
    Thanks!

    I also found an example for those searching the forums about how to implement touchRead.

    http://www.instructables.com/id/Over...ng-the-Teensy/

  4. #4
    Junior Member
    Join Date
    Oct 2012
    Posts
    17

    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);
    }
    ====================

  5. #5
    Junior Member
    Join Date
    Oct 2012
    Posts
    17

    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?

    Larry

  6. #6
    Senior Member ZTiK.nl's Avatar
    Join Date
    Dec 2012
    Location
    Amsterdam
    Posts
    179
    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
    Last edited by ZTiK.nl; 01-28-2013 at 05:22 PM. Reason: removed smiley

  7. #7
    Junior Member
    Join Date
    Oct 2012
    Posts
    17

    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);
     }
    ====================

  8. #8
    Administrator Robin's Avatar
    Join Date
    Oct 2012
    Location
    PJRC Global Headquarters
    Posts
    319
    Quote Originally Posted by LarryP View Post
    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?

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

  9. #9
    Junior Member
    Join Date
    Oct 2012
    Posts
    17
    Quote Originally Posted by Robin View Post
    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

  10. #10
    Junior Member
    Join Date
    Oct 2012
    Posts
    17

    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
    Attached Files Attached Files

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •