Skip to content

touchRead and GPIO interaction #5109

@philton

Description

@philton

Using an ESP32-S2-Saola-1_VL2 Board
Arduino IDE
Linux (OpenSuse) Host Connected via USB
Board: ESP32S2 Dev Module
CPU Frequency: 240MHz (WiFi)
Flash Frequency: 80MHz
Upload Speed: 921600
PSRAM: Disabled

What I am trying to do:
I am trying to sense capacitance over 9 pins, and for each measurement drive the other 8 pins.

Observations:
I can measure uint16_t capactances on any or all of them using touchRead( pin ). This works fine.
I can drive all the pins using pinMode( pin, OUTPUT ) (in setup()), and then read one pin (in loop()), as many times as I like. This works fine
If, in loop() I try to read a pin, and then set it back to being an output, and then go to read the next pin etc. I get very strange results:

  1. The scaling of the values read by touchRead changes drastically, differently for different channels.
  2. It often gets stuck repeatedly reading the same values with touchRead, this seems to be affected by delay times used in loop().
  3. I get interactions between pairs of pins in the sequence, where as the capacitance reading for one pin increases, the capacitance reading another pin falls.
  4. Much more frequent, periodic wacky capacitance readings.
    The behavior is fairly consistent with the same exact code.

Question:
How can I measure capacitance on 9 pins, such that for each one I measure all of the others are low impedance?

Example Code:
#include <esp32-hal-touch.h>

// Constants
static const uint16_t Meas_Delay = 2; // ms - much longer delays seem to make it worse
static const uint8_t Nchannels = 2; // Minimum necessary to show problem
static const gpio_num_t Pin_Numbers[Nchannels] = // The pin numbers to send to touchRead()
{ GPIO_NUM_6, GPIO_NUM_7, };

void setup()
{
// Set up the serial link for data
while(!Serial); // required for Flora & Micro, seems to help
delay(500);
Serial.begin(2000000);
delay(3000); // Serial port seems to take a while to set up
Serial.println( "OK" );

touchSetCycles( 0x20, 0x20 ); // Set up the capacitive cycle times
}

void loop() // One channel per loop, this seems to work better, but completely changes the scaling
{
gpio_num_t pin = Pin_Numbers[ch]; // Get the pin number for this channel
pinMode( pin, ANALOG ); // Redundant, but seems to help
delay(Meas_Delay); // Wait a bit
capacitances[ch] = touchRead( pin ); // Read capacitance

Serial.print( ch, DEC ); Serial.print( ":" ); Serial.print( capacitances[ch], DEC ); Serial.print( ", " );
pinMode( pin, OUTPUT ); // This is the line which screws it up,
// This is OK when just doing 1 channel, screws it up when cycling round more than one
ch = ++ch % Nchannels; // Go on to the next channel
if( !ch ) // Next channel will be 0 again
Serial.println();
}

Serial output with 2 channels and pinMode( pin, Output )

23:20:12.886 -> OK
23:20:12.886 -> 0:32600, 1:25599,
23:20:12.886 -> 0:3414, 1:3573,
23:20:12.886 -> 0:12365, 1:12188,
23:20:12.886 -> 0:12397, 1:12114,
......
Rather weird response to capacitance changes, as 0 rises 1 falls and vice versa, strange starting point, spurious spikes

Serial output with 2 channels and no pinMode( pin, Output )

23:22:50.864 -> OK
23:22:50.897 -> 0:32600, 1:25535,
23:22:50.897 -> 0:3331, 1:3259,
23:22:50.897 -> 0:3333, 1:3259,
23:22:50.897 -> 0:3332, 1:3259,
...........
Properly responsive to capacitance changes

Metadata

Metadata

Assignees

No one assigned

    Labels

    Status: StaleIssue is stale stage (outdated/stuck)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions