Skip to content

esp32s3 TouchPad not working #13178

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wangshujun-tj opened this issue Dec 12, 2023 · 7 comments · Fixed by #16169
Closed

esp32s3 TouchPad not working #13178

wangshujun-tj opened this issue Dec 12, 2023 · 7 comments · Fixed by #16169

Comments

@wangshujun-tj
Copy link

wangshujun-tj commented Dec 12, 2023

from machine import TouchPad, Pin
import time
t = TouchPad(Pin(5))
for i in range(100):
    time.sleep(0.5)
    print("%X"%t.read())

The same code changes the number with touch on ESP32, but the reading does not change on ESP32s3

Adjusting the initialization code as follows works fine, but I am not familiar enough with ESP32 and have not fully tested it, for reference only. Additionally, I suspect that the same issue also exists in ESP32s2
The changes are minimal, move the touch_Pad_Fsm_Start to touch_Pad_config After

STATIC mp_obj_t mtp_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw,
    const mp_obj_t *args) {
    mp_arg_check_num(n_args, n_kw, 1, 1, true);
    gpio_num_t pin_id = machine_pin_get_id(args[0]);
    const mtp_obj_t *self = NULL;
    for (int i = 0; i < MP_ARRAY_SIZE(touchpad_obj); i++) {
        if (pin_id == touchpad_obj[i].gpio_id) {
            self = &touchpad_obj[i];
            break;
        }
    }
    if (!self) {
        mp_raise_ValueError(MP_ERROR_TEXT("invalid pin for touchpad"));
    }

    static int initialized = 0;
    if (!initialized) {
        touch_pad_init();
        touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER);
        initialized = 1;
    }
    #if CONFIG_IDF_TARGET_ESP32
    esp_err_t err = touch_pad_config(self->touchpad_id, 0);
    #elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
    esp_err_t err = touch_pad_config(self->touchpad_id);
    touch_pad_fsm_start();
    #endif
    if (err == ESP_OK) {
        return MP_OBJ_FROM_PTR(self);
    }
    mp_raise_ValueError(MP_ERROR_TEXT("Touch pad error"));
}
@wangshujun-tj
Copy link
Author

Has any developer noticed this? I only tested esp32s3 and suspect that s2 also has the same issue, but I don't have the appropriate hardware at hand

@x-channel
Copy link

I got same problem.

@SkaveRat
Copy link

SkaveRat commented Apr 6, 2024

I think I got the same problem

When I read the value I get nonsensical values like "3252087".

Test code:

touch_pin = TouchPad(Pin(3, Pin.IN))
touch_pin.read()

Version: 1.22.2
ESP32-S3

@wangshujun-tj
Copy link
Author

我给出的帖子里面提到了解决方法,按照做简单修改既可以工作
可以得到可靠的可变的读数,但是s3和老的esp32数据变化趋势相反,数值范围差异也很大

@Shahir-abdulla
Copy link

Shahir-abdulla commented May 16, 2024

from machine import TouchPad, Pin import time t = TouchPad(Pin(5)) for i in range(100): time.sleep(0.5) print("%X"%t.read())

The same code changes the number with touch on ESP32, but the reading does not change on ESP32s3

Adjusting the initialization code as follows works fine, but I am not familiar enough with ESP32 and have not fully tested it, for reference only. Additionally, I suspect that the same issue also exists in ESP32s2 The changes are minimal, move the touch_Pad_Fsm_Start to touch_Pad_config After

STATIC mp_obj_t mtp_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 1, 1, true); gpio_num_t pin_id = machine_pin_get_id(args[0]); const mtp_obj_t *self = NULL; for (int i = 0; i < MP_ARRAY_SIZE(touchpad_obj); i++) { if (pin_id == touchpad_obj[i].gpio_id) { self = &touchpad_obj[i]; break; } } if (!self) { mp_raise_ValueError(MP_ERROR_TEXT("invalid pin for touchpad")); }

static int initialized = 0;
if (!initialized) {
    touch_pad_init();
    touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER);
    initialized = 1;
}
#if CONFIG_IDF_TARGET_ESP32
esp_err_t err = touch_pad_config(self->touchpad_id, 0);
#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
esp_err_t err = touch_pad_config(self->touchpad_id);
touch_pad_fsm_start();
#endif
if (err == ESP_OK) {
    return MP_OBJ_FROM_PTR(self);
}
mp_raise_ValueError(MP_ERROR_TEXT("Touch pad error"));

}

This actually works. Thank you @wangshujun-tj

@brainstorm
Copy link

brainstorm commented Jul 28, 2024

I felt like I was chasing my tail with this one since it worked perfectly fine on a WaveShare ESP32-S3-Zero board with the following code:

from machine import TouchPad, Pin
import time
t = TouchPad(Pin(1))

while True:
    time.sleep(0.5)
    print(t.read())

