Wi-Fi · разбор
Wi-Fi для Arduino: как подключить плату к сети
«Хочу, чтобы плата выходила в интернет» — самая частая просьба после первого мигающего светодиода. Разбираем, какой дорогой идти, почему плата не видит вашу сеть, сколько ей нужно тока и что она сможет делать дальше. Схемы на странице живые: их можно щёлкать. Все числа — из даташитов, исходников ядер и карточек наших плат.
Короткий ответ для нетерпеливых. У обычной Arduino Uno Wi-Fi нет и не появится: чипа радио на ней просто не установлено. Дешевле и проще всего не добавлять модуль к Uno, а взять отдельную плату, у которой радио уже внутри — например D1 mini за 290 ₽. Среда та же, скетч тот же, библиотеку ставить не нужно. Дальше по странице — почему так, и что делать, если менять плату нельзя.
Почему «модуль Wi-Fi» — это не то же самое, что модуль Bluetooth
С Bluetooth-модулем всё просто: он работает как удлинитель для двух проводов. Что плата отправила — то на телефоне появилось. Никакой библиотеки, никаких настроек. Люди по привычке ждут того же и от Wi-Fi, а получают совсем другое.
Wi-Fi — это не труба для байтов, а целая почтовая система. Чтобы отправить одно число, устройству нужно найти сеть, доказать роутеру, что оно знает пароль, получить адрес, узнать адрес получателя, собрать пакет, дождаться подтверждения и переслать заново то, что потерялось. Всё это — работа для отдельного процессора с собственной памятью.
Поэтому «модуль Wi-Fi» — это не деталь, а второй компьютер, который сильнее вашей Arduino. У модуля ESP-01, который чаще всего покупают к Uno, внутри чип ESP8266: он быстрее ATmega328 примерно в пять раз и памяти у него в двадцать раз больше. Возить такого пассажира и командовать им из Uno текстовыми командами — занятие неблагодарное. Гораздо честнее пересесть на него самого.
Отсюда главный вывод страницы, который экономит и деньги, и вечер: в большинстве случаев Wi-Fi к Arduino не добавляют, а меняют плату на такую, где он уже есть. Плата с радио внутри стоит дешевле, чем модуль плюс питание к нему, программируется в той же среде и тем же кодом.
Четыре дороги и их честная цена
Дорог на самом деле четыре, и выбирать между ними стоит один раз — до покупки, а не после третьего вечера с паяльником.
| Путь | Что покупаете | Что умеет | Порядок цены | Кому подходит |
|---|---|---|---|---|
| Плата, у которой Wi-Fi внутри | Одна плата: D1 mini на чипе ESP8266 или плата на ESP32 | Всё сама: и сеть, и программа. Библиотека уже в ядре платы | от 290 ₽ | Почти всем. Это самый короткий и самый дешёвый путь |
| Плата на ESP32 в корпусе Arduino Uno | Плата того же размера и с той же гребёнкой, но с радио внутри | То же самое, плюс на неё садятся привычные шилды | 770 ₽ | Тем, у кого проект уже собран на шилдах и в корпусе |
| Отдельный модуль к Arduino Uno | Модуль ESP-01, отдельное питание 3,3 В и делитель на линию приёма | Только через текстовые AT-команды: Uno диктует, модуль отвечает | у нас не продаётся | Тем, кому нельзя менять основную плату. Это трудный путь |
| Провод вместо радио | Ethernet-шилд или модуль W5500 плюс патч-корд | Ту же сеть, но без пароля, без помех и без переподключений | от 640 ₽ | Стационарным поделкам, которые должны работать годами |
Про установку самих плат в среду тут не пишем, чтобы не пересказывать соседние страницы: как поставить поддержку ESP8266 и что означают надписи D1, D2, D4 на её выводах — на странице ESP8266, NodeMCU и Wemos D1 mini, а про ESP32 и её распиновку — здесь. Пакеты плат наша среда берёт с собственного зеркала, поэтому установка не упирается в закрытые сайты.
Что должно быть с вашей сетью, чтобы плата её увидела
Половина вопросов «плата не подключается» решается не в коде, а в настройках роутера. Причина в том, что радио у платы гораздо проще телефонного, и то, что телефон проглатывает не глядя, для платы оказывается непреодолимым.
Самая частая история звучит так: «телефон эту сеть видит, а плата — нет». Почти всегда дело в диапазоне. Современный роутер вещает сразу в двух: 2,4 гигагерца и 5 гигагерц. Пятигигагерцевая сеть быстрее, и телефон обычно выбирает её. А радио у ESP8266 и ESP32 работает только на 2,4 — это заложено в самих чипах, и никакой настройкой это не меняется.
Отдельная ловушка — когда обе сети названы одинаково. Роутер считает это удобством: устройство само выберет, где лучше. Плата же видит только двухгигагерцевую половину, и получается, что иногда она подключается, а иногда нет, будто по настроению. Самое разумное — дать сети 2,4 ГГц собственное имя и указывать в скетче именно его.
| Что нужно от сети | Почему | Что сделать |
|---|---|---|
| Диапазон 2,4 ГГц | Радио платы работает только здесь. Сеть на 5 ГГц она не увидит никогда | В настройках роутера включите сеть 2,4 ГГц отдельным пунктом |
| Отдельное имя для 2,4 ГГц | Если оба диапазона названы одинаково, плата видит только половину сети и подключается через раз | Дайте двухгигагерцевой сети своё имя, например с добавкой -24 |
| Защита WPA2 | WPA3 умеет только ESP32. В ядре ESP8266 такого способа защиты нет вовсе | Поставьте WPA2 или смешанный режим WPA2/WPA3 |
| Имя латиницей | Русские буквы в имени сети — источник загадочных отказов: в скетче это байты, а не буквы | Переименуйте сеть латиницей или заведите отдельную сеть для поделок |
| Пароль от 8 знаков | Короче восьми знаков пароль WPA2 не бывает: плата такую сеть просто не примет | Проверьте пароль в настройках роутера, а не по памяти |
| Не гостевая сеть | В гостевой сети устройства обычно изолированы друг от друга: плата подключится, но с телефона не откроется | Посадите плату и телефон в одну и ту же основную сеть |
| Имя сети видно | Скрытую сеть сканер не покажет, и найти опечатку в имени будет нечем | На время настройки включите объявление имени |
| Без входа через страницу | Сети в кафе и на работе просят нажать кнопку на странице входа. Плата этого сделать не может | Для поделок нужна обычная домашняя сеть или отдельная точка доступа |
Первый скетч: посмотреть, что плата слышит
Прежде чем подключаться, полезно узнать, что плата вообще находит в эфире. Этот скетч печатает список сетей с номером канала и уровнем сигнала. Если вашей сети в списке нет — дальше можно не мучиться с паролем: проблема в диапазоне, в скрытом имени или в расстоянии.
Один и тот же текст работает и на ESP8266, и на ESP32: строчка #if defined(ESP8266) подставляет нужную библиотеку. Ставить её никуда не надо — она приезжает вместе с поддержкой платы.
// Что плата вообще слышит в эфире. Запускать до первого подключения:
// если вашей сети в списке нет - дело не в пароле, а в диапазоне,
// в скрытом имени или в расстоянии.
#if defined(ESP8266)
#include <ESP8266WiFi.h>
#define OPEN_NETWORK ENC_TYPE_NONE
#else
#include <WiFi.h>
#define OPEN_NETWORK WIFI_AUTH_OPEN
#endif
void setup() {
Serial.begin(115200);
delay(200);
Serial.println();
WiFi.mode(WIFI_STA); // клиент, но пока никуда не подключаемся
WiFi.disconnect();
delay(100);
}
void loop() {
Serial.println("Ищу сети...");
int found = WiFi.scanNetworks();
if (found <= 0) {
Serial.println("Ни одной сети. Плата слышит только диапазон 2,4 ГГц.");
} else {
for (int i = 0; i < found; i++) {
Serial.print(i + 1);
Serial.print(". ");
Serial.print(WiFi.SSID(i));
Serial.print(" канал ");
Serial.print(WiFi.channel(i));
Serial.print(" сигнал ");
Serial.print(WiFi.RSSI(i));
Serial.print(" dBm ");
if (WiFi.encryptionType(i) == OPEN_NETWORK) {
Serial.println("без пароля");
} else {
Serial.println("с паролем");
}
}
}
WiFi.scanDelete(); // освобождаем память под список
delay(10000);
}
Уровень сигнала печатается в дБм и всегда отрицательный: чем ближе к нулю, тем лучше. Примерные ориентиры: до −60 — отлично, до −70 — нормально, дальше −75 начнутся потери пакетов и «плата отваливается».
Подключаемся к сети
Теперь собственно подключение. Обратите внимание на две вещи: ожидание ограничено двадцатью секундами (иначе непонятно, что происходит), а при неудаче печатается код состояния — по нему дальше и ведётся вся диагностика.
// Плата подключается к домашней сети Wi-Fi и печатает свой адрес.
// Один и тот же скетч работает и на ESP8266 (D1 mini, NodeMCU), и на
// ESP32: нужную библиотеку подставляет компилятор.
#if defined(ESP8266)
#include <ESP8266WiFi.h>
#else
#include <WiFi.h>
#endif
// Регистр букв важен: "MyHome" и "myhome" - это разные сети.
// Сеть должна быть в диапазоне 2,4 ГГц: пятигигагерцевую плата не увидит.
const char WIFI_SSID[] = "имя вашей сети";
const char WIFI_PASS[] = "пароль от сети";
void setup() {
Serial.begin(115200);
delay(200);
Serial.println();
WiFi.mode(WIFI_STA); // режим клиента: плата идёт к роутеру
WiFi.begin(WIFI_SSID, WIFI_PASS);
Serial.print("Подключаюсь");
unsigned long start = millis();
// Ждём не вечно, а 20 секунд: иначе непонятно, что вообще происходит.
while (WiFi.status() != WL_CONNECTED && millis() - start < 20000) {
delay(500);
Serial.print(".");
}
Serial.println();
if (WiFi.status() == WL_CONNECTED) {
Serial.print("Готово. Адрес платы в сети: ");
Serial.println(WiFi.localIP());
Serial.print("Уровень сигнала: ");
Serial.print(WiFi.RSSI());
Serial.println(" dBm (ближе к нулю - лучше)");
} else {
// Расшифровка кодов - в таблице на странице: у ESP8266 и ESP32
// одна и та же цифра означает разное.
Serial.print("Не подключился. Код состояния: ");
Serial.println((int)WiFi.status());
}
}
void loop() {
// Вся работа сделана один раз в setup().
}
Что должно появиться в мониторе порта: несколько точек, а потом строчка вида «Адрес платы в сети: 192.168.1.47». Этот адрес — то, что вам понадобится дальше: именно его набирают в браузере, чтобы открыть страницу управления.
Коды состояния: одна цифра — два разных смысла
Метод WiFi.status() возвращает число. Тонкость, о которой почти нигде не написано: у ESP8266 и ESP32 эти числа означают разное. Мы сверили их прямо по исходникам ядер, а не по чужим статьям.
| Код | ESP8266 | ESP32 | Что это значит на практике |
|---|---|---|---|
| 0 | простой | простой | Ещё ничего не начиналось. Подождите или вызовите WiFi.begin() |
| 1 | сеть не найдена | сеть не найдена | Имя написано не так, сеть на 5 ГГц, сеть скрыта или плата слишком далеко |
| 2 | сканирование закончено | сканирование закончено | Служебное состояние, встречается редко |
| 3 | подключено | подключено | Всё хорошо: можно печатать адрес |
| 4 | не удалось подключиться | не удалось подключиться | У ESP32 это чаще всего неверный пароль: отдельного кода про пароль у неё нет |
| 5 | связь потеряна | связь потеряна | Была связь и пропала: слабый сигнал или роутер перезагрузился |
| 6 | неверный пароль | отключено | Одна цифра — два разных смысла. На ESP8266 проверьте пароль, на ESP32 — вызовите WiFi.begin() снова |
| 7 | отключено | такого кода нет | Плата отключена от сети намеренно или ещё не начинала |
| 255 | такого кода нет | радио не запущено | Не вызван WiFi.mode() или радио выключено |
Самая обидная строка — шестая. Человек читает в интернете «код 6 — неверный пароль», меняет пароль в скетче по десять раз, а у него ESP32, и шестёрка там означает всего лишь «сейчас не подключено». Проверьте, какая у вас плата, прежде чем верить чужой расшифровке.
Связь рвётся — и это нормально
Домашний Wi-Fi живёт своей жизнью: роутер перезагружают, соседи включают микроволновку, кто-то уносит плату в другую комнату. Скетч, который подключается один раз в setup(), после первого же обрыва становится мёртвым куском кода: сеть пропала, а он этого даже не заметил.
Правильный скетч сторожит связь и переподключается сам — и делает это, не останавливая программу. Никаких while с ожиданием сети в loop(): пока программа стоит в таком цикле, она не читает датчики и не отвечает на нажатия.
// Связь иногда пропадает: роутер перезагрузили, сигнал просел, помеха.
// Скетч следит за связью и переподключается, не останавливая программу:
// никаких delay() в ожидании сети.
#if defined(ESP8266)
#include <ESP8266WiFi.h>
// У D1 mini и NodeMCU встроенный светодиод инверсный: LOW - это «горит».
#define STATUS_LED LED_BUILTIN
#define LED_ON LOW
#define LED_OFF HIGH
#else
#include <WiFi.h>
// У плат на ESP32 единого встроенного светодиода нет: на большинстве он
// висит на выводе 2, а на некоторых его нет вовсе - тогда поставьте свой.
#define STATUS_LED 2
#define LED_ON HIGH
#define LED_OFF LOW
#endif
const char WIFI_SSID[] = "имя вашей сети";
const char WIFI_PASS[] = "пароль от сети";
const unsigned long RETRY_MS = 10000; // как часто пробовать снова
unsigned long lastTry = 0;
bool wasConnected = false;
// Одна и та же цифра у двух чипов означает разное - поэтому две таблицы.
const char* statusName(int code) {
#if defined(ESP8266)
switch (code) {
case 0: return "простой";
case 1: return "сеть с таким именем не найдена";
case 2: return "сканирование закончено";
case 3: return "подключено";
case 4: return "не удалось подключиться";
case 5: return "связь потеряна";
case 6: return "неверный пароль";
case 7: return "отключено";
}
#else
switch (code) {
case 0: return "простой";
case 1: return "сеть с таким именем не найдена";
case 2: return "сканирование закончено";
case 3: return "подключено";
case 4: return "не удалось подключиться (чаще всего - пароль)";
case 5: return "связь потеряна";
case 6: return "отключено";
case 255: return "радио не запущено";
}
#endif
return "неизвестный код";
}
void setup() {
Serial.begin(115200);
delay(200);
Serial.println();
pinMode(STATUS_LED, OUTPUT);
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASS);
lastTry = millis();
}
void loop() {
bool connected = (WiFi.status() == WL_CONNECTED);
if (connected != wasConnected) {
wasConnected = connected;
if (connected) {
Serial.print("Связь есть, адрес ");
Serial.println(WiFi.localIP());
} else {
Serial.println("Связь пропала, пробую снова");
}
}
if (!connected && millis() - lastTry > RETRY_MS) {
lastTry = millis();
Serial.print("Состояние: ");
Serial.println(statusName((int)WiFi.status()));
WiFi.disconnect();
WiFi.begin(WIFI_SSID, WIFI_PASS);
}
// Пока нет связи - светодиод мигает, есть связь - горит ровно.
if (connected) {
digitalWrite(STATUS_LED, LED_ON);
} else {
digitalWrite(STATUS_LED, (millis() / 300) % 2 ? LED_ON : LED_OFF);
}
}
Заодно этот скетч показывает состояние светодиодом: горит ровно — связь есть, мигает — идёт переподключение. Мелочь, а отлаживать поделку без монитора порта становится возможно.
Ещё одна вещь, о которой спрашивают: адрес платы может меняться. Роутер выдаёт его в аренду, и после перезагрузки плата может получить другой. Лечится двумя способами: либо в настройках роутера закрепить за платой постоянный адрес (это самый надёжный путь), либо задать адрес прямо в скетче методом WiFi.config(). Есть и третий, красивый способ — имя вида plata.local. Но полагаться на него нельзя: такие имена понимает не всякий телефон, Android научился этому только с двенадцатой версии, а многие роутеры режут нужную для этого групповую рассылку.
Питание: главная причина «плата сошла с ума»
Если запомнить со страницы только одно, пусть это будет вот что. Wi-Fi ест ток рывками. В покое плата потребляет около 80 миллиампер, но в момент передачи — короткими всплесками в несколько раз больше. Изготовитель чипа прямо пишет: источник должен отдавать не меньше 500 миллиампер.
Что происходит, если источник слабый: во время всплеска напряжение проседает, чип считает это сбоем питания и перезапускается. Со стороны это выглядит как заколдованный круг — плата стартует, доходит до подключения, перезагружается, стартует снова. Программу при этом можно переписывать бесконечно, толку не будет.
Отсюда же самая известная беда пути «модуль ESP-01 к Arduino Uno». Модуль пытаются питать от вывода 3V3 самой Uno, а у этого вывода официальный потолок — 50 миллиампер. Это в десять раз меньше требуемого. Модуль будет включаться, мигать и умирать при первой же попытке выйти в эфир.
Что помогает на практике: отдельный источник питания вместо вывода соседней платы; короткий и толстый USB-кабель вместо тонкого метрового; конденсатор на 470 микрофарад прямо у выводов питания платы — он сглаживает как раз короткие всплески. И общий минус: если питание отдельное, минус источника и минус платы должны быть соединены, иначе не работает ничего.
Проверяем, что плата действительно в интернете
Подключиться к роутеру и выйти в интернет — разные вещи. Самая простая и честная проверка: попросить у интернета точное время. Часы по сети умеет само ядро платы, библиотека не нужна.
// Проверка «плата действительно в интернете»: она спрашивает точное
// время у сервера времени и печатает его. Библиотека не нужна - часы
// по сети умеет само ядро платы.
#if defined(ESP8266)
#include <ESP8266WiFi.h>
#else
#include <WiFi.h>
#endif
#include <time.h>
const char WIFI_SSID[] = "имя вашей сети";
const char WIFI_PASS[] = "пароль от сети";
const long TIMEZONE_SEC = 3 * 3600; // Москва: плюс три часа от UTC
void setup() {
Serial.begin(115200);
delay(200);
Serial.println();
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.print("Адрес платы: ");
Serial.println(WiFi.localIP());
// Два сервера на случай, если первый не ответит.
configTime(TIMEZONE_SEC, 0, "ru.pool.ntp.org", "pool.ntp.org");
Serial.print("Жду время");
time_t now = time(nullptr);
while (now < 100000) { // пока часы не заведены, время близко к нулю
delay(300);
Serial.print(".");
now = time(nullptr);
}
Serial.println();
}
void loop() {
time_t now = time(nullptr);
struct tm* t = localtime(&now);
char line[32];
snprintf(line, sizeof(line), "%02d:%02d:%02d %02d.%02d.%04d",
t->tm_hour, t->tm_min, t->tm_sec,
t->tm_mday, t->tm_mon + 1, t->tm_year + 1900);
Serial.println(line);
delay(1000);
}
Если время пришло — сеть настоящая, наружу плата ходит. Заодно вы получили часы, которые не нужно заводить и которые не убегают: это тот самый случай, когда модуль часов реального времени можно не покупать вовсе, если у поделки всегда есть сеть.
Кто кому звонит: три роли платы
Дальше начинается самое интересное — и здесь новички чаще всего заходят в тупик, потому что не различают три совершенно разные схемы работы. Разница между ними не в коде, а в том, кто начинает разговор.
Первая роль — плата звонит сама. Раз в минуту открывает соединение, отдаёт показания и кладёт трубку. Так работают погодные станции и счётчики. Управлять такой платой нельзя: она выходит на связь по своему расписанию.
Вторая роль — звонят плате. На ней живёт маленький сайт, вы набираете её адрес в браузере и щёлкаете кнопки. Это самый наглядный способ управления, и работает он без интернета вообще — достаточно домашней сети. Но и только внутри неё: из интернета домашняя плата не видна, роутер её прячет.
Третья роль — оба звонят посреднику. И плата, и телефон соединяются с общим сервером, и он передаёт сообщения в обе стороны. Это единственный по-настоящему рабочий способ управлять поделкой из другого города, и при этом не открывать дырок в домашнем роутере.
Каждой роли посвящена отдельная статья — они продолжают эту:
- Веб-сервер на плате — страница с кнопками, которая открывается в браузере телефона.
- MQTT и умный дом — посредник, через которого поделка достаётся из любой точки мира.
- Прошивка по воздуху — как обновлять программу, не доставая плату из корпуса.
Если менять плату нельзя: модуль ESP-01 к Arduino Uno
Бывает, что основную плату трогать нельзя: проект собран, отлажен, залит в корпус. В этом случае к Uno добавляют модуль ESP-01. Путь рабочий, но трудный, и честно перечислить трудности лучше заранее.
Модуль общается с платой по последовательному порту текстовыми командами — они начинаются с букв AT. Чтобы отправить одно число на сервер, Uno должна составить и передать несколько таких команд, а потом разобрать ответы. Каждая команда — это строка в памяти, а оперативной памяти у Uno всего два килобайта. На практике половина её уходит на обслуживание модуля.
Плюс к этому три обязательных условия:
- Питание 3,3 вольта и не меньше 500 миллиампер. Не от вывода 3V3 платы Uno — там потолок 50 миллиампер, этого не хватит.
- Делитель на линию приёма модуля. Выводы модуля рассчитаны на 3,3 вольта, а Uno выдаёт 5. Два резистора решают вопрос — точно так же, как для Bluetooth-модуля.
- Скорость. Заводская скорость AT-прошивки обычно 115 200, а программный порт Uno на такой скорости уже не тянет: в мониторе будет каша. Скорость модуля меняют один раз командой
AT+UART_DEF=9600,8,1,0,0через USB-переходник, и дальше живут на 9600.
Первое, что стоит сделать с новым модулем, — просто поговорить с ним руками. Этот скетч превращает Uno в мост: что вы пишете в мониторе порта, уходит в модуль, что отвечает модуль — появляется на экране. Наберите AT и нажмите ввод: живой модуль ответит OK.
// Мост между монитором порта и модулем ESP-01: всё, что вы напишете
// в мониторе, уходит в модуль, всё, что ответит модуль, - на экран.
// Так модулю диктуют AT-команды руками, чтобы понять, живой ли он.
//
// ВАЖНО ПРО ПИТАНИЕ. Модуль питается 3,3 вольта и в момент передачи
// просит куда больше, чем даёт вывод 3V3 платы Uno (у него потолок
// 50 мА). Нужен отдельный источник 3,3 В на 500 мА и общий минус.
// Линия RX модуля тоже рассчитана на 3,3 В - к выводу 3 идёт делитель
// из двух резисторов, как и для Bluetooth-модуля.
#include <SoftwareSerial.h>
// 2 - принимаем от модуля (его TX), 3 - передаём модулю (его RX).
SoftwareSerial esp(2, 3);
// Заводская скорость AT-прошивки обычно 115200, но программный порт
// на такой скорости уже не тянет: в мониторе будет каша. Скорость
// модуля меняют один раз командой AT+UART_DEF=9600,8,1,0,0 через
// USB-переходник, а дальше работают на 9600.
const long ESP_BAUD = 9600;
void setup() {
Serial.begin(9600);
esp.begin(ESP_BAUD);
Serial.println("Мост открыт. Наберите AT и нажмите ввод.");
Serial.println("В мониторе выберите окончание строки «NL и CR».");
}
void loop() {
while (esp.available()) {
Serial.write(esp.read());
}
while (Serial.available()) {
esp.write(Serial.read());
}
}
В мониторе порта обязательно выберите окончание строки «NL и CR» — без него модуль не поймёт, что команда закончилась, и будет молчать. Это тот же порядок, что и при настройке Bluetooth-модуля.
Есть и промежуточный вариант — платы, у которых на одной плате стоят и ATmega, и ESP8266, а между ними переключатель. Про них написано на странице про ESP8266: там же разобрано, почему такие платы удобны в теории и капризны на практике.
Провод вместо радио: когда Ethernet лучше
Про этот путь почти не пишут, а он часто оказывается лучшим. Если поделка стоит на месте и рядом есть роутер, сетевой кабель даёт то, чего радио не даст никогда: отсутствие пароля, отсутствие помех, отсутствие переподключений и заметно меньшую задержку.
Шилд W5500 садится на Arduino Uno сверху и занимает шину SPI и вывод 10. Модуль той же микросхемы подключается пятью проводами к любой плате. Работает это с обычной Arduino Uno — тот случай, когда менять плату не нужно.
// Сеть по проводу: тот же интернет, только без радио и без пароля.
// Шилд или модуль W5500 садится на шину SPI, выбор кристалла - вывод 10.
#include <SPI.h>
#include <Ethernet.h>
// Любой адрес, лишь бы в сети он был один такой.
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
void setup() {
Serial.begin(9600);
while (!Serial) {
;
}
Ethernet.init(10); // вывод выбора кристалла у шилда W5500
Serial.println("Спрашиваю адрес у роутера...");
if (Ethernet.begin(mac) == 0) {
Serial.println("Роутер адрес не выдал.");
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
Serial.println("Плата не видит сам модуль: проверьте SPI и питание.");
} else if (Ethernet.linkStatus() == LinkOFF) {
Serial.println("Кабель не воткнут или мёртв.");
}
return;
}
Serial.print("Готово. Адрес платы: ");
Serial.println(Ethernet.localIP());
}
void loop() {
// Раз в несколько минут аренда адреса продлевается сама.
Ethernet.maintain();
delay(1000);
}
Дальше код почти не отличается от Wi-Fi: те же соединения, те же запросы, только вместо WiFiClient используется EthernetClient. Минус ровно один — провод. Если поделка должна ездить или висеть на стене без розетки рядом, Ethernet отпадает.
Что делать, если не работает
Таблица собрана по вопросам, которые приходят к нам чаще всего. Ищите строку по симптому, а не по догадке о причине.
| Что видно | Что на самом деле | Что сделать |
|---|---|---|
| Плата бесконечно перезагружается, как только доходит до подключения | Источнику не хватает тока на всплеск передачи | Отдельное питание не меньше 500 мА, короткий и толстый USB-кабель, конденсатор 470 мкФ по питанию |
| В мониторе порта каша из непонятных знаков, потом нормальный текст | Это не ошибка: загрузчик ESP8266 всегда говорит на скорости 74 880, а ваш скетч — на своей | Ничего не делайте. Если каша идёт всё время — поставьте в мониторе ту же скорость, что в Serial.begin() |
| Сканер не показывает мою домашнюю сеть | Сеть на 5 ГГц, имя скрыто или роутер далеко | Включите на роутере сеть 2,4 ГГц с отдельным именем и подойдите ближе |
| Состояние 6 на плате ESP8266 | Неверный пароль — на этом чипе для него есть отдельный код | Скопируйте пароль из настроек роутера, а не по памяти: путают ноль и букву O, дефис и тире |
| Состояние 1: сеть не найдена, хотя телефон её видит | Имя написано не буква в букву или сеть в другом диапазоне | Сверьте имя со списком из сканера, а не с экрана телефона |
| Плата подключилась, адрес есть, но с телефона не открывается | Плата и телефон в разных сетях или в гостевой сети включена изоляция | Одна и та же сеть для обоих, изоляцию клиентов выключить |
| Адрес платы 0.0.0.0 | Роутер не выдал адрес: закончился запас адресов или включён фильтр по MAC | Перезагрузите роутер, проверьте фильтр, при необходимости задайте плате постоянный адрес |
| Имя вида «плата.local» не открывается на телефоне | Такие имена понимает не всякий телефон: Android научился этому только с двенадцатой версии, и роутер может резать групповую рассылку | Откройте по числовому адресу и закрепите его за платой в настройках роутера |
| После перезагрузки роутера плата не вернулась в сеть | В скетче нет переподключения: связь установили один раз в setup() | Возьмите скетч со сторожем связи из раздела «Связь рвётся» |
| У стола работает, в дальней комнате отваливается | Слабый сигнал: у платы антенна на самой плате и она хуже телефонной | Печатайте WiFi.RSSI(): дальше −75 dBm начинаются потери. Разверните плату, уберите металл рядом, поставьте ближе к роутеру |
| «Sketch too big» на плате, у которой 4 МБ памяти | Память поделена: скетчу отведена не вся флеш-память, а её часть — вторая половина зарезервирована под обновление по воздуху | Разбор целиком — в статье про прошивку по воздуху |
| Работает, но раз в сутки зависает | Длинные delay() и блокирующие циклы: пока программа стоит, радио не обслуживается | Уберите delay() из loop(), считайте время по millis(), в тяжёлых циклах вызывайте delay(0) или yield() |
Честно про безопасность
Поделка на ESP в домашней сети — это устройство без пароля. Любой, кто уже подключён к вашему Wi-Fi, может открыть её страницу и нажать все кнопки. Для настольной лампы это не беда, для замка на двери — беда.
Второе: пароль от сети лежит в скетче открытым текстом и вместе с прошивкой попадает во флеш-память платы. Тот, у кого плата окажется в руках, прочитает его за минуту. Не заливайте в поделки, которые уезжают из дома, пароль от основной сети — заведите для них отдельную.
Третье, и самое важное: не открывайте на роутере «проброс порта» к плате, чтобы дотянуться до неё из интернета. Так вы выставляете наружу устройство без единой проверки прав, и находят такие устройства за часы, а не за годы. Правильный способ достать поделку издалека — посредник, про которого написано в отдельной статье.
Что купить
Всё проверено 24 августа 2026 года: каждая карточка открыта отдельно, цена и артикул взяты с самой страницы товара. Того, чего нет в наличии, в подборке нет.
WeMos D1 mini на ESP8266
Самый короткий путь к Wi-Fi: плата размером с половину спичечного коробка, разъём micro-USB на борту, радио внутри. Дешевле, чем отдельный модуль с питанием к нему. С неё имеет смысл начинать, если проект небольшой и выводов нужно немного.
Piranha ESP32 v2
Шаг вперёд от D1 mini: два ядра, гораздо больше памяти, встроенный Bluetooth и запас на защищённые соединения. Именно её стоит брать, если поделка будет ходить в интернет, а не только по домашней сети.
WeMos ESP32 D1/R32 — ESP32 в корпусе Uno
Тот самый случай «проект собран на шилдах, менять механику не хочется»: размер, отверстия и гребёнка как у Arduino Uno, а внутри ESP32 с Wi-Fi. Помните про вольты: выводы у неё трёхвольтовые, шилды с выходом 5 вольт нужно проверять по схеме.
Источник питания 5 В, 2 А
То самое «нормальное питание», без которого половина проектов с Wi-Fi живёт в вечной перезагрузке. Два ампера — запас вчетверо больше требуемого: хватит и плате, и датчикам, и подсветке.
Понижающий преобразователь LM2596
Если питание уже есть, но на 9 или 12 вольт, этот модуль сделает из него ровные 5 вольт с хорошим запасом по току. Дешевле отдельного блока питания и удобнее для поделки внутри корпуса.
Ethernet Shield W5500
Сеть по проводу для Arduino Uno и Mega: садится сверху, занимает шину SPI и вывод 10. Ни пароля, ни помех, ни переподключений — для стационарной поделки это часто удобнее радио.
Сетевой модуль W5500
Та же микросхема, но не шилдом, а отдельной платой на пять проводов. Подойдёт любой плате, а не только той, что в корпусе Uno, и стоит вдвое дешевле шилда.
Патч-корд RJ45, 30 см
Короткий сетевой кабель до роутера. Мелочь, о которой вспоминают, когда шилд уже приехал, а воткнуть его нечем.
Провода «папа-мама», 40 штук
Ими соединяют плату с датчиками и модулем сети: с одной стороны штырёк, с другой гнездо. Длина 20 см, десять цветов.
Дальше по теме
- Веб-сервер на Arduino — страница с кнопками прямо на плате.
- MQTT и умный дом — как достать поделку из интернета и не открыть дырку в роутере.
- Прошивка по воздуху — обновление программы без кабеля.
- ESP8266, NodeMCU и Wemos D1 mini — установка ядра, распиновка и память самой популярной платы с Wi-Fi.
- Плата ESP32 — что у неё внутри и какие выводы можно занимать.
- Bluetooth и модуль HC-05 — вторая беспроводная дорога, у которой интернета нет.
Частые вопросы
Можно ли подключить Wi-Fi к Arduino Uno?
Можно, но почти всегда не нужно. К Uno добавляют модуль ESP-01, и тогда Uno командует им текстовыми AT-командами: на каждую отправку данных уходит несколько строк, а оперативной памяти у Uno всего два килобайта — половина её тратится на обслуживание модуля. Плюс модулю нужно отдельное питание 3,3 вольта минимум на 500 миллиампер (вывод 3V3 у Uno отдаёт максимум 50 миллиампер) и делитель на линию приёма. Отдельная плата, у которой радио уже внутри, стоит дешевле такого набора, программируется в той же среде и делает всё сама. Uno имеет смысл оставлять только тогда, когда проект уже собран и менять его нельзя.
Почему плата не видит мою сеть Wi-Fi, хотя телефон её видит?
Чаще всего сеть работает на 5 гигагерцах. Радио у ESP8266 и ESP32 умеет только диапазон 2,4 гигагерца — это свойство самих чипов, настройками оно не меняется. Вторая по частоте причина: обе сети роутера названы одинаково, и плата видит только двухгигагерцевую половину — тогда она подключается через раз. Третья: имя сети скрыто, и в списке сканера её нет вовсе. Реже встречаются WPA3 (его понимает ESP32, но не ESP8266), русские буквы в имени сети и фильтр по MAC-адресам. Запустите сканер сетей: если вашей сети нет в его списке, дело не в пароле.
Какую плату с Wi-Fi взять новичку?
Для первого проекта — D1 mini на чипе ESP8266: размером с половину спичечного коробка, разъём USB на борту, стоит меньше трёхсот рублей. Если поделка будет ходить в интернет, а не только по домашней сети, лучше сразу брать ESP32: у неё два ядра и заметно больше памяти, а значит, ей по силам защищённые соединения, без которых современные сайты и мессенджеры не работают. Если проект уже собран на шилдах в корпусе Arduino Uno, есть плата на ESP32 ровно того же размера и с той же гребёнкой — только помните, что выводы у неё трёхвольтовые.
Нужна ли библиотека, чтобы плата вышла в Wi-Fi?
Нет. Работа с сетью входит в поддержку самой платы: для ESP8266 это ESP8266WiFi.h, для ESP32 — WiFi.h, и обе приезжают вместе с пакетом платы. Ничего скачивать и класть в папку библиотек не нужно. Более того, один и тот же скетч можно написать сразу для обеих плат: строчка #if defined(ESP8266) подставит нужный заголовок. Библиотеки понадобятся позже и по делу — например, для работы с MQTT.
Почему плата перезагружается, когда подключается к сети?
Это почти всегда питание, а не программа. Wi-Fi потребляет ток рывками: в покое около 80 миллиампер, а в момент передачи короткими всплесками в несколько раз больше. Изготовитель чипа прямо требует источник не меньше 500 миллиампер. Когда источник слабый, во время всплеска напряжение проседает, чип считает это сбоем и перезапускается — получается бесконечный круг «старт, подключение, перезагрузка». Лечится отдельным источником питания вместо вывода соседней платы, коротким толстым USB-кабелем и конденсатором на 470 микрофарад у выводов питания.
Можно ли управлять платой через интернет, а не только из дома?
Можно, но не тем способом, который приходит в голову первым. Веб-страница, которую плата отдаёт браузеру, работает только внутри домашней сети: из интернета плата не видна, её прячет роутер. Пробрасывать к ней порт на роутере не стоит — так наружу выставляется устройство, у которого нет ни пароля, ни проверки прав, и находят такие устройства за часы. Правильный путь — посредник: и плата, и телефон соединяются с одним сервером, и он передаёт сообщения в обе стороны. Именно так устроены MQTT и боты в мессенджерах.
Wi-Fi или Bluetooth — что выбрать для управления с телефона?
Если телефон и плата рядом, а интернет не нужен — Bluetooth проще: не нужны ни роутер, ни пароль, ни адреса, и модуль работает как удлинитель провода. Если нужно управлять из другой комнаты, показывать данные на обычной веб-странице, писать в умный дом или выходить наружу — только Wi-Fi. Ещё одно отличие важно владельцам iPhone: популярный Bluetooth-модуль HC-05 с айфоном не работает вовсе, а Wi-Fi одинаково доступен с любого телефона, потому что страница открывается в обычном браузере.
Что для этого нужно в среде
Все скетчи с этой страницы собираются в Trema IDE без единой скачанной библиотеки: работа с сетью входит в поддержку самих плат. Поддержку ESP8266 и ESP32 среда берёт с нашего собственного зеркала, поэтому установка не упирается в закрытые сайты и не требует ручной правки ссылок.
Что почитать рядом: как поставить поддержку платы — ESP8266 и ESP32. Что делать, если скетч не заливается — Ошибка загрузки. Куда подключать остальные модули — Модули для Arduino. Идеи для проектов — Проекты на Arduino.
