You're welcome; I learned too.
I tried to make the detection faster, while preserving Teensyduino compatibility. Here is my 'fastest' version (i.e. most sensitive to small capacitances). Basically, I extracted the variable portions from Paul's Teensy macros, and also abused the gcc ## macro preprocessing capability -- perhaps this isn't the most robust, but it works for now. Note that if LCDPin is a variable (not a #defined macro), it won't work.
Also, turning off interrupts during the measurement gives a more consistent result (it can still dither between two adjacent integers).
Code:
// 5 counts = 20 pF
#define LCDPin 12 // convenient
#define LEDPin 13
#define digitalReadFasterMacro(pin) CORE_PIN ## pin ## _PINREG
#define digitalReadFaster(pin) digitalReadFasterMacro(pin)
#define digitalReadFasterMaskMacro(pin) CORE_PIN ## pin ## _BITMASK
#define digitalReadFasterMask(pin) digitalReadFasterMaskMacro(pin)
uint32_t readArray[20]; // increase to suit
int iLoop = 0;
void setup() {
pinMode(LCDPin, OUTPUT);
pinMode(LEDPin, OUTPUT);
Serial.begin(115200);
while (!Serial) {
digitalWrite(LEDPin, HIGH); delay(50); digitalWrite(LEDPin, LOW);
delay(100); } // Wait for Arduino Serial Monitor to open
}
void loop() {
int iMeasure = 0;
int j=0;
pinMode(LCDPin, OUTPUT);
digitalWrite(LCDPin, LOW);
delayMicroseconds(10); // Be sure it is low
*portConfigRegister(LCDPin) = PORT_PCR_MUX(1) | PORT_PCR_PE | PORT_PCR_PS;
noInterrupts();
// pinMode(LCDPin, INPUT_PULLUP);
*portModeRegister(LCDPin) = 0; // Actually switch
// for (int i=0; i < (sizeof(readArray)/sizeof(uint32_t)); i++) readArray[i] = GPIOC_PDIR; // too slow
// This compiles to the same as readArray[constant] = ...
readArray[j++] = digitalReadFaster(LCDPin);
readArray[j++] = digitalReadFaster(LCDPin);
readArray[j++] = digitalReadFaster(LCDPin);
readArray[j++] = digitalReadFaster(LCDPin);
readArray[j++] = digitalReadFaster(LCDPin);
readArray[j++] = digitalReadFaster(LCDPin);
readArray[j++] = digitalReadFaster(LCDPin);
readArray[j++] = digitalReadFaster(LCDPin);
readArray[j++] = digitalReadFaster(LCDPin);
readArray[j++] = digitalReadFaster(LCDPin);
readArray[j++] = digitalReadFaster(LCDPin);
readArray[j++] = digitalReadFaster(LCDPin);
readArray[j++] = digitalReadFaster(LCDPin);
readArray[j++] = digitalReadFaster(LCDPin);
readArray[j++] = digitalReadFaster(LCDPin);
readArray[j++] = digitalReadFaster(LCDPin);
readArray[j++] = digitalReadFaster(LCDPin);
readArray[j++] = digitalReadFaster(LCDPin);
readArray[j++] = digitalReadFaster(LCDPin);
readArray[j++] = digitalReadFaster(LCDPin);
interrupts();
for (int i=0; i < (sizeof(readArray)/sizeof(uint32_t)); i++) if(!(readArray[i] & digitalReadFasterMask(LCDPin))) iMeasure=i;
Serial.print(iLoop++); Serial.write(' '); Serial.println(iMeasure);
delay(100);
}