OTOH, on a custom board with a ESP32-S3-MINI-1 module I was seeing static reads from the touch sensor, as other folks report in this issue such as the following (no change at all when touching/not touching):

(...)
1957609
1957609
1957609
1957609
(..)

Then I connected a oscilloscope probe on the CUSTOM board

Baseline (no touch other than the scope probe):

RigolDS8

Touching with fingers:

RigolDS9

And then I looked back at the waveforms on the Waveshare board

No touch (only scope probe attached):

RigolDS10

Touch:

RigolDS11

Analysis and workaround

So there's an obvious electrical difference between touch and no touch on both boards, discarding electrical issues. Then I suspected that the difference on baselines between boards might be the culprit: getting a unstable value as baseline during initialization of the sensor.

Then I thought: well, perhaps folks initialize the touch too early before the baseline is relatively stable on custom boards (with more noise and design/manufacturing defects)? That'd also explain the relocation of the touch_pad_fsm_start() function and at least one user reporting success too: timing matters.

Using the following rearrangement of the code (waiting for 10 seconds before importing TouchPad at all):

import time

time.sleep(10)
from machine import TouchPad, Pin

t = TouchPad(Pin(2))

while True:
    time.sleep(0.5)
    print(t.read())

Makes the touch values finally make sense on the custom board:

42719
42759
178112
200197
218871
228830
235282
241806
238224
247305
247342
251422
42723
42731

So a more robust fix than using hardcoded delays would be for that FSM (touch_pad_fsm_start) to sample values and detect when they are clearly out of range and "try again" to init?

EDIT: Further experimentation suggests that the mechanical configuration of the touch surface does play a big role in determining the baseline on initialization. In my board's case the screws connected to the touch surface were not tight enough and causing false readings across reboots... upon tightening them, all touch false starts disappeared, so YMMV massively here.

brainstorm added a commit to CCHS-Melbourne/Spectrogram that referenced this issue Oct 25, 2024
…he 3 touch buttons and then mic... mic task only seems to work when it's the only task spawned (when no touch tasks are spawned)... and in any case, touch reliability seems to be erratic? See micropython/micropython#13178 (comment) /cc @projectgus (do let me know if you need more context and/or a better explanation)
projectgus added a commit to projectgus/micropython that referenced this issue Nov 6, 2024
Closes micropython#13178.

TouchPad confirmed working on both chips, and fixes the the ESP32-S3
reading constant max value. Was unable to reproduce the bug on ESP32-S2 but
this may be due to my test setup, and it still works with the fix.

This work was funded through GitHub Sponsors.

Signed-off-by: Angus Gratton <angus@redyak.com.au>
projectgus added a commit to projectgus/micropython that referenced this issue Nov 20, 2024
Closes micropython#13178.

TouchPad confirmed working on both chips, and fixes the the ESP32-S3
reading constant max value. Was unable to reproduce the bug on ESP32-S2 but
this may be due to my test setup, and it still works with the fix.

This work was funded through GitHub Sponsors.

Signed-off-by: Angus Gratton <angus@redyak.com.au>
@ppamment
Copy link

I am doing something like this which works around successfully. Thanks @projectgus hopefully that PR resolves things, this drove me nuts for a while!

    async def monitor(self) -> None:
        await asyncio.sleep(2) # Give it some time to calibrate touch on start
        while (self.threshold > 150000):
            from machine import TouchPad
            self.touch_handle = TouchPad(self.touch_pin)
            self.threshold = self.touch_handle.read()*1.5
            logger.debug(f"Threshold: {self.threshold}")
            await asyncio.sleep(1)

dpgeorge pushed a commit that referenced this issue Nov 28, 2024
Closes #13178.

TouchPad confirmed working on both chips, and fixes the the ESP32-S3
reading constant max value. Was unable to reproduce the bug on ESP32-S2 but
this may be due to my test setup, and it still works with the fix.

This work was funded through GitHub Sponsors.

Signed-off-by: Angus Gratton <angus@redyak.com.au>
wiznet-grace pushed a commit to wiznet-grace/micropython that referenced this issue Feb 27, 2025
Closes micropython#13178.

TouchPad confirmed working on both chips, and fixes the the ESP32-S3
reading constant max value. Was unable to reproduce the bug on ESP32-S2 but
this may be due to my test setup, and it still works with the fix.

This work was funded through GitHub Sponsors.

Signed-off-by: Angus Gratton <angus@redyak.com.au>
wiznet-grace pushed a commit to WIZnet-ioNIC/WIZnet-ioNIC-micropython that referenced this issue Feb 28, 2025
Closes micropython#13178.

TouchPad confirmed working on both chips, and fixes the the ESP32-S3
reading constant max value. Was unable to reproduce the bug on ESP32-S2 but
this may be due to my test setup, and it still works with the fix.

This work was funded through GitHub Sponsors.

Signed-off-by: Angus Gratton <angus@redyak.com.au>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
7 participants