Руководства · 9 мин чтения

Сенсорные пины ESP32: touchRead, порог, прерывание и слайдер

Руководство по сенсорным пинам ESP32: таблица пинов T0–T9, значения touchRead и порог, кнопки и слайдеры из фольги, touchAttachInterrupt и пробуждение из глубокого сна касанием.

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

В этом руководстве сначала разберёмся, какой GPIO подключён к какому сенсорному каналу и от каких пинов лучше держаться подальше. Затем прочитаем значения touchRead, подберём правильный порог и напишем надёжную сенсорную кнопку с автокалибровкой и гистерезисом. Ещё ты узнаешь, как сделать площадки из фольги и медной ленты, как регулировать яркость светодиода слайдером из трёх площадок, как работать с прерываниями через touchAttachInterrupt и как будить ESP32 из глубокого сна касанием. В последних разделах — проблемы с влажностью и помехами, отличия ESP32-S3 и короткий пример на MicroPython.

Отладочная плата ESP32
У классической ESP32 есть 10 ёмкостных сенсорных каналов с именами T0–T9; дополнительный модуль не нужен.

Как работают сенсорные пины ESP32?

Каждый сенсорный пин подключён к измерительной схеме внутри чипа. Эта схема непрерывно заряжает и разряжает пин и считает, сколько циклов заряда-разряда успевает пройти за фиксированное время. Провод и площадка на пине ведут себя как маленький конденсатор. Когда ты подносишь палец, твоё тело добавляет к этому конденсатору несколько пикофарад, заряд и разряд замедляются, и за то же время проходит меньше циклов. Поэтому на классической ESP32 значение touchRead при касании падает. С коротким проводом в покое обычно видно 40–80; при касании пальцем значение опускается примерно до 10–25. Эти числа зависят от длины провода, размера площадки, платы и окружения, поэтому никогда не вписывай порог по памяти: измерь его на своей установке.

ХарактеристикаКлассическая ESP32ESP32-S2 / ESP32-S3
Число сенсорных каналов10 (T0–T9)14 (T1–T14)
Значение при касанииПадаетРастёт
Типичное значение в покое40–80От тысяч до десятков тысяч
Тип, возвращаемый touchReaduint16_tuint32_t
Порог прерыванияАбсолютное значение, срабатывает ниже негоПрирост относительно значения в покое
Пробуждение из глубокого снаНесколько площадокОдна площадка

Таблица сенсорных пинов ESP32 (T0–T9)

Сенсорные каналы подключены только к определённым GPIO; если вызвать touchRead на другом пине, осмысленного значения не будет. Ядро Arduino определяет для этих каналов готовые константы вроде T0 и T1, так что touchRead(T0) в коде — то же самое, что touchRead(4). Некоторые из этих пинов — пины конфигурации при старте (strapping), которые определяют, как плата запускается при включении; как сенсорные они работают, но выбирать их в первую очередь не стоит.

КаналGPIOПримечание
T0GPIO 4Безопасный, первый выбор
T1GPIO 0Подключён к кнопке BOOT, на 30-пиновых платах не выведен; не используй
T2GPIO 2Подключён к встроенному светодиоду, пин конфигурации при старте; значения могут «плавать»
T3GPIO 15Пин конфигурации при старте (влияет на сообщения при загрузке); используй осторожно
T4GPIO 13Безопасный
T5GPIO 12Пин конфигурации при старте (напряжение флеш-памяти); если при включении на нём высокий уровень, плата не запустится
T6GPIO 14Безопасный, при загрузке выдаёт короткий ШИМ-сигнал
T7GPIO 27Безопасный
T8GPIO 33Безопасный
T9GPIO 32Безопасный
Обрати внимание на порядок T8 и T9: T8 — это GPIO 33, а T9 — GPIO 32; выглядит перепутанным, но это правильно. Кроме того, никогда не подавай на сенсорный пин больше 3,3 V и не используй один и тот же пин одновременно как сенсорный вход и цифровой выход. Где находятся пины на твоей плате, можно посмотреть в утилите распиновки.

Делаем площадки: провод, алюминиевая фольга и медная лента

В качестве сенсорной площадки подойдёт любая проводящая поверхность. Проще всего — оголённый конец перемычки, вставленной в пин. Для более удобной поверхности можно взять кусочек алюминиевой фольги 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), можно в реальном времени наблюдать обе линии и видеть, как значения падают при касании.

C++ (Arduino IDE)
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 процентов от значения в покое. Использование двух отдельных порогов называется гистерезисом; он не даёт кнопке срабатывать раз за разом, когда значение дрожит прямо на границе. Если интересна механическая сторона кнопок, загляни в статью как подключить кнопку.

