Два года я таскал в коробке Arduino Uno и был доволен собой, пока не захотел табло с погодой над рабочим столом, которое само берёт температуру из сети. На Uno нет ни одного сетевого железа: ATmega328P даже не подозревает, что вокруг летают радиоволны. Ethernet-шилд стоил как половина новой платы, а тут в посылке из Китая за 350 рублей приехала плата размером со спичечный коробок, на которой уже сидят WiFi и Bluetooth. Это был ESP32 — и в тот вечер я впервые услышал, как Serial пишет IP-адрес, полученный по воздуху.
В этом уроке я покажу, чем ESP32 отличается от привычной Uno и от ESP8266, как установить пакет плат в Arduino IDE и какие четыре строчки подключают плату к домашней сети. Разберём WiFi.begin(), WiFi.status() и WiFi.localIP() на реальном скетче, повторим подключение в симуляторе прямо на этой странице и закончим экспериментами, которые стоит сделать руками.
ESP32 против Uno и ESP8266: что вы получаете
ESP32 — это не «улучшенная Uno», а устройство другой лиги. Внутри два 32-битных ядра Xtensa LX6, каждое разгоняется до 240 МГц — против одного 8-битного ядра на 16 МГц у Uno. По частоте это в 15 раз быстрее, а на практике разница ещё жирнее: одно ядро ESP32 крутит WiFi-стек, второе целиком отдаётся вашему скетчу, и они не мешают друг другу.
Память — вторая причина перейти на ESP32, как только проект дорос до строк и JSON-ответов. У Uno 2 КБ RAM: строка ответа на килобайт уже грозит переполнением. У ESP32 — 520 КБ RAM и обычно 4 МБ flash, поэтому в скетч спокойно помещаются и HTTP-клиент, и дисплей, и буферы данных. Плюс радиомодуль WiFi 2.4 ГГц (стандарт b/g/n) и Bluetooth с BLE — Uno не умеет ни того, ни другого даже за деньги.
Есть и плата за всё это. Логика ESP32 — 3.3 В, а не 5 В как на Uno: пины не переносят 5-вольтовые сигналы, и это придётся учитывать с каждым датчиком. Аналого-цифровой преобразователь тут точнее — 12 бит, шкала от 0 до 4095 (у Uno 10 бит и 0–1023), но есть нюанс: пины GPIO 34–39 работают только на вход, без подтяжки, и выхода из них не сделаешь. Мнение моё простое: для первых опытов берите DevKit V1 на 38 пинов с USB-чипом CP2102 — если только вы сразу не полезли в батарейный проект с глубоким сном, тогда лучше взять плату с приличным стабилизатором, потому что дешёвые клоны в режиме сна жрут больше, чем обещал даташит.
| Параметр | Arduino Uno | ESP8266 | ESP32 |
|---|---|---|---|
| Ядро | ATmega328P, 8 бит | Tensilica L106, 32 бита | Xtensa LX6, 32 бита, 2 ядра |
| Частота | 16 МГц | 80–160 МГц | до 240 МГц |
| RAM | 2 КБ | около 50 КБ | 520 КБ |
| Flash | 32 КБ | 1–4 МБ (модуль) | обычно 4 МБ |
| WiFi | нет | 2.4 ГГц | 2.4 ГГц, b/g/n |
| Bluetooth | нет | нет | есть, BLE и классический |
| Логика | 5 В | 3.3 В | 3.3 В |
| ADC | 10 бит, 0–1023 | 10 бит | 12 бит, 0–4095 |
Установка esp32 в Arduino IDE: один раз и навсегда
- Откройте Файл → Настройки и в поле «Дополнительные ссылки для Менеджера плат» вставьте адрес пакета Espressif:
https://espressif.github.io/arduino-esp32/package_esp32_index.json(в старых версиях — ссылка на raw.githubusercontent.com, обе рабочие). - Откройте Инструменты → Плата → Менеджер плат, в поиске наберите
esp32, выберите esp32 by Espressif Systems и жмите «Установить». Пакет весит около 200 МБ и качается минут десять — это нормально, не выдёргивайте кабель. - В Инструменты → Плата выберите ESP32 Dev Module — универсальный вариант для почти всех DevKit-плат.
- Подключите плату USB-кабелем и выберите порт в Инструменты → Порт. Порта в списке нет? Поставьте драйвер CP210x (для чипа CP2102) или CH340 — смотря какой USB-мост на вашей плате.
- Скорость монитора порта — 115200 бод: почти все примеры ESP32 шлют отладку именно на этой скорости.
WiFi.begin, WiFi.status, WiFi.localIP: сеть за четыре строчки
#include <WiFi.h> const char* ssid = "MoyaSetka"; // имя вашей сетиconst char* password = "superParol"; // пароль сети void setup() { Serial.begin(115200); // монитор порта — тоже 115200 pinMode(2, OUTPUT); // GPIO 2 — встроенный светодиод платы WiFi.begin(ssid, password); // запускаем подключение Serial.print("Подключаюсь к "); Serial.println(ssid); while (WiFi.status() != WL_CONNECTED) { // ждём готовности delay(500); Serial.print("."); // точечка = «ещё работаю» } Serial.println(); Serial.println("WiFi подключён!"); digitalWrite(2, HIGH); // светится — есть связь Serial.print("IP-адрес платы: "); Serial.println(WiFi.localIP());} void loop() { // пока пусто: сеть уже настроена в setup()}Строка const char* ssid = "MoyaSetka" объявляет текстовую константу — имя сети живёт в памяти программ и не тратит драгоценный RAM. В симуляторе ниже я заменил её на тип String ради простоты, на реальной плате работают оба варианта.
WiFi.begin(ssid, password) не подключается мгновенно — она лишь запускает процесс поиска сети и согласования с роутером. Поэтому сразу за ней идёт цикл: пока WiFi.status() не вернёт WL_CONNECTED, мы каждые полсекунды печатаем точку и мигаем светодиодом. Такой паттерн «запустил — крутился в while» вы будете повторять в каждом сетевом скетче, от HTTP-клиента до веб-сервера.
Когда связь установлена, WiFi.localIP() возвращает адрес, который выдал роутер по DHCP, — например 192.168.1.100. Запишите его: в уроке про веб-сервер именно по этому адресу вы будете открывать страницу из браузера. Учтите, адрес может смениться после перезагрузки роутера — привязать плате постоянный адрес можно настройкой DHCP-резервации на роутере.
И два условия, на которых все спотыкаются. Первое: ESP32 видит только сети 2.4 ГГц — если роутер настроен так, что раздаёт один общий SSID только в 5 ГГц, плата напишет вам вечно моргающий цикл из точек, а вы полчаса будете винить пароль. Второе: кракозябры в мониторе порта означают несломанную плату, а скорость — скетч шлёт на 115200, монитор стоит на 9600.
Эксперименты: закрепите руками
- Засеките время подключения: сохраните
unsigned long t0 = millis();перед WiFi.begin() и после выхода из while выведитеmillis() - t0. В симуляторе подключение займёт 1–2 секунды, на реальной плате — обычно 2–6 секунд, зависит от роутера. - Сделайте индикатор живой связи: в loop() раз в 5 секунд проверяйте
WiFi.status()и печатайте «Связь есть» или «Связи нет» через if иmillis()— без delay(), чтобы loop() не блокировался. - Поменяйте ssid на несуществующую сеть и подумайте заранее, что произойдёт. В симуляторе плата всё равно «подключится» — эмуляция добрая. На реальной плате цикл станет бесконечным, и это подсказка к следующему шагу: в настоящих скетчах в while добавляют таймаут через millis() и выходят из него с ошибкой, если сеть так и не нашлась.
- Выведите IP раз в 10 секунд в loop(): вы убедитесь, что адрес плата хранит постоянно, и научитесь печатать значение WiFi.localIP() из любого места скетча.
- ESP32: 32 бита, 240 МГц, два ядра, 520 КБ RAM, WiFi 2.4 ГГц и Bluetooth — по цене трети Uno
- Логика 3.3 В (5 В на пины подавать нельзя), ADC 12 бит — 0–4095, GPIO 34–39 — только вход
- Ошибка «WiFi.h: No such file or directory» лечится установкой пакета плат ESP32 в Boards Manager, а не скачиванием файла вручную
- Подключение: WiFi.begin(ssid, pass) → while (WiFi.status() != WL_CONNECTED) → WiFi.localIP()
- Монитор порта — строго 115200 бод, иначе вместо отладки кракозябры
- 1. Скетч со строкой #include <WiFi.h> не компилируется: No such file or directory. В чём причина?
- 2. Чем ESP32 отличается от Arduino Uno? Верное утверждение:
- 3. Роутер раздаёт две сети: одну в диапазоне 2.4 ГГц, вторую в 5 ГГц. Какую увидит ESP32?
- 4. Что вернёт analogRead() на ESP32 при напряжении 1.65 В на пине?
- 5. Вы соединили выходной пин Uno (5 В) напрямую с GPIO платы ESP32. Что будет?
- 6. Что произойдёт сразу после вызова WiFi.begin(ssid, password)?
Если у вас плата на столе — загрузите скетч из этого урока и попробуйте все четыре эксперимента на железе: симулятор и реальная плата дополняют друг друга. Дальше по разделу интереснее: в следующем уроке научим плату не просто сидеть в сети, а самой ходить в интернет за данными — шлём HTTP GET-запросы, разбираем коды ответов и вытаскиваем из текстового ответа настоящие числа. А пока запомните главное правило безопасности: 3.3 В на пинах, 5 В — только на пин питания VIN от хорошего источника.
Частые вопросы по теме урока
- Скетч со строкой #include <WiFi.h> не компилируется: No such file or directory. В чём причина?
- WiFi.h входит в пакет плат Espressif. Без него IDE не знает ни саму плату, ни её библиотеки; ручное копирование файла только ломает сборку. Не установлен пакет плат ESP32 в Менеджере плат
- Чем ESP32 отличается от Arduino Uno? Верное утверждение:
- У ESP32 два ядра на 240 МГц. В остальных пунктах всё наоборот: логика у него 3.3 В, ADC — 12 бит (0–4095), RAM — 520 КБ. Частота 240 МГц против 16 МГц и два ядра вместо одного
- Роутер раздаёт две сети: одну в диапазоне 2.4 ГГц, вторую в 5 ГГц. Какую увидит ESP32?
- В ESP32 стоит радиомодуль 2.4 ГГц (802.11 b/g/n). Диапазон 5 ГГц он не видит физически — подключайте плату к сети 2.4 ГГц. Только 2.4 ГГц
- Что вернёт analogRead() на ESP32 при напряжении 1.65 В на пине?
- ADC у ESP32 12-битный: полная шкала 0–4095. Половина напряжения — половина шкалы, примерно 2048. Около 2048
- Вы соединили выходной пин Uno (5 В) напрямую с GPIO платы ESP32. Что будет?
- Логика ESP32 — 3.3 В и пины не толерантны к 5 В. Для связи с 5-вольтовой техникой ставят делитель напряжения или конвертер уровней. GPIO рассчитан на 3.3 В, пин ESP32 можно вывести из строя
- Что произойдёт сразу после вызова WiFi.begin(ssid, password)?
- WiFi.begin только запускает подключение. Результат проверяют циклом: while (WiFi.status() != WL_CONNECTED) { delay(500); } Запустится процесс подключения, готовность проверяют через WiFi.status()