espressif / esp-idf

Espressif IoT Development Framework. Official development framework for Espressif SoCs.
Apache License 2.0
13.82k stars 7.32k forks source link

using touch_pad_read_raw_data() with touch sensors on esp32s3 reads high, unchanging values (IDFGH-11130) #12300

Open saillingaway opened 1 year ago

saillingaway commented 1 year ago

Answers checklist.

IDF version.

v5.2-dev-2756-g2bc1f2f574

Operating System used.

macOS

How did you build your project?

Command line with idf.py

If you are using Windows, please specify command line type.

None

Development Kit.

ESP32-S3 M5Stack M5Stamp

Power Supply used.

USB

What is the expected behavior?

The touch_sensor_v2 touch_pad_read example should output values that fluctuate similarly to the example output, and values should go up when respective sensors are touched.

What is the actual behavior?

Running the example exactly as it is results in the following output:

T1: [14721] T2: [14516] T3: [2438734] T4: [4116735] T5: [4158749] T6: [1539359] T7: [1538649] T8: [1585147] T9: [4035765] T10: [244164] T11: [948200] T12: [1998005] T13: [3530295] T14: [4177858]
T1: [14721] T2: [14516] T3: [2438734] T4: [4116735] T5: [4158749] T6: [1539359] T7: [1538649] T8: [1585147] T9: [4035765] T10: [244164] T11: [948200] T12: [1998005] T13: [3530295] T14: [4177858]
T1: [14721] T2: [14516] T3: [2438734] T4: [4116735] T5: [4158749] T6: [1539359] T7: [1538649] T8: [1585147] T9: [4035765] T10: [244164] T11: [948200] T12: [1998005] T13: [3530295] T14: [4177858]
T1: [14721] T2: [14516] T3: [2438734] T4: [4116735] T5: [4158749] T6: [1539359] T7: [1538649] T8: [1585147] T9: [4035765] T10: [244164] T11: [948200] T12: [1998005] T13: [3530295] T14: [4177858]
T1: [14721] T2: [14516] T3: [2438734] T4: [4116735] T5: [4158749] T6: [1539359] T7: [1538649] T8: [1585147] T9: [4035765] T10: [244164] T11: [948200] T12: [1998005] T13: [3530295] T14: [4177858]
T1: [14721] T2: [14516] T3: [2438734] T4: [4116735] T5: [4158749] T6: [1539359] T7: [1538649] T8: [1585147] T9: [4035765] T10: [244164] T11: [948200] T12: [1998005] T13: [3530295] T14: [4177858]
T1: [14721] T2: [14516] T3: [2438734] T4: [4116735] T5: [4158749] T6: [1539359] T7: [1538649] T8: [1585147] T9: [4035765] T10: [244164] T11: [948200] T12: [1998005] T13: [3530295] T14: [4177858]
T1: [14721] T2: [14516] T3: [2438734] T4: [4116735] T5: [4158749] T6: [1539359] T7: [1538649] T8: [1585147] T9: [4035765] T10: [244164] T11: [948200] T12: [1998005] T13: [3530295] T14: [4177858]

The values are all exceptionally higher than the ones from the example output, and none of the values ever change no matter which sensors are touched.

Steps to reproduce.

  1. Install and set up esp-idf for MacOS following espressif doc
  2. Open the example project esp-idf/examples/peripherals/touch_sensor/touch_sensor_v2/touch_pad_read
  3. Open terminal with working directory of the example project
  4. Build the project with idf.py build
  5. Attach esp32s3 via USB and flash with idf.py flash -p PORT
  6. Use idf.py monitor to see the output

Debug Logs.

No response

More Information.

During my troubleshooting I found that:

  1. adding touch_pad_fsm_start(); right before touch_pad_read_raw_data(); makes it so some of the raw values will fluctuate a little and respond to touch, but some remain unchanging.
            touch_pad_fsm_start();
            touch_pad_read_raw_data(button[i], &touch_value);    // read raw data.
            printf("T%d: [%4"PRIu32"] ", button[i], touch_value);
        }

resulting output shows T2, T3 and T4 still don't show any change, and they don't respond to touch unlike the others.

