Сенсорные пины ESP32: touchRead, порог, прерывание и слайдер
Руководство по сенсорным пинам ESP32: таблица пинов T0–T9, значения touchRead и порог, кнопки и слайдеры из фольги, touchAttachInterrupt и пробуждение из глубокого сна касанием.
Сенсорные пины ESP32 — это особые GPIO, подключённые к ёмкостным сенсорным датчикам, встроенным в чип. У классической ESP32 их 10 (T0–T9), и они без всякого дополнительного модуля распознают касание провода, кусочка алюминиевой фольги или медной ленты. Для этого хватает одной функции: touchRead(). Когда палец приближается к площадке, он добавляет в цепь небольшую ёмкость, а ESP32 выдаёт это изменение в виде числа. Так можно сделать сенсорный выключатель, диммер света, слайдер или скрытую кнопку открытия без механической кнопки.
В этом руководстве сначала разберёмся, какой GPIO подключён к какому сенсорному каналу и от каких пинов лучше держаться подальше. Затем прочитаем значения touchRead, подберём правильный порог и напишем надёжную сенсорную кнопку с автокалибровкой и гистерезисом. Ещё ты узнаешь, как сделать площадки из фольги и медной ленты, как регулировать яркость светодиода слайдером из трёх площадок, как работать с прерываниями через touchAttachInterrupt и как будить ESP32 из глубокого сна касанием. В последних разделах — проблемы с влажностью и помехами, отличия ESP32-S3 и короткий пример на MicroPython.

