touchRead Sensor Size

Status
Not open for further replies.

mark_m

Active member
Is there any limit to the size of surface that can be used for capacitive sensing using toughRead on a Teensy3.2?

I did some successful testing with a sheet of copper about a square foot that worked but now am having some problems using four new sensors (on four pins).

Could I run into limits for current capacity for charging, or time to charge limits?
 
Thinking back, my original test, about six months ago, was with an arduino using the capacitiveSensor library. I was able to get sensitivity out to about two feet. I assumed I would have similar results with the Teensy but I wonder if the capacitiveSensor setup has the potential for greater range, is this possible?

The other thing that's changed is I have shielded leads running up to the sensors. Could shielding the leads have an adverse effect?
 
Nope. Shielding is a good idea!

The Teensy 3.2 is 3.3V so you probably won't be able to get quite the same results but I imagine it should work
 
Nope. Shielding is a good idea!

The Teensy 3.2 is 3.3V so you probably won't be able to get quite the same results but I imagine it should work

That's a good point. I wonder if there's a way to amplify the capacitance somehow electrically.
 
Everything is described in the reference manual. If you have to deal with big capacitances, you should adjust the current and divider values of the oscillators. The Teensy's touch hardware is much different from the usual RC time delay circuits.
 
Everything is described in the reference manual. If you have to deal with big capacitances, you should adjust the current and divider values of the oscillators. The Teensy's touch hardware is much different from the usual RC time delay circuits.

Thanks. Just took a quick look and saw that there's some adjustments available 'though I did not see how to achieve those (not saying it's not there:), are they something I can do simply in software?
 
are they something I can do simply in software?

Yes. Find and edit touch.c. Experiment with CURRENT, NSCAN and PRESCALE.

You should not need to restart Arduino. Simply save the file and when you upload, Arduino will detect the file is newer and rebuild that code automatically.

The file has more than 1 copy of those settings, so make sure you're editing the ones for the board you're using.

Obviously keeping written notes for the settings you tried and results you measured will be much more effective than just trying things and attempting to remember in your head which changes did what.
 
Yes. Find and edit touch.c. Experiment with CURRENT, NSCAN and PRESCALE.

You should not need to restart Arduino. Simply save the file and when you upload, Arduino will detect the file is newer and rebuild that code automatically.

The file has more than 1 copy of those settings, so make sure you're editing the ones for the board you're using.

Obviously keeping written notes for the settings you tried and results you measured will be much more effective than just trying things and attempting to remember in your head which changes did what.

Excellent. I'll of course keep an unaltered copy of the file as s.o.p.
Guessing I'll up the current to account for the large surface area (I'm using about a square foot of fine brass cloth) and see what that does, go from there doing one thing at a time.

Much obliged for these answers.
-mm
 
Well it only took me about 40 minutes to find touch.c... Macs are so weird... Anyway I see that CURRENT is defined twice and NSCAN and PRESCALE are defined three times. Assuming I should put same values in all the defines for each of those yes?
 
Well now I've done it:) I think editing the file on a mac maybe didn't agree with things. As soon as I saved the file touch.c, even if I undid any changes, it started erring with unknown classes or something, looked like a formatting problem. After messing with it unsuccessfully, I decided to reinstall both arduino and teensyduino.