T1: [32366] T2: [53853] T3: [2910174] T4: [3419543] T5: [1675466] T6: [5625] T7: [71151] T8: [89432] T9: [63607] T10: [13947] T11: [13947] T12: [14518] T13: [14711] T14: [15072] 
T1: [32353] T2: [53797] T3: [2910174] T4: [3419543] T5: [1675466] T6: [3041124] T7: [72618] T8: [89380] T9: [63588] T10: [13940] T11: [13946] T12: [14518] T13: [14718] T14: [15068] 
T1: [32360] T2: [53816] T3: [2910174] T4: [3419543] T5: [1675466] T6: [3035738] T7: [72610] T8: [89410] T9: [63602] T10: [13941] T11: [13958] T12: [14522] T13: [14718] T14: [15072] 
T1: [32353] T2: [53821] T3: [2910174] T4: [3419543] T5: [1675466] T6: [3035605] T7: [72638] T8: [89396] T9: [63606] T10: [13943] T11: [13959] T12: [14523] T13: [14715] T14: [15069] 
T1: [32356] T2: [53853] T3: [2910174] T4: [3419543] T5: [1675466] T6: [3035537] T7: [72618] T8: [89426] T9: [63626] T10: [13931] T11: [13952] T12: [14510] T13: [14718] T14: [15066] 
  1. moving initialization and configuration outside of for loops resulted in less values being unresponsive and unchanging:
static const touch_pad_t button[TOUCH_BUTTON_NUM] = {
    TOUCH_PAD_NUM1,
    TOUCH_PAD_NUM2,
    TOUCH_PAD_NUM3, 
    TOUCH_PAD_NUM4,
    TOUCH_PAD_NUM5,
    TOUCH_PAD_NUM6,
    TOUCH_PAD_NUM7,
    TOUCH_PAD_NUM8,
    TOUCH_PAD_NUM9,
    TOUCH_PAD_NUM10,
    TOUCH_PAD_NUM11,
    TOUCH_PAD_NUM12,
    TOUCH_PAD_NUM13,
    TOUCH_PAD_NUM14
};
...
static void tp_example_read_task(void *pvParameter)
{
    uint32_t touch_value1;
    uint32_t touch_value2;
    uint32_t touch_value3;
    uint32_t touch_value4;
    uint32_t touch_value5;
    uint32_t touch_value6;
    uint32_t touch_value7;
    uint32_t touch_value8;
    uint32_t touch_value9;
    uint32_t touch_value10;
    uint32_t touch_value11;
    uint32_t touch_value12;
    uint32_t touch_value13;
    uint32_t touch_value14;
...
    while (1) {
    // instead of for loop:
        touch_pad_fsm_start();
        touch_pad_read_raw_data(button[0], &touch_value1);    
        touch_pad_read_raw_data(button[1], &touch_value2);    
        touch_pad_read_raw_data(button[2], &touch_value3);   
        touch_pad_read_raw_data(button[3], &touch_value4);    
        touch_pad_read_raw_data(button[4], &touch_value5);    
        touch_pad_read_raw_data(button[5], &touch_value6);    
        touch_pad_read_raw_data(button[6], &touch_value7);    
        touch_pad_read_raw_data(button[7], &touch_value8);    
        touch_pad_read_raw_data(button[8], &touch_value9);    
        touch_pad_read_raw_data(button[9], &touch_value10);   
        touch_pad_read_raw_data(button[10], &touch_value11);   
        touch_pad_read_raw_data(button[11], &touch_value12);    
        touch_pad_read_raw_data(button[12], &touch_value13);   
        touch_pad_read_raw_data(button[13], &touch_value14);    

        printf("T%d: [%4"PRIu32"] ", button[0], touch_value1);
        printf("T%d: [%4"PRIu32"] ", button[1], touch_value2);
        printf("T%d: [%4"PRIu32"] ", button[2], touch_value3);
        printf("T%d: [%4"PRIu32"] ", button[3], touch_value4);
        printf("T%d: [%4"PRIu32"] ", button[4], touch_value5);
        printf("T%d: [%4"PRIu32"] ", button[5], touch_value6);
        printf("T%d: [%4"PRIu32"] ", button[6], touch_value7);
        printf("T%d: [%4"PRIu32"] ", button[7], touch_value8);
        printf("T%d: [%4"PRIu32"] ", button[8], touch_value9);
        printf("T%d: [%4"PRIu32"] ", button[9], touch_value10);
        printf("T%d: [%4"PRIu32"] ", button[10], touch_value11);
        printf("T%d: [%4"PRIu32"] ", button[11], touch_value12);
        printf("T%d: [%4"PRIu32"] ", button[12], touch_value13);
        printf("T%d: [%4"PRIu32"] ", button[13], touch_value14);

        printf("\n");
        vTaskDelay(200 / portTICK_PERIOD_MS);
    }
}

