Teensy touchRead() problems, right usage!?

Status
Not open for further replies.

jangodde

Member
Hello dear pjrc forum people,

i currently did a project where i used the Teensy touch pins.
Not having read a lot of articles on the subject, i just connected cables that i soldered to metal nails to the Teensy's touch pins.
Using touchRead(), i get values in the range from 1000 - 5000, 1000 if i stay away, 5000 if i have my finger completely on the nail.
But touching for example my notebook computer's housing, i get values from 1000 - 30000, which is a better resolution, but i have to get rid of these inhomogeneities.

How can i make sure that i get the same values, no matter what the situation is like?

I already built a controller with nails hammered into the wooden top panel. So i can't really change the situation completely.
I read the following article: http://www.planetanalog.com/document.asp?doc_id=527410
There it is said that i would need another metal object surrounding my touchPin, connected to ground. I can't realise this anymore, unfortunately.
The article is stating that the usage of a sensor and a ground piece is better, because it enables an electric field that then is changed by human interaction, and that this would be more stable than what i just did.

Can you give me any hints?
Can you tell me how exactly the Teensy is making use of the capacitive touch technology?
What would be the right usage?
The simpleness of the touchRead() functionality may have mislead me to my "wrong" kind of usage!?

Could i improve my setup with putting grounded metal plates inside the housing?
This is the project: https://hackaday.io/project/8371-wooden-sensor-box-w-2-rotary-disks

Sorry for my english, i am not a native speaker.

Thanks for answers,
best wishes, Jan
 
sorry for my impatience,
but i'm working on a project and need to get on somehow.
so nobody has any suggestions?

i already looked at the other posts concerning touch capactive sensing, and someone posted a link to a k20 chip pdf, that didn't help me, as i didn't really get it.
is there some solution? and what about the grounding plate that was talked about in the article?

please help me :)
jan
 
I have not done this yet -thanks for the link.

Assume you read this : http://www.pjrc.com/teensy/td_libs_CapacitiveSensor.html
Teensy's ground pin should be connected to earth ground for best results. Normally the USB cable connects to a PC, which connects to earth ground by its power code. But when using a laptop on battery power or running without a computer, you may need to make a dedicated connection to earth ground.

Unless you have a consistent ground the change to capacitance will all be relative to the ground you have. That ground needs to be part of the Teensy system - and that includes the person doing the touching.

One workaround may be to calibrate Min and Max when the Teensy starts up and then perhaps use the map() function to put that into consistent terms for use.
 
What you can do is average the values of all the touchRead()s for every pin you are using.
If one of these pins goes above this, plus some arbitrary factor, you know that pin is being touched
 
thank you, defragster, but if i get this right, the "CapacitiveSensor Library" that you posted your link to is still the old approach.
touchRead() works differently (proably more sophisticated) and with only one teensy pin for each sensor.
so, the thing about grounding may be still true, but with the different new approach, things may also vary, right?
actually, it makes no difference wether i have my macbook charging or just running from battery. it does, however, make a huge difference if i touch the macbook housing or not.

Xenoamor and defragster, yes, you can do software solutions, of course.
the calibration method may be a good place to start - how would you realize this? each time the device is connected and is starting up, have something like 20 seconds where you use all sensors to determine the min/max range?

and with the averaging method that Xenoamor suggested: this is a good idea, but of course, you loose the ability to modulate with the touch sensors.
like, pressing your finger on a metal nail vs. touching the edge of the nail with a little bit of skin would give different values.

when reading through forums, some people were suggesting to put a metal plate connected to ground inside of the device - how would that make any difference?
and if there's anybody who really understands the teensy touch sensing technology - are the info that are giving here:
http://www.planetanalog.com/document.asp?doc_id=527410
still valid for the teensy's technology? would i achieve best results with some surrounding grounded electrodes?

thanks, jan
 
Going off my own projects was able to make a very basic proximity device along the lines of that link, having two parallel lines, one one the sense pin and one on Teensy ground. Which allowed function through the casting resin the project was embedded in. This stabilised the highly variable results I was getting through the USB ground and surrounding environment. Having read the link suspect I'd have been better with a much smaller sense point than the rather capactive wire I ended up with.

In terms of calibration I'd suggest having a running average running in the background at say 10 second intervals into a 100 slot ring buffer that tracks background and use that to pick out the interaction events, both rising and falling.

Tracking the observed peaks during interaction also means you can tweak the sensitivity if you are trying to support complex interaction (setting time on two buttons for example) so set a low threshold for initial press and then run a peak detection process to decrease sensitivity while the following button presses happen. Hopefully reducing double detections from fingers moving from button to button.
 
Thanks for your reply, GremlinWrangler

I have two questions:
1) Do i understand this right? In your device, you used a sensor pin (connected to teensy input) that was surround by some metal (connected to teensy ground)?
Just like in the planetanalog-link? And this was working better than using just a sensor and no grounding electrode?
2) I don't really know if i understand what you are saying in the third passage. What do you mean by "setting time on two buttons"? And are you talking about
on/off switch buttons? Or, like me, about using a button also as a continuous modulator input?

thanks!
 
In my case I had a sense wire and a grounded wire embedded right on the surface of clear resin. Since the whole project was a light show, having a grounded metal enclosure to achieve reliable grounding of the operator wasn't going to work, and the chosen power supply (phone charger) didn't offer a reliable ground. So used the teensy ground wire to provide something for the cap sense to work with. I think this has two caps in series so less effective than sticking an alligator clip to the user, but less painful.

Playing with a loop of wire just now it looked to make less of a difference than I thought. Running insulated wire in a short sense loop got readings ~850, rising to ~900 when solidly touched (outside the insulation, grabbing the metal gets >4000). Adding a earthed loop adjacent to the sense loop increased the steady state reading to ~900 but pushed the 'finger' reading to >1000.

So the process can work, but you are trying to sense changes less than 10% of your background reading so will need a fairly assertive filtering process. And I think you will benefit by having a ground plane adjacent to the touch zone through an increased signal to noise ratio.

So the lashup I've done here isn't going to provide true proximity senseing (>2-3mm) but can work without metal to finger contact, and provides and indication of pressure at 1mm.

The second part of my statement was thinking of how to filter the pin data to avoid issues if a fixed 'firm pressure' value was used. So have a running average not just for steady state, but also for highest value captured in a given series of presses. Otherwise someone with smaller fingers will have trouble getting a response, while someone with sausages may trigger multiple adjacent sensors.

Getting a pleasant user experience here if supporting random people and changed weather conditions (humidity and finger sweat will probably shift values) may require some work. If you are just trying to make something that works for you in a sane environment this will be a lot simpler.

Another example of using capsense on a Teensy:
http://njhurst.com/blog/01356576041
 
you need to calibrate to find a base value when the program starts. This takes care of the situation you described. Any reading > base (I use base + 20%) value means the pin was touched.

I wrote my own interrupt driven code (I find the library inadequate) to use 2 touch pins (32 and 33) to simulate 3 buttons.

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

  initTouch();
TSI_GENCS_TSIEN;
TSI_GENCS_TSIIE;
}

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

void tsi0_isr(void){
  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;
  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;
  }
}


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;
  Serial.print("Base value is ");//for debugging, remove in final code
  Serial.println(base);//for debugging, remove in final code
  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:
thank you, defragster, but if i get this right, the "CapacitiveSensor Library" that you posted your link to is still the old approach.

My link to that was specifically in reference to quoted and bolded comment on ground. Though IIRC your link was from a 2007 article ...
 
okay, thanks for all your comments!
i will try to put something like a grounding plate inside of the wooden housing. though honestly i don't know why exactly...
 
Don't forget your grounding doesn't have to be solid. Light wire mesh, aluminium or copper foil, or simply a looped and soldered at the crossings wire will all probably be 'good enough'. Classic approach to dealing with RF is a mesh screen, once the mesh is <3mm or so it's solid to pretty much anything except microwaves, and is far easier to shape into a Faraday cage than plate.
 
Status
Not open for further replies.
Back
Top