Now touchRead is not recognized (same code that's been working for months). Arduino 1.6.7, when I click About it shows teensyduino1.27. I see touch.c on disk, but it's not being picked up by Arduino.

It installs in a weird place, but it's automatic and I have no choice where it installs:
arduino.app|contents|java|hardware|teensy|avr|cores|teensy3

Is this correct? Arduino should just pick it up when it opens, no?
 
Did you select the Teensy 3.1/3.2 on boards? If so and the Arduino IDE you did the Teensyduino install are the same and the one you are running from - there must be something else odd?
 
Thats o's of the reasons I switched to jantje's eclipseArduino which allows to edit simultaneously main code and libraries in different tabs of the same IDE, even on a Mac where all the Teensyduino stuff is rather hidden in the virtual Arduino.app folder package.

One might also add there as much private library paths as one wants which allows easy switching between the "official" libraries and modified versions.
 
Thats o's of the reasons I switched to jantje's eclipseArduino which allows to edit simultaneously main code and libraries in different tabs of the same IDE, even on a Mac where all the Teensyduino stuff is rather hidden in the virtual Arduino.app folder package.

One might also add there as much private library paths as one wants which allows easy switching between the "official" libraries and modified versions.
I will have to learn about that. I kind of hate when things are happening automatically and hidden. Thanks.
 
I know you said you are using 4 touch pins, but here is the code I use for 2 pins (pins32 and 33). You can probably expand this to 4.
With the 2 pins, I simulate 3 buttons (3rd button if both pins are touched at the same time).
I implemented the code exactly as described in the datasheet and is interrupt driven. Refer to the datasheet for description of the registers. I think the calibration part is essential, as I get different base value depending on what I connect the pins to.

Code:
void setup() {
  delay(2000);
  Serial.begin(115200);
  pinMode(13,OUTPUT);

  initTouch();
}

//unsigned long prev = 0;
volatile uint16_t base = 0;
volatile uint8_t button;

void loop() {
  static uint8_t lastbutton = 0;
  static uint8_t debounce = 0;
  if (lastbutton != button) {
    debounce = 0;
  } else  if (++debounce > 8) {
    debounce = 0;
    switch (button) {
      case 1: Serial.println("Enter");
          break;
      case 2: Serial.println("Up");
          break;
      case 3: Serial.println("Down");
          break;
    }
  }
  lastbutton=button;
//  unsigned long curr = millis();
//  if (curr - prev > 1000) {
//    Serial.println(val1);
//    Serial.println(val2);
//    prev=curr;
//  }
}

void tsi0_isr(void){
//  static uint8_t prev = 0;
//  uint8_t cur = 0;
  if (TSI0_GENCS & TSI_GENCS_OVRF) {
    TSI0_GENCS |= TSI_GENCS_OVRF;
    initTouch();
    return;
  }
  TSI0_GENCS |= TSI_GENCS_EOSF;
  uint16_t val1 = TSI0_CNTR11>>16;
  uint16_t val2 = TSI0_CNTR5 >> 16;
  *portToggleRegister(13) = 1; //comment this line to stop led blinking, this is to know isr is working.
  if (val1> base && val2 > base) {
    //enter button
    button = 1;
  } else if (val1> base && val2 < base) {
    //up button
    button = 2;
  } else if (val1 < base && val2 > base) {
    //down button
    button = 3;
  } else {
    button = 0;
  }
//  if (cur == prev) {
//    button = cur;
//  }
//  prev = cur;
}


void initTouch() {
  *portConfigRegister(32) = PORT_PCR_MUX(0);//pin32
  *portConfigRegister(33) = PORT_PCR_MUX(0);//pin33

  SIM_SCGC5 |= SIM_SCGC5_TSI;
  TSI0_PEN = _BV(11) | _BV(5);

  //calibrate touch pins
  TSI0_GENCS &= ~TSI_GENCS_TSIEN;
  TSI0_SCANC = TSI_SCANC_REFCHRG(3) | TSI_SCANC_EXTCHRG(2);
  TSI0_GENCS =  TSI_GENCS_NSCN(15) | TSI_GENCS_PS(4) | TSI_GENCS_TSIEN | TSI_GENCS_SWTS;
  while (!(TSI0_GENCS & TSI_GENCS_EOSF));
  uint16_t val1 = TSI0_CNTR11 >> 16;
  uint16_t val2 = TSI0_CNTR5 >> 16;
  base = val1>val2?val1:val2;
  base *= 1.2;
  //next 2 lines for debugging, comment out in final code
  Serial.print("Base value is ");
  Serial.println(base);
  TSI0_GENCS &= ~TSI_GENCS_TSIEN;
  TSI0_SCANC |= TSI_SCANC_SMOD(100);//TSI_SCANC_REFCHRG(3) | TSI_SCANC_EXTCHRG(2) | TSI_SCANC_SMOD(100) | TSI_SCANC_AMCLKS(0) | TSI_SCANC_AMPSC(0);
  TSI0_GENCS |= TSI_GENCS_STM | TSI_GENCS_ESOR | TSI_GENCS_TSIIE | TSI_GENCS_TSIEN;;//TSI_GENCS_NSCN(15) | TSI_GENCS_PS(4) | TSI_GENCS_STM | TSI_GENCS_ESOR | TSI_GENCS_TSIIE | TSI_GENCS_ERIE | TSI_GENCS_TSIEN;

  NVIC_SET_PRIORITY(IRQ_TSI, 128);
  NVIC_ENABLE_IRQ(IRQ_TSI);

}
 
Last edited:
I tried a bunch of settings in touch.c and didn't see much difference. I admit I was less than methodical about this. The manual gives the following guidance:

"Lower current, higher number of scans, and higher prescaler increase sensitivity, but the trade-off is longer measurement time and decreased range."

I assume here that sensitivity is referring to precision, and that number of scans is just filtering with a rolling average. Which of current and prescale should be pushed to which limit to maximize the physical distance that can be sensed with a large surface? Thanks for any ideas.

p.s. I did verify I was editing the same touch.c file that was being sourced:)
 
