Maximum Number of Touch Pads/Latency

Status
Not open for further replies.

chrisgr99

Member
I need to know what is the maximum number of touch pads a given Teensy device can support. The documentation here

https://www.pjrc.com/teensy/td_libs_CapacitiveSensor.html

says that a pair of pins are required per pad. Do both pins need to be "Touch" pins? I see that pads can share a send pin. So if one Touch pin must be send, does that mean that the maximum number of touch pads is the number of available pins minus 1 for the send pin?

I need to scan all the pads as fast as possible. Assuming the user is touching a pad connected to the device ground and the sensing pads are touched directly, how fast can each be read?

If more than one send pin is assigned might it be possible to read more than one pin in parallel?
 
The touch pins don't use that library. You access them with touchRead(pin). It works the same as analogRead(pin), but instead of reading voltage it reads capacitance.

The CapacitiveSensor library can in principle be used for many inputs. But it's much slower and far less consistent than touchRead() on the pins with built-in hardware.

I need to scan all the pads as fast as possible .... how fast can each be read?

It depends on the capacitance. More capacitance requires more time. The hardware touchRead() pins are much faster. The worst case is approx 5ms, but don't take my word for it. You can check by using micros() or elapsedMicros in your code, and connect a 10nF ceramic capacitor to the pin.

The good news is the time is much quicker when the pin doesn't have much capacitance. So if you're scanning many pins and only 1 is touched, usually it goes pretty quick, at least on time scales humans can notice. Again, features like elapsedMicros and printing to the serial monitor are the best way to see what the real speed is.
 
Starting from my experience that touching will add about 150pF to the static capacitance already seen by the pin through parasitic an wiring capacitance, and considering that you just need the touched or not info, not precise capacitance measure (IIRC, the default resolution is about 20 ticks per pF), you might tweak touch.c in the Teensyduino core files to obtain quicker results through increasing the charge currents and/or the decreasing counter prescale factor of the TSI engine.
 
You could also consider adding an MPR121 to your circuit for touch detection. That chip offers a lot of customization and does a lot of the hard work for you in providing stable touch detection.

The MPR121 can also use interrupts to signal a touch to your Teensy so you don't need to continuously read in your main loop saving you Teensy CPU cycles.

Adafruit does a I2C based breakout board so you get 12 touch channels using only the pins on your Teensy needed for the I2C coms:
https://www.adafruit.com/product/1982
 
Still no need for an external product. The Teensy's integrated TSI engine can handle up to 16 touch pins (of which 12 are brought out on the T3.2) and can do almost everything autonomously in the background without eating much CPU cycles when thoughtfully programmed, for example using the TSI interrupt by enabling TSIIE in the TSI0_GENCS register. Detailed info can be found in the K20 reference manual, starting from page 1339 (Chapter 50).
 
Guess it depends on the project specifics and if you need Teensy pins for other stuff as well.

With the I2C based Adafruit breakout board you can use 4 of them setting jumpers for different I2C addresses. So a max of 48 touch channels using a single I2C.
 
...for example using the TSI interrupt by enabling TSIIE in the TSI0_GENCS register. Detailed info can be found in the K20 reference manual, starting from page 1339 (Chapter 50).

I'm trying to this, but I'm a complete neophyte and am not sure I understand the details.

Am I doing the right thing if I update the relevant line in touch.c to read as follows?
Code:
TSI0_GENCS = TSI_GENCS_NSCN(NSCAN) | TSI_GENCS_PS(PRESCALE) | TSI_GENCS_TSIEN | TSI_GENCS_SWTS [B]| TSI_GENCS_TSIIE(1)[/B];

Assuming I did that right, one thing I am completely clueless about is how to set the thresholds: TSICHHTH and TSICHLTH. It doesn't look like they are set in the GENCS register, and I can't find any other reference to how to set those. (At least not a reference I understand. As I said, I'm extremely new at this.)

Regardless, I appreciate any guidance that you can offer!
 
I have a small format keyboard I love that has the old large diameter DIN connector. After many years of use the keys still have excellent action because I changed the rubber membrane with small springs at each key. I'm tempted to now change the controller in it and make it a USB keyboard I can use with my current computers that lack old AT and XT keyboard inputs.. It uses the BTC-5100 keyboard controller chip by Intel which I can't find docs for. The keys are two half circle pads with solder mask 100% covering them. The moving part of the key has a disc of foil with foam behind it on the bottom of the key. The foil presses against the solder mask over the two half circles but can't make electrical contact with them. My guess is that is capacitive sensing in nature. It is arranged in 12 columns by 8 rows. The columns are directly connect to the BTC-5100 chip pins, while the rows are buffered though two TC4044BP CMOS quad 3-state R/S latches. Could a Teensy scan the matrix at a useful speed? I wouldn't be worried about how much CPU time it takes because I would be dedicating it to keyboard use, and maybe give it an OLED display for status. Right now I only have 3.6s to play with, and they show only 11 touch key inputs, but may be able to get a 3.2 soon.

This keyboard is second only in action to an old Cherry hall effect keyboard I used in a portable back in the early '80s. I consider it better than the early IBM PC keyboards before they cheapened them. I.E. The ones that were derived from Selectric typewriter keyboards.
 
I made a mistake on the number of columns. There are 13, labeled S0 to S12. S is likely for scan.

This keyboard uses a Toshiba 4044 CMOS R/S latch for it's capacitive sensor. ON semiconductor makes one with similar specs that may be a possible substitute.

I've probed the circuit out. Should't need the Teensy's capacitive touch inputs at all. The S* columns pins are directly tied to the pads on the keyboard with nothing in series and no pull ups or pull downs. The TC4044BP CMOS quad 3-state R/S latches have their Reset pins connected to the rows on the keyboard and have individual 100k resistors tied to the output of a voltage divider with a 1.69k 1% resistor on the GND side, and 1.00k 1% and 80.6 1% ohm resistors in series on the VCC side. All the Set inputs are directly tied together to a common pin on the keyboard controller. The Enable inputs are tied together and pulled up to VCC via a 10k resistor. Each Q output goes to an individual pin on the keyboard controller.

I'd assume the voltage of the resistor network could be tuned for nearly any CMOS input logic device.

There is also a diode, inductor, and some capacitors all hooked up to the controller chip. They look like they form a 2.6V power supply, but for what? The S* outputs have 5.15V with a small ripple when the VCC supply is 5.25V and steady, and they oscope out to have short dips to 0 volts periodically. Some much more often than others. Kinda like they scan those keys more often. A key press makes a very short drop in the Row line going to the reset input when the S line also tied to that key briefly dips low. That is enough to reset the latch and cause a low on the normally high Q output until the r/s latches are set again.

So what all that tells me is the Rows are sensed by the CMOS R/S latches which tells me the CMOS inputs work as a comparator. The signal then goes via the Q outputs directly to an IO pin on the controller. I looked at the specifications* for a Toshiba 4044 CMOS chip. At most 0.1uA and as little as 0.00001uA needed to generate a logic high or low. Looks like a touch sensor comparator to me. The 100k resistor between the R/S latch reset input and the voltage divider holds the reset input just higher than is needed to be interpreted as high. When the capacitor at the key has column side pulled low, and the key is pressed pushing the foil up against the solder mask over the column and row pads, the capacitor at the key charges up and causes a small drop in voltage. The 100k resistor can only charge it very slowly. That drop in voltage is interpreted by the R/S latch as a reset, so the Q output goes low.

So the scanning of this keyboard likely goes like this:
Code:
// row[r] = 0 means key is pressed
// row[r] = 1 means key is not pressed
Set S[0-12] column outputs high.
Set the SET inputs of the R/S latches high. (all are tied together)
while(true) {
  for (c = 0; c < 13; c++) {
    set S[c] low
    wait a bit for resets to happen and propagate to the input pins
    read row[0-7] // byte read of an 8 bit port. input pins are tied to the Q outputs of R/S latches
    set S[c] high // do now for longer time to settle
    for (r = 0, r < 8; r++) {
      // only look for key changes
      if ((row[r] is 1) && (last_column_row[c][r] was 0))
        queue (keycode[c][r] | keyUpFlag) to be sent;
      if((row[r] is 0) && (last_column_row[c][r] was 1))
        queue (keycode[c][r] | keyDownFlag) to be sent;
    }
    last_column_row[c][0-7] = row[0-7];
    Set the SET inputs of the R/S latches high.
    wait a bit for voltages to settle
  }
}

Given that the keyboard is simple, and without any passives, it should be easy to use the capacitive keys with other styles of scanning capacitive keyboard arrays.

* Toshiba TC4044BP https://datasheet.octopart.com/TC4044BP-Toshiba-datasheet-13722376.pdf

http://www.onsemi.com/pub/Collateral/MC14043B-D.PDF looks to be a still availble equivalent.
 
I'm trying to this, but I'm a complete neophyte and am not sure I understand the details.

Am I doing the right thing if I update the relevant line in touch.c to read as follows?
Code:
TSI0_GENCS = TSI_GENCS_NSCN(NSCAN) | TSI_GENCS_PS(PRESCALE) | TSI_GENCS_TSIEN | TSI_GENCS_SWTS [B]| TSI_GENCS_TSIIE(1)[/B];

Assuming I did that right, one thing I am completely clueless about is how to set the thresholds: TSICHHTH and TSICHLTH. It doesn't look like they are set in the GENCS register, and I can't find any other reference to how to set those. (At least not a reference I understand. As I said, I'm extremely new at this.)

Regardless, I appreciate any guidance that you can offer!

@mccand - did you find the way to activate enable the interrupt for TouchRead?
 
@defragster - Unfortunately, I have not.

The tentative solution I posted above doesn't work, and I don't understand what's going on well enough to understand why not.

I'm still interested in having touch interrupts, if anyone can give me some pointers.
 
I added the "| TSI_GENCS_TSIIE" [had to remove the param (1)] and it did not generate interrupts for me. Tried a couple hacks to confirm it should be able to get through - but not seeing it as enabled and active
 
Status
Not open for further replies.
Back
Top