История про сэкономленные 200 рублей. Собирал стенд с OLED, энкодером и серво, в корзину легла плата на C3 — та же ESP32, только дешевле и миниатюрнее. Итог: ноги кончились на середине проекта, потому что часть GPIO у C3 отдана встроенному USB и флешу, а половина оставшихся сидит на strapping. В итоге плата-малышка ушла в ящик, а стенд собрался на классическом DevKit V1 — который я, собственно, и должен был взять сразу. Ошибка стоила не денег, а двух вечеров перепланировки пинов.
Семейство ESP32 давно перестало быть одной платой: классический WROOM-32 на DevKit V1, компактный одноядерный C3 и мощный двухъядерный S3 продаются рядом, выглядят почти одинаково и зовутся одинаково, а проекты у них разные. Разберём, чем они отличаются по ядрам, радио и числу ног, почему на C3 и S3 Serial идёт прямо через USB без CP2102 и что такое конфликт ADC2 с WiFi — на примерах из практики, чтобы при следующем заказе выбор занимал минуту, а не вечер чтения форумов.
Три брата: WROOM-32, C3 и S3
DevKit V1 — это ESP32-WROOM-32: два ядра Xtensa по 240 МГц, WiFi 2,4 ГГц, Bluetooth классический плюс BLE, до 25 GPIO на штырьках. C3 — одно ядро RISC-V на 160 МГц, WiFi и только BLE 5, ног заметно меньше (из-за USB и флеша свободными остаются считанные единицы на модулях с малым корпусом), зато цена и размер минимальные. S3 — старший: два ядра Xtensa по 240 МГц, WiFi и BLE 5, до 45 GPIO, опциональный PSRAM и настоящий USB-OTG, на котором чип представляется клавиатурой или мышью без внешних прошивок. Классического Bluetooth у C3 и S3 нет — если проект дружит с SPP-модулями или аудио по BT, остаются только WROOM.
Вторая разница, о которую спотыкаются на первой неделе: USB. На DevKit V1 стоит мост CP2102, и Serial идёт через него. У C3 и S3 есть собственный USB-контроллер: в Arduino IDE включаешь опцию «USB CDC On Boot», и Serial.print идёт прямо в USB-разъём чипа. Плюс — меньше деталей на плате; минус — порт появляется после загрузки скетча, и первые строки лога без delay(500) в setup() теряются. Третья разница тонкая, но коварная: на WROOM и C3 второй АЦП (ADC2) перестаёт работать при включённом WiFi — аналоговые входы берут с ADC1 (GPIO32-39 на WROOM), иначе analogRead вернёт мусор. Про опасные пины обеих плат у меня уже есть разбор распиновки — там же про strapping GPIO0/2/12/15.
// Один скетч для DevKit V1, C3 и S3: скан эфира и MAC-адрес.// На C3/S3 в настройках платы включи "USB CDC On Boot: Enabled",// иначе Serial пойдёт мимо USB и лог будет пуст.#include <WiFi.h> const int PIN_LED = 2; // D2: на DevKit V1 - встроенный, на C3/S3 - свой void setup() { Serial.begin(115200); delay(500); // порт успевает подняться pinMode(PIN_LED, OUTPUT); Serial.print("MAC: "); Serial.println(WiFi.macAddress()); WiFi.mode(WIFI_STA); // только клиент, сеть не поднимаем} void loop() { Serial.println("--- skan setej ---"); int n = WiFi.scanNetworks(); // блокирующий скан, тут LED горит digitalWrite(PIN_LED, HIGH); for (int i = 0; i < n; i++) { Serial.print(WiFi.SSID(i)); Serial.print(" RSSI "); Serial.println(WiFi.RSSI(i)); } digitalWrite(PIN_LED, LOW); delay(5000);}Скетч намеренно не использует ни одного pin-номера, кроме LED, — поэтому компилируется на всех трёх платах без правок. delay(500) в setup() — прямое следствие USB-CDC на C3 и S3: последовательный порт появляется не сразу, и без паузы теряются первые строки. WiFi.scanNetworks() блокирующий — на WROOM во время скана ADC2 уже нечитаем, поэтому если у тебя на плате аналоговый датчик, скан и опрос АЦП разнеси по времени, о чём честно говорит таблица ниже.
Практическое правило, к которому я пришёл после пары переделок: берёшь плату под конкретный проект. Один датчик и батарейка — C3. Стенд с кучей периферии, дисплеем и классическим Bluetooth — DevKit V1. USB-клавиатура, камера, PSRAM, тяжёлые задачи — S3. «На вырост» покупаю только DevKit V1: у него запас ног, который в один вечер спасает проект.
| Параметр | DevKit V1 (WROOM-32) | ESP32-C3 | ESP32-S3 |
|---|---|---|---|
| Ядро | 2× Xtensa 240 МГц | 1× RISC-V 160 МГц | 2× Xtensa 240 МГц |
| Радио | WiFi + BT Classic + BLE | WiFi + BLE 5 (Classic нет) | WiFi + BLE 5 (Classic нет) |
| GPIO на штырьках | до 25 | 13-15 | до 45 |
| USB | мост CP2102 | встроенный, CDC | встроенный, CDC + OTG/HID |
| ADC при WiFi | только ADC1 (GPIO32-39) | только ADC1 | ADC1 + ADC2 работают |
| Strapping-пины | GPIO0, 2, 12, 15 | GPIO2, 8, 9 (9 = BOOT) | GPIO0, 3, 45, 46 |
| Когда брать | универсал, много ног, SPP | дешёво, мелко, батарейка | HID, камеры, PSRAM, экраны |
- 1. Какой чип умеет USB-OTG и представляется компьютеру клавиатурой без внешних схем?
- 2. На DevKit V1 включён WiFi. С каких пинов analogRead вернёт адекватные значения?
- DevKit V1 — универсал: 2 ядра, BT Classic + BLE, до 25 GPIO, запас на вырост
- C3 — дёшево и мелко для одного датчика на батарейке, но ног мало и нет BT Classic
- S3 — HID, PSRAM и до 45 GPIO: бери под экраны, камеры и USB-периферию
- USB CDC On Boot на C3/S3: delay(500) в setup(), иначе первые строки лога теряются
Частые вопросы по теме урока
- Какой чип умеет USB-OTG и представляется компьютеру клавиатурой без внешних схем?
- USB-OTG с классами HID есть только у S3. CDC On Boot на C3 лишь создаёт последовательный порт через встроенный USB, клавиатурой чип от этого не станет. У WROOM USB вообще через мост CP2102. ESP32-S3
- На DevKit V1 включён WiFi. С каких пинов analogRead вернёт адекватные значения?
- При активном WiFi периферия ADC2 отдана радиомодулю — классическая ловушка WROOM и C3. ADC1 (GPIO32-39 на WROOM) продолжает работать, либо скан и опрос АЦП разносят по времени. только с ADC1 (GPIO32-39)