Figured out the problem if not yet the solution. Power supply noise. I'm running these things off no-name Meanwell-like switching power supplies and they are putting enough noise into the system that I need too many iterations of filtering the sensor data to have it perform properly. Hooked it all up to a 12V gel cell and bingo all was well.

So, I can't really run this system off of batteries, or at least greatly preferable not to. Any best guesses as to whether it's broadcast noise or line noise? I'm going to try just sticking an electrolytic capacitor across the p.s. 24VDC output and see if that's all it takes. Any starting points as to values? 100uF, 1000uF? I've got lots of caps of all sizes from various amplifier rebuilds to try out...
 
I have an old scope that sometimes works, I'll stick it on there today and try different caps and see if anything helps.
 
Yeah brought it down some with caps but not enough I guess. Cut the noise by about 60-70% but still really messes with the sensing. I think they're just really noisy and maybe are broadcasting some noise as well, 'though I have audio amplification happening a few inches away and it's quiet. But maybe higher frequency than audio.
 
Get a 200+ uH inductor and a couple of 1000+ uF caps. Make sure the inductor is rated for more than your current, and the capacitors rated for more than your voltage.
On the output from the power supply, hook up capacitor in parallel, inductor in series, second capacitor in parallel.
Now, you have a LC filter, which is much better than just a parallel C.
The corner frequency of those components would be about 250 Hz. Presumably the noise you're seeing is at a higher frequency than that?
Else, add more of each :)
 
Get a 200+ uH inductor and a couple of 1000+ uF caps. Make sure the inductor is rated for more than your current, and the capacitors rated for more than your voltage.
On the output from the power supply, hook up capacitor in parallel, inductor in series, second capacitor in parallel.
Now, you have a LC filter, which is much better than just a parallel C.
The corner frequency of those components would be about 250 Hz. Presumably the noise you're seeing is at a higher frequency than that?
Else, add more of each :)
The other way I'm thinking of going is just getting a transformer-based power supply. I tested a wall-wart today that was lying around and it worked fine. I need about 4 amps at 24V for some of the stuff I'm running so the wall wart was much too small but it at least demonstrated to me that the noise problem is probably high frequency noise from the switching. I'll see what's available in old-school power supplies as well as consider making up a filter as you described. I don't have any chokes so I'll be buying parts one way or the other:) Thanks for the suggestion - if I go the LC route could you recommend a spec for the inductor? Thanks again.
 
This might work: http://www.digikey.com/product-detail/en/abracon-llc/AIRD-02-221K/535-11415-ND/2660709
7 Amps rating, 220 uH, through hole.
Note that the capacitors are important, too -- without the "H" of capacitors bracketing the inductor, you don't get the filter steepness you want.
And if 1000 uF is too big for you, 100 uF instead will raise the rejection frequency by little over 3x (sqrt(10)) -- if 800 Hz is still good for you, that'll work, too.
 
Status
Not open for further replies.
Back
Top