C++ (Arduino IDE)
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Не даёт светодиоду переключаться снова и снова, пока палец лежит на площадке
Во время калибровки при запуске площадку трогать нельзя. Если плата стоит в коробке и при включении кто-то может коснуться площадки, можно сохранить значение в покое в EEPROM или Preferences и проверять его при каждом запуске, либо использовать среднее, которое очень медленно следует за значением в покое (например, обновляется на 1 процент каждую секунду).

Прерывания по касанию с touchAttachInterrupt

Вместо того чтобы постоянно вызывать touchRead, можно поручить сенсорному оборудованию измерять в фоне и вызывать функцию, когда значение опустится ниже порога. Для этого служит touchAttachInterrupt(пин, функция, порог). На классической ESP32 прерывание срабатывает, когда измеренное значение опускается ниже порога, и повторяется в каждом цикле измерения, пока палец остаётся на площадке. Поэтому функция прерывания должна только выставлять флаг, а основная работа должна выполняться в loop() с проверкой времени. Общие правила прерываний разобраны в статье прерывания Arduino.

C++ (Arduino IDE)
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
C++ (Arduino IDE)
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.

C++ (Arduino IDE)
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(порог).

MicroPython
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; он сам распознаёт касание и выдаёт обычный цифровой сигнал.

Сенсорный модуль TTP223
На платах без встроенных сенсорных пинов модуль TTP223 распознаёт касание и выдаёт цифровой сигнал.

Проблемы с влажностью, водой и помехами

Ёмкостное измерение реагирует не только на пальцы, но и на воду. Капля воды или сильная влажность на площадке увеличивают ёмкость, значение падает, и кнопка может сработать сама. В проектах для ванной, кухни или улицы размещай площадку за поверхностью, на которой не задерживается вода, выбирай порог чуть ниже и требуй, чтобы касание длилось не меньше 50–100 мс. Длинные провода, расположенные рядом реле и моторы, а также плохой USB-источник питания тоже заставляют значения «плавать». В таблице ниже собраны самые частые проблемы и их решения.

ПроблемаВероятная причинаРешение
Срабатывает самоПорог слишком близко к значению в покоеОпусти порог до 60% от значения в покое, добавь гистерезис
Значения постоянно скачутДлинный или висящий провод, зашумлённое питаниеУкороти провод, усредняй 4–8 измерений, возьми хороший USB-кабель
После отключения от компьютера изменилась чувствительностьИзменилась опорная земляКалибруй в итоговой конфигурации, с батареей или блоком питания
Срабатывает при влажности или от капли водыВода увеличивает ёмкостьСпрячь площадку за покрытие, задай минимальное время касания
Один пин вообще не меняетсяИспользован несенсорный GPIOСверься с таблицей пинов; GPIO 34–39 не сенсорные
Плата не запускаетсяПлощадка и провод на GPIO 12 мешают загрузкеПеренеси площадку на GPIO 4, 13, 27, 32 или 33
В постоянном проекте держи провод площадки коротким и закреплённым, сделай вокруг площадки кольцо GND с зазором 2–3 мм и заново измерь порог, когда плата уже стоит в своей коробке. Крышка коробки, трасса провода и даже положение руки меняют значение в покое на несколько единиц.

Сенсорные пины на 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
#103Новичок

Мигающий светодиод на ESP32

Учит базовой работе с выходами GPIO на ESP32. Эффект мигания получается включением и выключением светодиода с цифрового пина. Это ESP32-версия классического проекта мигания на Arduino UNO; базовые команды мигания в среде Arduino те же, но расположение пинов ESP32 и уровни GPIO 3,3 V отличаются от Arduino UNO.

4.7(37)
100
Управление светодиодом кнопкой на ESP32 (переключение)
#105Новичок

Управление светодиодом кнопкой на ESP32 (переключение)

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

4.6(39)
58
Мигание встроенным светодиодом ESP32
#106Новичок

Мигание встроенным светодиодом ESP32

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

4.8(29)
53
Плавное затухание светодиода с PWM на ESP32
#110Новичок

Плавное затухание светодиода с PWM на ESP32

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

4.8(36)
55
Управление RGB-светодиодом на ESP32
#111Новичок

Управление RGB-светодиодом на ESP32

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

4.6(29)
51
Глубокий сон ESP32: экономия батареи (OLED + счётчик в RTC RAM)
#135Продвинутый
Premium

Глубокий сон ESP32: экономия батареи (OLED + счётчик в RTC RAM)

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

4.3(10)
16
Смеситель цветов на ESP32 (3 потенциометра + RGB-светодиод + OLED)
#138Продвинутый
Premium

Смеситель цветов на ESP32 (3 потенциометра + RGB-светодиод + OLED)

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

4.7(6)
10
Умное освещение на ESP32 (PIR + LDR + реле + OLED)
#141Продвинутый
Premium

Умное освещение на ESP32 (PIR + LDR + реле + OLED)

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

4.3(6)
11