Как работают сенсорные пины ESP32?
Каждый сенсорный пин подключён к измерительной схеме внутри чипа. Эта схема непрерывно заряжает и разряжает пин и считает, сколько циклов заряда-разряда успевает пройти за фиксированное время. Провод и площадка на пине ведут себя как маленький конденсатор. Когда ты подносишь палец, твоё тело добавляет к этому конденсатору несколько пикофарад, заряд и разряд замедляются, и за то же время проходит меньше циклов. Поэтому на классической ESP32 значение touchRead при касании падает. С коротким проводом в покое обычно видно 40–80; при касании пальцем значение опускается примерно до 10–25. Эти числа зависят от длины провода, размера площадки, платы и окружения, поэтому никогда не вписывай порог по памяти: измерь его на своей установке.
| Характеристика | Классическая ESP32 | ESP32-S2 / ESP32-S3 |
|---|---|---|
| Число сенсорных каналов | 10 (T0–T9) | 14 (T1–T14) |
| Значение при касании | Падает | Растёт |
| Типичное значение в покое | 40–80 | От тысяч до десятков тысяч |
| Тип, возвращаемый touchRead | uint16_t | uint32_t |
| Порог прерывания | Абсолютное значение, срабатывает ниже него | Прирост относительно значения в покое |
| Пробуждение из глубокого сна | Несколько площадок | Одна площадка |
Таблица сенсорных пинов ESP32 (T0–T9)
Сенсорные каналы подключены только к определённым GPIO; если вызвать touchRead на другом пине, осмысленного значения не будет. Ядро Arduino определяет для этих каналов готовые константы вроде T0 и T1, так что touchRead(T0) в коде — то же самое, что touchRead(4). Некоторые из этих пинов — пины конфигурации при старте (strapping), которые определяют, как плата запускается при включении; как сенсорные они работают, но выбирать их в первую очередь не стоит.
| Канал | GPIO | Примечание |
|---|---|---|
| T0 | GPIO 4 | Безопасный, первый выбор |
| T1 | GPIO 0 | Подключён к кнопке BOOT, на 30-пиновых платах не выведен; не используй |
| T2 | GPIO 2 | Подключён к встроенному светодиоду, пин конфигурации при старте; значения могут «плавать» |
| T3 | GPIO 15 | Пин конфигурации при старте (влияет на сообщения при загрузке); используй осторожно |
| T4 | GPIO 13 | Безопасный |
| T5 | GPIO 12 | Пин конфигурации при старте (напряжение флеш-памяти); если при включении на нём высокий уровень, плата не запустится |
| T6 | GPIO 14 | Безопасный, при загрузке выдаёт короткий ШИМ-сигнал |
| T7 | GPIO 27 | Безопасный |
| T8 | GPIO 33 | Безопасный |
| T9 | GPIO 32 | Безопасный |
Делаем площадки: провод, алюминиевая фольга и медная лента
В качестве сенсорной площадки подойдёт любая проводящая поверхность. Проще всего — оголённый конец перемычки, вставленной в пин. Для более удобной поверхности можно взять кусочек алюминиевой фольги 2×2 см или самоклеящуюся медную ленту; медная лента ещё и паяется, поэтому лучше подходит для постоянных проектов. Площадку можно приклеить к картону, к внутренней стороне пластиковой коробки или к обратной стороне деревянной детали. Касание распознаётся и через 1–3 мм пластика, оргстекла или стекла; просто падение значения становится меньше, поэтому порог нужно измерить заново. Провод от площадки до ESP32 держи коротким: провода длиннее 20–30 см превращаются в антенны, и касание самого провода тоже вызывает срабатывание.
| Материал площадки | Рекомендуемый размер | Плюсы | Внимание |
|---|---|---|---|
| Конец перемычки | Кончик провода | Никакой подготовки | Низкая чувствительность, для проб |
| Алюминиевая фольга | От 2×2 до 3×3 см | Дёшево, есть везде | Не паяется, провод крепи скотчем или зажимом |
| Медная лента | От 1,5×1,5 до 3×3 см | Паяется, ровно режется | Если клей не проводящий, провод припаивают к верхней стороне |
| Площадка на перфоплате или печатной плате | Диаметр 1–2 см | Надёжно и аккуратно | Область GND вокруг снижает помехи |
| Металлический предмет (винт, дверная ручка) | Зависит от предмета | Можно сделать скрытую кнопку | Крупный металл сильно снижает значение в покое |
Читаем значения touchRead и задаём порог
Первым делом посмотри реальные числа на своей установке. Скетч ниже читает GPIO 4 (T0) и GPIO 27 (T7) по восемь раз и выводит среднее. Если открыть в Arduino IDE через меню «Инструменты» «Плоттер по последовательному соединению» (Serial Plotter), можно в реальном времени наблюдать обе линии и видеть, как значения падают при касании.
1// ESP32 dokunmatik değer okuma / ESP32 touch value reading
2// GPIO 4 = T0, GPIO 27 = T7
3
4void setup() {
5 Serial.begin(115200);
6 delay(500);
7}
8
9void loop() {
10 uint32_t t0 = 0, t7 = 0;
11 for (int i = 0; i < 8; i++) { // 8 ölçümün ortalaması / average of 8 readings
12 t0 += touchRead(T0);
13 t7 += touchRead(T7);
14 }
15 Serial.print("T0:");
16 Serial.print(t0 / 8);
17 Serial.print(" T7:");
18 Serial.println(t7 / 8); // Seri Çizici için / for the Serial Plotter
19 delay(100);
20}Наблюдая за значениями, запиши три ситуации: площадка в покое, палец на площадке и палец в 1–2 см над площадкой. Например, если в покое 62, при касании 14, а при приближении 45, безопасный порог — примерно 60 процентов от значения в покое, то есть около 37. Если поставить порог слишком близко к значению в покое, он сработает уже при приближении пальца; если слишком низко — лёгкие касания будут пропускаться.
| Ситуация | Пример значения | Комментарий |
|---|---|---|
| В покое, короткий провод и фольга 2×2 см | 55–70 | Опорное значение |
| Палец в 1–2 см | 40–50 | Не должно срабатывать |
| Касание пальцем | 10–20 | Однозначное касание |
| Касание через 1 мм пластика | 25–35 | Порог стоит немного поднять |
| Длинный, свободно висящий провод | Нестабильно, 30–70 | Укороти провод, усредняй показания |
Сенсорная кнопка с автокалибровкой
Вместо того чтобы вписывать порог числом, гораздо надёжнее измерить значение площадки в покое при запуске платы и вычислить порог из него. Скетч ниже при запуске усредняет 50 измерений, считает падение на 40 процентов касанием и переключает светодиод. Отпускание он засчитывает, когда значение поднимается выше 80 процентов от значения в покое. Использование двух отдельных порогов называется гистерезисом; он не даёт кнопке срабатывать раз за разом, когда значение дрожит прямо на границе. Если интересна механическая сторона кнопок, загляни в статью как подключить кнопку.
1// Otomatik kalibrasyonlu dokunmatik buton / self-calibrating touch button
2// GPIO 4 (T0) dokunma pedi, GPIO 2 kart üstü LED
3// GPIO 4 (T0) touch pad, GPIO 2 onboard LED
4
5const uint8_t DOKUNMA_PIN = T0; // GPIO 4
6const uint8_t LED_PIN = 2;
7
8uint32_t bosDeger = 0; // dokunulmamış değer / untouched value
9uint32_t basEsik, birakEsik; // histerezisli eşikler / thresholds with hysteresis
10bool basili = false;
11bool ledDurum = false;
12
13uint32_t ortalamaOku(uint8_t pin, int adet) {
14 uint32_t toplam = 0;
15 for (int i = 0; i < adet; i++) {
16 toplam += touchRead(pin);
17 delay(2);
18 }
19 return toplam / adet;
20}
21
22void setup() {
23 Serial.begin(115200);
24 pinMode(LED_PIN, OUTPUT);
25 delay(300); // açılışta pede dokunma / do not touch at boot
26 bosDeger = ortalamaOku(DOKUNMA_PIN, 50);
27 basEsik = bosDeger * 60 / 100; // %40 düşüş = dokunma / 40% drop = touch
28 birakEsik = bosDeger * 80 / 100; // %20 altına dönünce bırakıldı / released
29 Serial.printf("Bos: %u Bas: %u Birak: %u\n", bosDeger, basEsik, birakEsik);
30}
31
32void loop() {
33 uint32_t deger = ortalamaOku(DOKUNMA_PIN, 4);
34
35 if (!basili && deger < basEsik) { // yeni dokunma / new touch
36 basili = true;
37 ledDurum = !ledDurum;
38 digitalWrite(LED_PIN, ledDurum);
39 Serial.println("Dokunuldu / touched");
40 } else if (basili && deger > birakEsik) { // parmak çekildi / finger lifted
41 basili = false;
42 }
43 delay(20);
44}| Часть кода | Задача |
|---|---|
| ortalamaOku() (усреднение) | Усредняет несколько измерений, сглаживая случайные выбросы |
| bosDeger (значение в покое) | Значение без касания, измеренное при запуске; если условия изменились, перезапуск платы обновляет калибровку |
| basEsik = 60% (порог нажатия) | Когда значение опускается ниже, засчитывается новое касание |
| birakEsik = 80% (порог отпускания) | Когда значение поднимается выше, палец считается убранным |
| Переменная basili | Не даёт светодиоду переключаться снова и снова, пока палец лежит на площадке |
Прерывания по касанию с touchAttachInterrupt
Вместо того чтобы постоянно вызывать touchRead, можно поручить сенсорному оборудованию измерять в фоне и вызывать функцию, когда значение опустится ниже порога. Для этого служит touchAttachInterrupt(пин, функция, порог). На классической ESP32 прерывание срабатывает, когда измеренное значение опускается ниже порога, и повторяется в каждом цикле измерения, пока палец остаётся на площадке. Поэтому функция прерывания должна только выставлять флаг, а основная работа должна выполняться в loop() с проверкой времени. Общие правила прерываний разобраны в статье прерывания Arduino.
1// touchAttachInterrupt ile dokunma kesmesi / touch interrupt
2// GPIO 27 (T7) pedi; eşik touchRead ile ölçülerek seçilmeli
3// GPIO 27 (T7) pad; pick the threshold from your touchRead values
4
5const uint8_t PED = T7; // GPIO 27
6const uint16_t ESIK = 40; // ESP32: değer bunun ALTINA inince tetikler / fires below this
7volatile bool dokunuldu = false;
8
9void IRAM_ATTR dokunmaKesmesi() {
10 dokunuldu = true; // kesmede yalnız bayrak / only set a flag in the ISR
11}
12
13void setup() {
14 Serial.begin(115200);
15 touchAttachInterrupt(PED, dokunmaKesmesi, ESIK);
16}
17
18void loop() {
19 static unsigned long sonDokunma = 0;
20 if (dokunuldu) {
21 dokunuldu = false;
22 // Parmak durdukça kesme tekrar tekrar gelir; 300 ms'de bir say
23 // The ISR repeats while the finger stays; count once per 300 ms
24 if (millis() - sonDokunma > 300) {
25 sonDokunma = millis();
26 Serial.printf("Dokunma! deger: %u\n", touchRead(PED));
27 }
28 }
29}В этом примере порог равен 40; это подходит для площадки, у которой в покое около 60, иначе измени его по числам из скетча измерения выше. Атрибут IRAM_ATTR у функции прерывания размещает её в быстрой памяти; для функций прерываний на ESP32 его рекомендуется использовать. Чтобы отключить прерывание, вызови touchDetachInterrupt(pin). На классической ESP32 можно также вызвать touchInterruptSetThresholdDirection(false), чтобы прерывание срабатывало, когда значение поднимается выше порога; это удобно, чтобы поймать момент, когда палец убирают.
Сенсорный слайдер из трёх площадок
Трёх площадок в ряд достаточно, чтобы определить, где находится палец. Когда палец между двумя площадками, значения падают у обеих; глядя на то, насколько упало значение каждой площадки, положение вычисляют через взвешенное среднее. Если вырезать площадки не простыми квадратами, а входящими друг в друга зигзагами или «ёлочкой», палец в любом положении касается минимум двух площадок, и слайдер работает намного плавнее. Для начала хорошо подойдут три полоски медной ленты шириной 1,5 см с зазорами 1–2 мм.
| Деталь | Пин ESP32 | Примечание |
|---|---|---|
| Площадка A (слева) | GPIO 13 (T4) | Положение 0 |
| Площадка B (в центре) | GPIO 14 (T6) | Положение 500 |
| Площадка C (справа) | GPIO 33 (T8) | Положение 1000 |
| Светодиод | GPIO 26 | Через резистор 220 Ω, короткая ножка к GND |
1// Üç pedli dokunmatik kaydırıcı ile LED parlaklığı / 3-pad touch slider dims an LED
2// Pedler: GPIO 13 (T4), GPIO 14 (T6), GPIO 33 (T8); LED: GPIO 26
3// Pads: GPIO 13 (T4), GPIO 14 (T6), GPIO 33 (T8); LED: GPIO 26
4
5const uint8_t pedler[3] = {T4, T6, T8};
6const uint8_t LED_PIN = 26;
7uint32_t bos[3]; // her pedin boştaki değeri / idle value of each pad
8int parlaklik = 0;
9
10uint32_t oku(uint8_t pin) {
11 uint32_t t = 0;
12 for (int i = 0; i < 4; i++) t += touchRead(pin);
13 return t / 4;
14}
15
16void setup() {
17 Serial.begin(115200);
18 delay(300);
19 for (int p = 0; p < 3; p++) {
20 uint32_t t = 0;
21 for (int i = 0; i < 32; i++) t += touchRead(pedler[p]);
22 bos[p] = t / 32;
23 }
24}
25
26void loop() {
27 long fark[3];
28 long toplam = 0;
29 for (int p = 0; p < 3; p++) {
30 fark[p] = (long)bos[p] - (long)oku(pedler[p]); // dokununca değer düşer / value drops on touch
31 if (fark[p] < 0) fark[p] = 0;
32 toplam += fark[p];
33 }
34
35 // Toplam düşüş boştaki değerin %25'ini geçerse parmak var
36 // A finger is present if the total drop exceeds 25% of an idle value
37 if (toplam > (long)bos[1] / 4) {
38 // Ağırlıklı ortalama: ped A = 0, ped B = 500, ped C = 1000
39 // Weighted average: pad A = 0, pad B = 500, pad C = 1000
40 long konum = (fark[1] * 500L + fark[2] * 1000L) / toplam;
41 parlaklik = map(konum, 0, 1000, 0, 255);
42 analogWrite(LED_PIN, parlaklik);
43 Serial.printf("Konum: %ld Parlaklik: %d\n", konum, parlaklik);
44 }
45 delay(30);
46}При запуске скетч сохраняет значение в покое для каждой площадки, а затем в каждом проходе цикла вычисляет величину падения. Если суммарное падение достаточно большое, палец находится на слайдере, и положение определяется в диапазоне от 0 до 1000. Это значение мы переводим в 0–255 с помощью map() и отправляем на светодиод через analogWrite(). analogWrite() работает и в версиях 2.x, и в версиях 3.x ядра ESP32 для Arduino. Как устроен ШИМ, рассказано в статье что такое ШИМ.
Пробуждение из глубокого сна касанием
В проекте на батарейках ESP32 можно отправить в глубокий сон и будить только тогда, когда кто-то касается площадки. В этом режиме ядра выключены, но сенсорная измерительная схема продолжает работать с малым потреблением. Функция touchSleepWakeUpEnable(пин, порог) за один вызов задаёт порог и включает пробуждение по касанию. На классической ESP32 источником пробуждения можно сделать несколько площадок; на ESP32-S2 и S3 допускается только одна. После пробуждения esp_sleep_get_touchpad_wakeup_status() сообщает, какая площадка разбудила плату. Подробности глубокого сна и значения тока разобраны в статье глубокий сон ESP32.
1// Dokunarak deep sleep'ten uyanma / wake from deep sleep by touch
2// GPIO 27 (T7) pedi / GPIO 27 (T7) pad
3
4#if CONFIG_IDF_TARGET_ESP32
5 #define ESIK 40 // ESP32: değer bunun altına inerse uyanır / wakes below this value
6#else
7 #define ESIK 5000 // ESP32-S2/S3: boştaki değere göre artış / rise above the baseline
8#endif
9
10RTC_DATA_ATTR int uyanmaSayisi = 0; // uykuda korunur / kept during deep sleep
11
12void setup() {
13 Serial.begin(115200);
14 delay(500);
15 uyanmaSayisi++;
16
17 if (esp_sleep_get_wakeup_cause() == ESP_SLEEP_WAKEUP_TOUCHPAD) {
18 Serial.printf("Dokunmayla uyandi, ped: %d\n", (int)esp_sleep_get_touchpad_wakeup_status());
19 } else {
20 Serial.println("Ilk acilis ya da baska neden / first boot or other cause");
21 }
22 Serial.printf("Uyanma sayisi: %d\n", uyanmaSayisi);
23
24 // Burada ölçüm yap, veri gönder... / take readings, send data here...
25 delay(2000);
26
27 touchSleepWakeUpEnable(T7, ESIK); // T7 pedini uyandırma kaynağı yap / enable T7 as wake source
28 Serial.println("Uyuyorum / going to sleep");
29 Serial.flush();
30 esp_deep_sleep_start();
31}
32
33void loop() {
34}После пробуждения код снова начинается с setup(), потому что в глубоком сне содержимое ОЗУ стирается. Чтобы сохранить счётчик пробуждений, перед переменной стоит RTC_DATA_ATTR; такие переменные хранятся в небольшой RTC-памяти, которая сохраняется во время сна. Поскольку сенсорное измерение продолжается и во сне, ток в глубоком сне немного выше, чем при пробуждении по таймеру; учитывай это, когда оцениваешь время работы от батареи. Блок #if в коде позволяет той же программе компилироваться с правильным порогом и на ESP32-S2 и S3.
Сенсорные пины ESP32 в MicroPython
Если на ESP32 установлен MicroPython, то же самое делается классом TouchPad из модуля machine. Его метод read() возвращает то же значение, что и touchRead() в Arduino; на классической ESP32 оно так же падает при касании. Для пробуждения используются esp32.wake_on_touch(True) и метод площадки config(порог).
1# ESP32 MicroPython dokunmatik pin / ESP32 MicroPython touch pin
2from machine import Pin, TouchPad
3import time
4
5ped = TouchPad(Pin(4)) # GPIO 4 = T0
6led = Pin(2, Pin.OUT) # kart üstü LED / onboard LED
7
8bos = sum(ped.read() for _ in range(20)) // 20 # dokunulmamış değer / idle value
9esik = bos * 6 // 10
10basili = False
11
12while True:
13 deger = ped.read()
14 if not basili and deger < esik:
15 basili = True
16 led.value(not led.value()) # her dokunuşta LED'i değiştir / toggle on every touch
17 print("dokunuldu", deger)
18 elif basili and deger > bos * 8 // 10:
19 basili = False
20 time.sleep_ms(30)У Raspberry Pi Pico нет встроенного ёмкостного сенсорного датчика. Если нужна сенсорная кнопка с Pico или Arduino Uno, проще всего взять готовый модуль TTP223; он сам распознаёт касание и выдаёт обычный цифровой сигнал.