void app_main(void)
{
    /* Initialize touch pad peripheral. */
    touch_pad_init();
    // instead of for loop:
    touch_pad_config(button[0]);
    touch_pad_config(button[1]);
    touch_pad_config(button[2]);
    touch_pad_config(button[3]);
    touch_pad_config(button[4]);
    touch_pad_config(button[5]);
    touch_pad_config(button[6]);
    touch_pad_config(button[7]);
    touch_pad_config(button[8]);
    touch_pad_config(button[9]);
    touch_pad_config(button[10]);
    touch_pad_config(button[11]);
    // touch_pad_config(button[12]);
    // touch_pad_config(button[13]);
...

The output from this change have T3 and T4 still showing some unexpected behavior-- both are much higher relative to the example output and other raw values, and T3 is still unresponsive and unchanging.

T1: [14731] T2: [14518] T3: [2438670] T4: [3199656] T5: [13371] T6: [13368] T7: [13449] T8: [12864] T9: [13310] T10: [13812] T11: [14906] T12: [15248] T13: [14869] T14: [15693] 
T1: [14732] T2: [14518] T3: [2438670] T4: [1670880] T5: [13359] T6: [13339] T7: [13420] T8: [12839] T9: [13275] T10: [13775] T11: [14874] T12: [15218] T13: [14915] T14: [15687] 
T1: [14742] T2: [14516] T3: [2438670] T4: [3340706] T5: [13344] T6: [13342] T7: [13419] T8: [12832] T9: [13275] T10: [13792] T11: [14875] T12: [15219] T13: [14918] T14: [15700] 
T1: [14733] T2: [14514] T3: [2438670] T4: [3168419] T5: [13361] T6: [13342] T7: [13419] T8: [12839] T9: [13283] T10: [13775] T11: [14871] T12: [15217] T13: [14918] T14: [15686] 
T1: [14731] T2: [14517] T3: [2438670] T4: [3168595] T5: [13358] T6: [13336] T7: [13420] T8: [12840] T9: [13292] T10: [13781] T11: [14870] T12: [15215] T13: [14916] T14: [15688] 

for my project touch sensor 1 is being used for something seperate, and I want 12 touch sensors, so my workaround right now is to use T2, and T4-T14:

static const touch_pad_t button[TOUCH_BUTTON_NUM] = {
    // TOUCH_PAD_NUM1, // being used for something else
    TOUCH_PAD_NUM2,
    // TOUCH_PAD_NUM3, // not being used
    TOUCH_PAD_NUM4,
    TOUCH_PAD_NUM5,
    TOUCH_PAD_NUM6,
    TOUCH_PAD_NUM7,
    TOUCH_PAD_NUM8,
    TOUCH_PAD_NUM9,
    TOUCH_PAD_NUM10,
    TOUCH_PAD_NUM11,
    TOUCH_PAD_NUM12,
    TOUCH_PAD_NUM13,
    TOUCH_PAD_NUM14
};
...
static void tp_example_read_task(void *pvParameter)
{
    uint32_t touch_value1;
    uint32_t touch_value2;
    uint32_t touch_value3;
    uint32_t touch_value4;
    uint32_t touch_value5;
    uint32_t touch_value6;
    uint32_t touch_value7;
    uint32_t touch_value8;
    uint32_t touch_value9;
    uint32_t touch_value10;
    uint32_t touch_value11;
    uint32_t touch_value12;
...
    while (1) {
    // instead of for loop:
        touch_pad_fsm_start();
        touch_pad_read_raw_data(button[0], &touch_value1);    
        touch_pad_read_raw_data(button[1], &touch_value2);    
        touch_pad_read_raw_data(button[2], &touch_value3);   
        touch_pad_read_raw_data(button[3], &touch_value4);    
        touch_pad_read_raw_data(button[4], &touch_value5);    
        touch_pad_read_raw_data(button[5], &touch_value6);    
        touch_pad_read_raw_data(button[6], &touch_value7);    
        touch_pad_read_raw_data(button[7], &touch_value8);    
        touch_pad_read_raw_data(button[8], &touch_value9);    
        touch_pad_read_raw_data(button[9], &touch_value10);   
        touch_pad_read_raw_data(button[10], &touch_value11);   
        touch_pad_read_raw_data(button[11], &touch_value12);

        printf("T%d: [%4"PRIu32"] ", button[0], touch_value1);
        printf("T%d: [%4"PRIu32"] ", button[1], touch_value2);
        printf("T%d: [%4"PRIu32"] ", button[2], touch_value3);
        printf("T%d: [%4"PRIu32"] ", button[3], touch_value4);
        printf("T%d: [%4"PRIu32"] ", button[4], touch_value5);
        printf("T%d: [%4"PRIu32"] ", button[5], touch_value6);
        printf("T%d: [%4"PRIu32"] ", button[6], touch_value7);
        printf("T%d: [%4"PRIu32"] ", button[7], touch_value8);
        printf("T%d: [%4"PRIu32"] ", button[8], touch_value9);
        printf("T%d: [%4"PRIu32"] ", button[9], touch_value10);
        printf("T%d: [%4"PRIu32"] ", button[10], touch_value11);
        printf("T%d: [%4"PRIu32"] ", button[11], touch_value12);

        printf("\n");
        vTaskDelay(200 / portTICK_PERIOD_MS);
    }
}

void app_main(void)
{
    /* Initialize touch pad peripheral. */
    touch_pad_init();
    // instead of for loop:
    touch_pad_config(button[0]);
    touch_pad_config(button[1]);
    touch_pad_config(button[2]);
    touch_pad_config(button[3]);
    touch_pad_config(button[4]);
    touch_pad_config(button[5]);
    touch_pad_config(button[6]);
    touch_pad_config(button[7]);
    touch_pad_config(button[8]);
    touch_pad_config(button[9]);
    touch_pad_config(button[10]);
    touch_pad_config(button[11]);
...

Which gives me the below output most similar to the example output, all the sensors fluctuate, react to touch and the value for T4 is also lower when I don't include TOUCH_PAD_NUM3 in touch_pad_t button).

T2: [14475] T4: [13773] T5: [13353] T6: [13335] T7: [13413] T8: [12834] T9: [13283] T10: [13745] T11: [14867] T12: [15214] T13: [14918] T14: [15670] 
T2: [14468] T4: [13770] T5: [13330] T6: [13327] T7: [13407] T8: [12827] T9: [13283] T10: [13756] T11: [14868] T12: [15209] T13: [14916] T14: [15692] 
T2: [14471] T4: [13774] T5: [13351] T6: [13330] T7: [13409] T8: [12825] T9: [13278] T10: [13762] T11: [14878] T12: [15216] T13: [14917] T14: [15689] 
T2: [14472] T4: [13767] T5: [13347] T6: [13329] T7: [13404] T8: [12824] T9: [13280] T10: [13774] T11: [14874] T12: [15216] T13: [14912] T14: [15691] 

I'm new to embedded development so I may have missed some additional necessary configuration, but I've looked at the docs and application note and didn't see anything so posting an issue here in hopes to get some insight onto what's going on. A little confused as to why I had to make these adjustments to get raw data like in the example--especially since the way I'm using touch_pad_fsm_start() now to get those values seems wrong/different from its intended use. Is there possibly a bug here? Either with the higher values or why the raw values don't update unless I restart the finite state machine each time I want to read values. Thanks in advance.

leeebo commented 1 year ago

@saillingaway Hi, please refer #12198

saillingaway commented 1 year ago

@leeebo Thanks for the reply. I saw this issue already while I was searching for a solution and I don't think this is the same issue I'm having now. The way I understand it, if one touch sensor gets too high, all of the other touch sensors will hang as well. Is this right? I do think that was happening at first--one of the first high readings from touch_pad_read_raw_data() would hang the rest of the sensors and so none of the values would ever change. It makes sense that calling touch_pad_fsm_start() right before touch_pad_read_raw_data() would 'fix' things so most of the values update each time. However, I don't understand why T3, T4 and T5 would still be stuck. After the weird fix of getting rid of the for loops, TOUCH_PAD_NUM3/T3 would still show a high unchanging value, even though it's only configured as a touch sensor. I basically can't use T3 as a touch sensor as things are now. From that other thread, are you saying T3 is hanging every time values are read, and it reads the exact same raw value every iteration despite resetting the fsm before each read?

In #12198 you said if one of the pins was accidentally connected to another device the touch sensor would be trapped in that pin, causing abnormal readings in that channel and maybe in other channels too, but I've only plugged the chip into my machine, in order to flash and monitor. Still, if that is what's happening here, is there more configuration for T3 that's necessary to use it as a touch sensor again? I already have a smaller sample size (100) like you mentioned in the other thread and what I had above was the result of that. I've also tried resetting all the pins with gpio_reset_pin(GPIO_NUM_X) and then configuring them as a touch_sensors.

I understand any GPIO pins enabled and configured as touch sensors can't be connected to any other function or hardware, which I don't believe I'm doing. Also, the other functionality T1 will be used for that I mentioned before isn't configured, I only removed TOUCH_PAD_NUM1 from button[] preemptively as a reminder to myself. I also experimented with touch_pad_set_voltage() to try to see if I could get the value of T3 to come down but didn't have any luck.

I was reading through the esp32-s3 data sheet again and saw on page 16 that GPIO3 is a strapping pin. It says after start up the strapping pins are freed up to be used as I/O pins after reset, but I'm curious if there's some artifact that's interfering with the reading?

leeebo commented 1 year ago

image

Hi @saillingaway , after checking the StampS3 schematic, I found the root cause: the GPIO3 (T3) of StampS3 is pulled up outside, this is forbidden for the touch sensor because the pulled-up pin is not able to charge and discharge as normal.

  1. Removing T3 from your button list will work around.
  2. The reason call touch_pad_fsm_start(); before each read makes some difference, is because the FSM will restart. In normal case please only call it once
leeebo commented 1 year ago

The StampS3 pullup GPIO3 by default, could be an attempt to switch USB-JTAG and Standard JTAG interface through the strapping pin. which causes touch sensor T3 to become unusable.

image

saillingaway commented 1 year ago

Thank you! I looked at the schematic and I see that now. Thankfully my work around will be okay since I don't need all the sensors. Unfortunately like I said, if I don't call touch_pad_fsm_start(); every single time, no values will update. If I only call it once, the output of raw data will look like this:

T1: [14721] T2: [14516] T3: [2438734] T4: [4116735] T5: [4158749] T6: [1539359] T7: [1538649] T8: [1585147] T9: [4035765] T10: [244164] T11: [948200] T12: [1998005] T13: [3530295] T14: [4177858]
T1: [14721] T2: [14516] T3: [2438734] T4: [4116735] T5: [4158749] T6: [1539359] T7: [1538649] T8: [1585147] T9: [4035765] T10: [244164] T11: [948200] T12: [1998005] T13: [3530295] T14: [4177858]
T1: [14721] T2: [14516] T3: [2438734] T4: [4116735] T5: [4158749] T6: [1539359] T7: [1538649] T8: [1585147] T9: [4035765] T10: [244164] T11: [948200] T12: [1998005] T13: [3530295] T14: [4177858]
T1: [14721] T2: [14516] T3: [2438734] T4: [4116735] T5: [4158749] T6: [1539359] T7: [1538649] T8: [1585147] T9: [4035765] T10: [244164] T11: [948200] T12: [1998005] T13: [3530295] T14: [4177858]
T1: [14721] T2: [14516] T3: [2438734] T4: [4116735] T5: [4158749] T6: [1539359] T7: [1538649] T8: [1585147] T9: [4035765] T10: [244164] T11: [948200] T12: [1998005] T13: [3530295] T14: [4177858]
T1: [14721] T2: [14516] T3: [2438734] T4: [4116735] T5: [4158749] T6: [1539359] T7: [1538649] T8: [1585147] T9: [4035765] T10: [244164] T11: [948200] T12: [1998005] T13: [3530295] T14: [4177858]
T1: [14721] T2: [14516] T3: [2438734] T4: [4116735] T5: [4158749] T6: [1539359] T7: [1538649] T8: [1585147] T9: [4035765] T10: [244164] T11: [948200] T12: [1998005] T13: [3530295] T14: [4177858]
T1: [14721] T2: [14516] T3: [2438734] T4: [4116735] T5: [4158749] T6: [1539359] T7: [1538649] T8: [1585147] T9: [4035765] T10: [244164] T11: [948200] T12: [1998005] T13: [3530295] T14: [4177858]

So the only way I can get any new readings is to call it at the beginning of the while loop before all the touch_pad_read_raw_data(); calls. Is this maybe because T3 was causing the sensors to hang? Also, is there any reason you can think why moving the config and init outside of for loops would fix T4 and T5?

leeebo commented 1 year ago

Yes, If you enable and try to read from T3, the sensor will hang, causing other channels not work also.

After remove GPIO3/T3, the example touch_sensor_v2/touch_pad_read should work as normal

saillingaway commented 1 year ago
  1. The reason call touch_pad_fsm_start(); before each read makes some difference, is because the FSM will restart. In normal case please only call it once

@leeebo yeah I understand that the values are different because the FSM restarts, normally I would follow the example and only call it once but I need to use it every loop to get different readings because of the issue with T3 I think. (Even if T3 is removed, calling touch_pad_fsm_start(); only once at the beginning outputs data that never changes)

leeebo commented 1 year ago

@saillingaway After removing T3 (not config and not read), the touch should work as normal, touch_pad_fsm_start(); only needs to be called once after touch init. Does the examples work for you then?

saillingaway commented 1 year ago

@leeebo I tested it again and it works 🎉 Never took out the config but I think before I must not have actually removed TOUCH_PAD_NUM3 from button[], I may have only removed the touch_pad_read_raw_data() for button[2]/GPIO3/T3 which wouldn't fix anything lol. Thanks for your help on this!