Проблемы с влажностью, водой и помехами
Ёмкостное измерение реагирует не только на пальцы, но и на воду. Капля воды или сильная влажность на площадке увеличивают ёмкость, значение падает, и кнопка может сработать сама. В проектах для ванной, кухни или улицы размещай площадку за поверхностью, на которой не задерживается вода, выбирай порог чуть ниже и требуй, чтобы касание длилось не меньше 50–100 мс. Длинные провода, расположенные рядом реле и моторы, а также плохой USB-источник питания тоже заставляют значения «плавать». В таблице ниже собраны самые частые проблемы и их решения.
| Проблема | Вероятная причина | Решение |
|---|---|---|
| Срабатывает само | Порог слишком близко к значению в покое | Опусти порог до 60% от значения в покое, добавь гистерезис |
| Значения постоянно скачут | Длинный или висящий провод, зашумлённое питание | Укороти провод, усредняй 4–8 измерений, возьми хороший USB-кабель |
| После отключения от компьютера изменилась чувствительность | Изменилась опорная земля | Калибруй в итоговой конфигурации, с батареей или блоком питания |
| Срабатывает при влажности или от капли воды | Вода увеличивает ёмкость | Спрячь площадку за покрытие, задай минимальное время касания |
| Один пин вообще не меняется | Использован несенсорный GPIO | Сверься с таблицей пинов; GPIO 34–39 не сенсорные |
| Плата не запускается | Площадка и провод на GPIO 12 мешают загрузке | Перенеси площадку на GPIO 4, 13, 27, 32 или 33 |
Сенсорные пины на ESP32-S3 и других моделях
ESP32-S2 и ESP32-S3 используют сенсорное оборудование второго поколения и отличаются от классической ESP32 в трёх важных моментах. Во-первых, каналы находятся на GPIO 1–14, и их 14; T1 — это GPIO 1, T14 — GPIO 14. Во-вторых, значения гораздо больше и растут при касании; площадка, у которой в покое около 20 000, при касании может выйти за 40 000. В-третьих, порог в touchAttachInterrupt и touchSleepWakeUpEnable — не абсолютное значение, а прирост относительно значения в покое. На S3 можно также с помощью touchInterruptGetLastStatus(pin) узнать, нажата ли площадка до сих пор. У ESP32-C3 и ESP32-C6 сенсорного датчика нет вообще. Если код пишется для нескольких моделей, разделяй их через CONFIG_IDF_TARGET_ESP32, как в примере с пробуждением.
Идеи проектов с сенсорными пинами
- Настольная лампа: невидимый выключатель из медной ленты, приклеенной за деревянной крышкой, и регулировка яркости долгим касанием.
- Диммер со слайдером: меняй яркость и цвет светодиодной ленты WS2812B слайдером из трёх площадок.
- Дверной звонок или устройство для заметок на батарейках: ESP32 ждёт в глубоком сне, просыпается от касания площадки и отправляет уведомление по Wi-Fi.
- Фруктовое пианино: игрушка с проводами к бананам и яблокам, которая играет свою ноту на каждом фрукте; звук может издавать зуммер.
- Скрытая кодовая панель: замок, который открывается, если в правильном порядке коснуться четырёх площадок, спрятанных внутри коробки.
Сенсорные пины ESP32 дают проекту сенсорный интерфейс благодаря нескольким сантиметрам фольги и паре строк кода. В приложении BlueGrays есть проекты вроде мигания светодиодом на ESP32, управления светодиодом кнопкой, яркости светодиода с ШИМ и глубокого сна — каждый с пошаговой схемой и кодом; замени кнопки сенсорными площадками из этого руководства и собери свою версию.
Частые вопросы
Сколько сенсорных пинов у ESP32?
У классической ESP32 10 ёмкостных сенсорных каналов: T0–T9, то есть GPIO 4, 0, 2, 15, 13, 12, 14, 27, 33 и 32. У ESP32-S2 и ESP32-S3 14 каналов на GPIO 1–14. У ESP32-C3 и C6 сенсорного датчика нет.
Каким должно быть значение touchRead на ESP32?
На классической ESP32 с коротким проводом обычно читается 40–80 в покое и 10–25 при касании. Точное число зависит от провода, размера площадки и окружения. Хорошее начало — измерить на своей установке и выбрать порог примерно в 60 процентов от значения в покое.
Как задать порог касания на ESP32?
Сначала измерь с помощью touchRead значения площадки в покое и при касании. На классической ESP32 поставь порог между ними, обычно на 60 процентов от значения в покое. Самый надёжный способ — измерять значение в покое при запуске, вычислять порог в коде и добавлять гистерезис.
Можно ли разбудить ESP32 из глубокого сна сенсорным пином?
Да. С помощью touchSleepWakeUpEnable(пин, порог) сделай площадку источником пробуждения, затем вызови esp_deep_sleep_start(); при касании площадки плата перезапустится. Классическая ESP32 поддерживает несколько площадок, ESP32-S2 и S3 — одну.
Почему сенсорный пин ESP32 срабатывает сам?
Обычно порог слишком близко к значению в покое, провод площадки длинный или вокруг влажно. Опусти порог, усредняй несколько измерений, добавь гистерезис и укороти провод. Важно также калибровать с тем источником питания, от которого плата будет работать в итоге.
Почему на ESP32-S3 touchRead растёт при касании?
ESP32-S2 и S3 используют сенсорное оборудование второго поколения, в котором измеряемое значение растёт вместе с ёмкостью. Поэтому на S3 при касании значение увеличивается и составляет десятки тысяч. Порог прерывания и пробуждения тоже задаётся как прирост относительно значения в покое, а не как абсолютное число.
Что собрать после прочтения
Все проекты
Мигающий светодиод на ESP32
Учит базовой работе с выходами GPIO на ESP32. Эффект мигания получается включением и выключением светодиода с цифрового пина. Это ESP32-версия классического проекта мигания на Arduino UNO; базовые команды мигания в среде Arduino те же, но расположение пинов ESP32 и уровни GPIO 3,3 V отличаются от Arduino UNO.

Управление светодиодом кнопкой на ESP32 (переключение)
При каждом нажатии кнопки состояние светодиода меняется: если горел — гаснет, если не горел — загорается. Классический шаблон переключения. Антидребезг убирает механический шум кнопки, чтобы одно нажатие давало одно переключение.

Мигание встроенным светодиодом ESP32
Мигание встроенным синим светодиодом на ESP32 DevKit V1. Внешние компоненты не нужны! Первый проект, который стоит попробовать после покупки ESP32. Встроенный светодиод подключён к GPIO 2.

Плавное затухание светодиода с PWM на ESP32
Плавное изменение яркости светодиода от 0 до максимума и от максимума до 0. PWM управляется через analogWrite(), как в Arduino, — тот же синтаксис без проблем работает в ESP32 Arduino Core 3.0+. Достаточно определения пина, pinMode и analogWrite.

Управление RGB-светодиодом на ESP32
Бесконечное число цветов одним RGB-светодиодом вместо 3 отдельных. Как в Arduino, радужный переход получается заданием значений R/G/B через analogWrite(). Теория цвета (например, красный + зелёный = жёлтый) видна на практике.

Глубокий сон ESP32: экономия батареи (OLED + счётчик в RTC RAM)
Режим глубокого сна (Deep Sleep) у ESP32 снижает потребление до ~10 µA, выключая процессор и большую часть периферии, — это важно для IoT-устройств на батарейках. В этом проекте используются три источника пробуждения: таймер (15 секунд), внешний пин (EXT0 — кнопка GPIO 33) и касание (T0/GPIO 4). Переменные с RTC_DATA_ATTR сохраняются во время глубокого сна — счётчики загрузок, пробуждений по таймеру и по кнопке ведутся непрерывно.

Смеситель цветов на ESP32 (3 потенциометра + RGB-светодиод + OLED)
Умная лампа для смешивания цветов на ESP32: вращая три потенциометра, можно получить любой цвет! Когда крутишь потенциометры красного, зелёного и синего, RGB-светодиод с общим катодом меняет цвет в реальном времени. OLED-дисплей SSD1306 показывает значения каждого цвета в диапазоне 0–255, полосы заполнения и веб-код цвета HEX (например, #FF8040). Мини-студия цвета, которая учит теории цвета RGB, чтению АЦП, регулировке яркости через PWM и дизайну экрана I2C.

Умное освещение на ESP32 (PIR + LDR + реле + OLED)
Сделай умное освещение для коридора, ванной или кладовки на ESP32! С PIR-датчиком движения, датчиком освещённости LDR и модулем реле собирается классический сценарий «свет включается при движении в темноте»: если вокруг уже светло, движение свет НЕ включает, и днём энергия экономится. Свет горит 30 секунд; если движение продолжается, таймер сбрасывается, и свет горит дольше. OLED SSD1306 крупно показывает состояние (ON / DAYTIME / WAITING) и обратный отсчёт.
Другие статьи
Приложение BlueGrays
Собери эту схему шаг за шагом в телефоне
Схема подключения, код и список деталей на одном экране. 200+ проектов на Arduino, ESP32 и Pico готовы к сборке.
Наведи камеру телефона
Наведи камеру на код — откроется магазин приложений на телефоне.
или открыть магазин

