Компоненты · 11 мин чтения

ESP-01 с Arduino: AT-команды, программирование и реле

Подключение ESP-01 (ESP8266) к Arduino: 8 пинов, питание 3,3 V, Wi-Fi через AT-команды, программирование с GPIO0 на GND, релейный модуль ESP-01S и частые ошибки.

ESP-01 — крошечный (24,8 × 14,3 мм) и очень дешёвый модуль на Wi-Fi-чипе ESP8266. Если подключить ESP-01 к Arduino, плата без беспроводной связи, например Uno или Nano, получает Wi-Fi всего с помощью нескольких проводов. С завода на модуле стоит AT-прошивка: Arduino отправляет по последовательной линии короткие текстовые команды вроде «AT+CWJAP», а ESP-01 подключается к сети, отправляет и принимает данные. При желании ESP-01 можно программировать и как самостоятельный микроконтроллер, вообще без Arduino: его процессор гораздо быстрее, чем у Uno.

В этом руководстве разберём 8 пинов ESP-01, почему ему обязательно нужно мощное питание 3,3 V, как работать с AT-командами на Arduino Uno, как сделать веб-страницу, которая включает светодиод с телефона, как программировать модуль напрямую через USB-TTL-преобразователь (способ «GPIO0 на GND»), как управлять лампой через релейный модуль ESP-01S и как использовать модуль с Raspberry Pi Pico. В конце — решения самых частых ошибок и подсказка, когда лучше выбрать NodeMCU или ESP32.

Wi-Fi-модуль ESP-01 на ESP8266
Wi-Fi-модуль ESP-01: чип ESP8266EX, флеш-память, печатная антенна и 8 пинов в гребёнке 2×4 на одной маленькой плате.

Что такое ESP-01 и как он работает?

ESP-01 — первый и самый маленький модуль, который компания Ai-Thinker разработала на чипе ESP8266EX. На плате есть чип, кварцевый резонатор на 26 MHz, флеш-память для программы и настроек и печатная антенна-змейка; USB-порта, стабилизатора напряжения и кнопок нет. Поэтому ESP-01 нельзя просто воткнуть в компьютер: питание и последовательное соединение нужно организовать отдельно. Модуль можно использовать двумя способами: как Wi-Fi-модем (стоит AT-прошивка, Arduino отправляет команды) или как самостоятельный микроконтроллер (в него загружается собственная программа из Arduino IDE, а AT-прошивка стирается). Большинство модулей, которые продаются сегодня, — это чёрная версия ESP-01S.

ПараметрЗначение
ЧипESP8266EX (Tensilica L106, 32-битный)
Тактовая частота80 MHz (можно поднять до 160 MHz)
Флеш-памятьESP-01: 512 КБ, ESP-01S: 1 МБ
ОЗУ (RAM)Около 80 КБ ОЗУ для данных; при подключённом Wi-Fi программе остаётся ~50 КБ
Wi-Fi802.11 b/g/n, только 2,4 GHz, печатная антенна
Рабочее напряжение3,0–3,6 V (рекомендуется 3,3 V)
ТокВ среднем 70–80 mA при подключении, ~170 mA при передаче, пики выше 300 mA
Ток в глубоком снеОколо 20 µA (чип)
Доступные GPIO4 шт.: GPIO0, GPIO2, GPIO1 (TX), GPIO3 (RX)
Аналоговый входНет (пин АЦП не выведен)
Размер24,8 × 14,3 мм
Заводская прошивкаAT-прошивка (обычно 115200 бод)

ESP-01 и ESP-01S: в чём разница

ПараметрESP-01ESP-01S
Цвет платыОбычно синийЧёрный
Флеш-память512 КБ (в поздних чёрных версиях 1 МБ)1 МБ
Светодиод питанияКрасный, горит постоянноНет
Синий светодиодНа линии TX (GPIO1), мигает при передаче данныхНа GPIO2, горит, когда на пине LOW
Распиновка8 пиновТе же 8 пинов, полная совместимость
ПотреблениеНа несколько mA больше из-за светодиода питанияНиже, лучше подходит для проектов на батарейках

Распиновка ESP-01: что делают 8 пинов

У ESP-01 8 пинов в гребёнке 2×4, и только четыре из них можно использовать как входы и выходы. Названия пинов напечатаны не на каждой плате, поэтому перед подключением сверь модуль с распиновкой от продавца: если перепутать VCC и GND, модуль сгорит за считаные секунды. Вот что делает каждый пин и как он подключается в обычном режиме:

ПинНазначениеПодключение в обычном режиме
VCCВход питания 3,3 VМощный источник 3,3 V (не меньше 300 mA)
GNDЗемляОбщая GND с Arduino и источником питания
TX (GPIO1)Выход последовательных данныхК линии RX Arduino
RX (GPIO3)Вход последовательных данныхК линии TX Arduino (на 5-вольтовых платах через делитель напряжения)
EN (CH_PD)Включает чипНа 3,3 V (напрямую или через 10 kΩ)
RSTПерезапускает чип при LOWСвободен или подтянут к 3,3 V через 10 kΩ
GPIO0Выбирает режим загрузки, затем обычный ввод-выводПри старте HIGH (свободен); при программировании на GND
GPIO2Обычный ввод-вывод (синий светодиод на ESP-01S)При старте должен оставаться HIGH
ESP-01 работает только от 3,3 V; верхний предел рабочего напряжения чипа — 3,6 V. Если подать 5 V от Arduino на пин VCC, модуль может выйти из строя навсегда. Пин TX у Arduino Uno тоже выдаёт сигнал 5 V, поэтому не подключай его к пину RX ESP-01 напрямую: используй делитель напряжения или преобразователь логических уровней.

Потребление тока: почему пина 3,3 V на Arduino не хватает

Большинство проблем, из-за которых ESP-01 сгорает или постоянно перезагружается, связаны с питанием. При подключении к Wi-Fi модуль потребляет в среднем 70–80 mA, а при передаче около 170 mA; короткие пики при старте и в момент подключения к сети могут превышать 300 mA. А пин 3,3 V на Arduino Uno официально рассчитан всего на 50 mA. ESP-01, запитанный от этого пина, часто отвечает на команду «AT», но как только пытается подключиться к сети, напряжение проседает и модуль сбрасывается — со стороны это похоже на ошибку в программе. Решение — стабилизатор AMS1117-3.3 (1 A) с питанием от 5 V плюс электролитический конденсатор 100–470 µF между пинами VCC и GND модуля. Как работают стабилизаторы, рассказано в статье о стабилизаторе напряжения 7805.

Источник питанияПодходит?Примечание
Пин 3,3 V на Arduino UnoНетОфициально 50 mA; модуль сбрасывается при подключении к Wi-Fi
Пин 3,3 V на USB-TTL-преобразователеОбычно нетВстроенный стабилизатор чипа обычно выдаёт 50–100 mA
Стабилизатор AMS1117-3.3 (вход 5 V)ДаДо 1 A; 10 µF на выходе, 100–470 µF рядом с модулем
USB-адаптер для ESP-01ДаНа нём есть CH340 и AMS1117; модуль вставляется напрямую
2 батарейки AA (3 V)На граниПо мере разряда напряжение падает ниже 3 V, и модуль работает нестабильно
Одна ячейка Li-ion (3,7–4,2 V)Напрямую нетВыше предела 3,6 V; нужен LDO-стабилизатор на 3,3 V (с малым падением напряжения)

Подключение ESP-01 к Arduino Uno (для AT-команд)

Единственный аппаратный последовательный порт Arduino Uno (D0 и D1) используется совместно с USB-подключением. Поэтому удобнее всего подключить ESP-01 к пинам D2 и D3 через библиотеку SoftwareSerial: при загрузке кода в Uno не нужно отключать ESP-01, а монитор порта остаётся свободным для отладки. Raspberry Pi Pico и так работает от 3,3 V, поэтому делитель ей не нужен:

Пин ESP-01Arduino UnoRaspberry Pi PicoПримечание
VCCВыход AMS1117-3.3AMS1117-3.3 или 3V3(OUT)Пина 3,3 V на Uno не хватает; для выхода 3V3 на Pico рекомендуемый предел — 300 mA
GNDGNDGNDСтабилизатор, плата и модуль на общей GND
TXD2GP1 (UART0 RX)Подключается напрямую
RXD3 (через делитель 1 kΩ / 2 kΩ)GP0 (UART0 TX)На Pico делитель не нужен
EN (CH_PD)3,3 V3,3 VНапрямую или через 10 kΩ
RSTНе подключёнНе подключёнПри желании подтяни к 3,3 V через 10 kΩ
GPIO0Не подключёнНе подключёнВ обычном режиме не подключай к GND
GPIO2Не подключёнНе подключёнПри старте должен оставаться HIGH

Чтобы понизить сигнал 5 V с пина D3 на Uno, поставь резистор 1 kΩ от D3 к RX ESP-01 и резистор 2 kΩ от RX ESP-01 к GND. На выходе получится 5 × 2 / (1 + 2) = 3,33 V; если вместо 2 kΩ взять 2,2 kΩ, выйдет 3,44 V, и оба варианта безопасны. Другие номиналы резисторов можно подобрать в утилите делителя напряжения. В обратную сторону делитель не нужен: 3,3 V с пина TX ESP-01 выше порога 3 V, который Uno считает за HIGH. Основы последовательной связи подробно разобраны в статье о последовательной связи UART.

Первый тест: отправляем AT-команды из монитора порта

  1. Загрузи в Uno скетч-мост ниже; для первой попытки поставь ESP_BAUD равным 115200, потому что большинство модулей приходят с этой скоростью (у старых может быть 9600).
  2. Открой монитор порта на скорости 115200 бод и выбери конец строки Both NL & CR («NL и CR»); без этого модуль не понимает, что команда закончилась.
  3. Набери AT и отправь — в ответ должно прийти OK. Если приходят мусорные символы, скорости не совпадают.
  4. SoftwareSerial не может надёжно читать на 115200, поэтому навсегда понизь скорость модуля до 9600 командой AT+UART_DEF=9600,8,1,0,0. Даже если ответ выглядит искажённым, команда обычно доходит.
  5. Поменяй ESP_BAUD в скетче на 9600, загрузи его снова и повтори команду AT; теперь ответ OK должен выглядеть чисто.
  6. Проверь, что модуль работает исправно: прочитай версию прошивки командой AT+GMR и выведи список ближайших Wi-Fi-сетей командой AT+CWLAP.
C++ (Arduino IDE)
1#include <SoftwareSerial.h>
2
3SoftwareSerial esp(2, 3);          // D2 = RX, D3 = TX (bölücüyle ESP RX'e) / D3 to ESP RX via divider
4
5const long ESP_BAUD = 9600;        // ilk denemede 115200 yap / use 115200 on the first try
6
7void setup() {
8  Serial.begin(115200);            // Seri Monitör hızı / Serial Monitor speed
9  esp.begin(ESP_BAUD);
10  Serial.println("AT komutu yaz / type an AT command");
11}
12
13void loop() {
14  if (esp.available()) {           // ESP-01'den geleni ekrana yaz / ESP-01 -> screen
15    Serial.write(esp.read());
16  }
17  if (Serial.available()) {        // klavyeden yazılanı ESP-01'e gönder / keyboard -> ESP-01
18    esp.write(Serial.read());
19  }
20}

Самые полезные AT-команды ESP-01

КомандаЧто делаетПример ответа
ATПроверяет связьOK
AT+RSTПерезапускает модульOK ... ready (модуль готов)
AT+GMRПоказывает версию прошивкиAT version:... SDK version:... OK (версии AT и SDK)
AT+UART_DEF=9600,8,1,0,0Навсегда меняет скорость в бодахOK
AT+CWMODE=1Режим станции; 2 = точка доступа, 3 = оба режимаOK
AT+CWLAPВыводит список ближайших Wi-Fi-сетей+CWLAP:(3,"MyWiFi",-58,...) (тип защиты, имя, уровень сигнала)
AT+CWJAP="MyWiFi","Password123" (имя сети, пароль)Подключается к Wi-Fi-сетиWIFI CONNECTED, WIFI GOT IP, OK
AT+CIFSRПоказывает полученный IP-адрес+CIFSR:STAIP,"192.168.1.45" (IP-адрес станции)
AT+CIPMUX=1Включает несколько соединений (обязательно для сервера)OK
AT+CIPSERVER=1,80Запускает TCP-сервер на порту 80OK
AT+CIPSTART=0,"TCP","192.168.1.10",80 (соединение 0, адрес, порт)Подключается к серверу по соединению 00,CONNECT и OK
AT+CIPSEND=0,20Отправляет 20 байт по соединению 0> ... SEND OK (отправлено)
AT+CIPCLOSE=0Закрывает соединение 00,CLOSED и OK
Если AT+CWJAP не срабатывает, модуль выводит +CWJAP:1 (таймаут), +CWJAP:2 (неверный пароль), +CWJAP:3 (сеть не найдена) или +CWJAP:4 (не удалось подключиться), а за ним FAIL. ESP8266 видит только сети 2,4 GHz, поэтому если сеть не находится, проверь, что на роутере включён диапазон 2,4 GHz. Команды пиши заглавными буквами, а имя сети и пароль — в двойных кавычках.

Управление светодиодом с телефона на Arduino Uno и ESP-01

Теперь превратим AT-команды в программу. Скетч ниже подключает ESP-01 к твоей сети, открывает небольшой веб-сервер на порту 80 и выводит IP-адрес в монитор порта. Если ввести этот адрес в браузере телефона, подключённого к той же Wi-Fi-сети, откроется страница с двумя кнопками; они включают и выключают встроенный светодиод на пине 13 Uno. Подключи вместо светодиода релейный модуль — и тем же способом можно управлять лампой. Перед загрузкой скорость модуля должна быть уже переключена на 9600 на предыдущем шаге.

C++ (Arduino IDE)
1#include <SoftwareSerial.h>
2
3SoftwareSerial esp(2, 3);              // D2 = RX, D3 = TX (bölücüyle) / D3 via divider
4const int LED_PIN = 13;                // Uno'nun dahili LED'i / Uno onboard LED
5
6const char* WIFI_SSID = "AgAdi";       // Wi-Fi adın / your Wi-Fi name
7const char* WIFI_PASS = "Sifre123";    // Wi-Fi şifren / your Wi-Fi password
8
9bool ledOn = false;
10bool pending = false;                  // cevap bekleyen istek var mı / request waiting for a reply
11int linkId = 0;                        // ESP-01'in bağlantı numarası (0-4) / connection id (0-4)
12char line[64];
13byte lineLen = 0;
14
15// Beklenen yazıyı süre dolana kadar ara / wait until the expected text arrives or time runs out
16bool waitFor(const char* expect, unsigned long timeout) {
17  unsigned long start = millis();
18  size_t idx = 0;
19  size_t len = strlen(expect);
20  while (millis() - start < timeout) {
21    if (esp.available()) {
22      char c = esp.read();
23      Serial.write(c);                 // gelen her şeyi göster / echo everything
24      if (c == expect[idx]) {
25        idx++;
26        if (idx == len) return true;
27      } else {
28        idx = (c == expect[0]) ? 1 : 0;
29      }
30    }
31  }
32  return false;
33}
34
35bool sendAT(const char* cmd, const char* expect, unsigned long timeout) {
36  esp.println(cmd);                    // println sonuna \r\n ekler / println adds \r\n
37  return waitFor(expect, timeout);
38}
39
40void sendPage(int id) {
41  char body[220];
42  snprintf(body, sizeof(body),
43           "<meta name='viewport' content='width=device-width'>"
44           "<h2>LED: %s</h2>"
45           "<a href='/on'><button>AC / ON</button></a> "
46           "<a href='/off'><button>KAPAT / OFF</button></a>",
47           ledOn ? "ACIK / ON" : "KAPALI / OFF");
48  char head[110];
49  snprintf(head, sizeof(head),
50           "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n"
51           "Content-Length: %d\r\nConnection: close\r\n\r\n",
52           (int)strlen(body));
53
54  esp.print("AT+CIPSEND=");            // önce kaç bayt gideceğini söyle / announce the length first
55  esp.print(id);
56  esp.print(',');
57  esp.println(strlen(head) + strlen(body));
58  if (waitFor(">", 2000)) {            // ">" gelince veriyi yolla / send data after ">"
59    esp.print(head);
60    esp.print(body);
61    waitFor("SEND OK", 5000);
62  }
63  esp.print("AT+CIPCLOSE=");           // bağlantıyı kapat / close the connection
64  esp.println(id);
65  waitFor("OK", 2000);
66}
67
68void handleLine() {
69  if (strncmp(line, "+IPD,", 5) == 0) {          // yeni istek / new request: +IPD,0,384:GET /on ...
70    linkId = line[5] - '0';
71    if (strstr(line, "GET /on ")) ledOn = true;
72    else if (strstr(line, "GET /off ")) ledOn = false;
73    digitalWrite(LED_PIN, ledOn ? HIGH : LOW);
74    pending = true;
75  } else if (pending && lineLen == 0) {           // boş satır = isteğin sonu / empty line = end of request
76    pending = false;
77    sendPage(linkId);
78  }
79}
80
81void setup() {
82  pinMode(LED_PIN, OUTPUT);
83  Serial.begin(115200);
84  esp.begin(9600);                     // AT+UART_DEF=9600,8,1,0,0 ile ayarlanmış olmalı / set with AT+UART_DEF
85
86  sendAT("AT+RST", "ready", 5000);     // temiz başlangıç / clean restart
87  sendAT("AT+CWMODE=1", "OK", 2000);   // istemci modu / station mode
88
89  esp.print("AT+CWJAP=\"");            // AT+CWJAP="ad","şifre" / AT+CWJAP="ssid","password"
90  esp.print(WIFI_SSID);
91  esp.print("\",\"");
92  esp.print(WIFI_PASS);
93  esp.println("\"");
94  if (!waitFor("OK", 20000)) {
95    Serial.println(F("\nWi-Fi baglanamadi / Wi-Fi failed"));
96  }
97
98  sendAT("AT+CIPMUX=1", "OK", 2000);         // sunucu için çoklu bağlantı / multiple connections
99  sendAT("AT+CIPSERVER=1,80", "OK", 2000);   // 80 portunda sunucu / server on port 80
100  sendAT("AT+CIFSR", "OK", 2000);            // IP adresini yaz / print the IP address
101}
102
103void loop() {
104  while (esp.available()) {            // ESP-01'den gelenleri satır satır oku / read line by line
105    char c = esp.read();
106    if (c == '\n') {
107      line[lineLen] = '\0';
108      handleLine();
109      lineLen = 0;
110    } else if (c != '\r' && lineLen < sizeof(line) - 1) {
111      line[lineLen++] = c;
112    }
113  }
114}

Как работает код: когда подключается браузер, ESP-01 передаёт запрос в Arduino в виде +IPD,0,384:GET /on HTTP/1.1, где 0 — номер соединения, а 384 — число принятых байт. Arduino ищет в этой строке «GET /on» или «GET /off» и переключает светодиод. Когда приходит пустая строка, обозначающая конец запроса, скетч командой AT+CIPSEND=0,длина сообщает, сколько байт отправит, после приглашения «>» от модуля отправляет страницу и после ответа «SEND OK» закрывает соединение командой AT+CIPCLOSE. Страница специально короткая: 2 КБ ОЗУ у Uno не хватает на длинный HTML, а одна команда CIPSEND отправляет не больше 2048 байт. В более сложных проектах библиотека вроде WiFiEspAT избавляет от ручного управления AT-командами.

Программирование ESP-01 напрямую: способ «GPIO0 на GND»

ESP8266 внутри ESP-01 с 32-битным процессором на 80 MHz гораздо мощнее, чем Arduino Uno. Если в проекте только реле, датчик или светодиод, Arduino вообще не нужна: программа загружается прямо в ESP-01. При старте ESP8266 проверяет уровни на GPIO0, GPIO2 и GPIO15 и по ним решает, что делать. На плате ESP-01 GPIO15 уже соединён с GND, а GPIO2 должен оставаться HIGH, поэтому режим загрузки выбирает только GPIO0:

GPIO0GPIO2GPIO15Режим загрузкиСообщение при старте на 74880 бод
HIGH (свободен)HIGHLOWОбычная работа: запускается программа из флеш-памятиboot mode:(3,x) (обычный режим)
LOW (GND)HIGHLOWРежим программирования (загрузка по UART)boot mode:(1,x) и waiting for host (ожидание компьютера)
Пин ESP-01ПодключениеПримечание
VCCВыход стабилизатора 3,3 VПина 3,3 V на USB-TTL-преобразователе обычно не хватает
GNDGND USB-TTL и GND стабилизатораВсё на общей земле
TXRXD USB-TTLПерекрёстное подключение
RXTXD USB-TTLПеремычка должна стоять на 3,3 V
EN (CH_PD)3,3 VНапрямую или через 10 kΩ
RSTНе подключён (для сброса ненадолго на GND)При желании подтяни к 3,3 V через 10 kΩ
GPIO0GNDТолько во время загрузки; потом отключи
GPIO2Не подключёнПри старте должен оставаться HIGH
  1. В Arduino IDE открой «Файл › Настройки» (File › Preferences) и добавь https://arduino.esp8266.com/stable/package_esp8266com_index.json в поле «Дополнительные ссылки для Менеджера плат» (Additional boards manager URLs).
  2. В «Менеджере плат» (Boards Manager) найди esp8266 и установи пакет ESP8266 Community.
  3. В меню «Инструменты › Плата» (Tools › Board) выбери Generic ESP8266 Module. В пункте Flash Size для ESP-01S поставь 1MB (FS:64KB OTA:~470KB), а для старого синего ESP-01 — один из вариантов на 512KB.
  4. Переставь перемычку на USB-TTL-преобразователе в положение 3,3 V, подключи модуль по таблице выше и оставь GPIO0 соединённым с GND.
  5. Отключи и снова подай питание на модуль или ненадолго замкни RST на GND; теперь модуль стартует в режиме программирования.
  6. Выбери порт USB-TTL-преобразователя в меню «Инструменты › Порт» и загрузи скетч. Для первого теста подойдёт «Файл › Примеры › ESP8266 › Blink»; на ESP-01S синий светодиод подключён к GPIO2.
  7. Когда появится «Hard resetting via RTS pin...» (сброс через пин RTS), отсоедини GPIO0 от GND и перезапусти модуль. Если GPIO0 останется на GND, программа не запустится, и модуль снова стартует в режиме программирования.
Чтобы программировать было проще, можно взять USB-адаптер для ESP-01 с CH340 и AMS1117 на борту — модуль вставляется в него напрямую. На некоторых таких адаптерах есть переключатель UART/PROG; на моделях без него придётся припаять кнопку или перемычку между GPIO0 и GND. Если USB-TTL-преобразователя нет, можно соединить пин RESET на Arduino Uno с GND и использовать USB-чип платы как мост; в этом случае TX подключается к TX, RX к RX, а уровень 5 V всё равно нужно понижать делителем. Подробности — в статье об USB-TTL-преобразователе.

Управление реле через GPIO0 и GPIO2: релейный модуль ESP-01S

Пины общего назначения у ESP-01 — это GPIO0 и GPIO2, но при старте оба должны быть в состоянии HIGH. Поэтому всё, что к ним подключено, не должно тянуть пин к LOW, пока плата запускается. Самое надёжное решение — подключение с активным LOW: при старте на пине HIGH, и реле остаётся выключенным, а когда программа переводит пин в LOW, реле включается. Готовый релейный модуль ESP-01S устроен именно так: он питается от 5 V, его стабилизатор выдаёт 3,3 V для ESP-01S, а GPIO0 через транзистор управляет реле с контактами 10 A 250 V AC. На платах версии v4.0 и новее реле включается, когда на GPIO0 LOW; старые платы v1.0 могут потребовать небольшой доработки для работы с ESP-01S, так что проверь версию своей платы.

Релейный модуль на 5 V
Реле позволяет слабым управляющим сигналом включать и выключать лампу на 230 V; на релейной плате ESP-01S такое же реле подключено к пину GPIO0 модуля ESP-01.
C++ (Arduino IDE)
1#include <ESP8266WiFi.h>
2#include <ESP8266WebServer.h>
3#include <ESP8266mDNS.h>
4
5const char* ssid = "AgAdi";            // Wi-Fi adın / your Wi-Fi name
6const char* password = "Sifre123";     // Wi-Fi şifren / your Wi-Fi password
7
8const int RELAY_PIN = 0;               // ESP-01S röle kartında GPIO0 / GPIO0 on the ESP-01S relay board
9const int RELAY_ON = LOW;              // çoğu kartta LOW = çeker; tersse değiştir / LOW = on, swap if yours is inverted
10const int RELAY_OFF = HIGH;
11
12ESP8266WebServer server(80);
13bool relayOn = false;
14
15void sendPage() {
16  String html = F("<!DOCTYPE html><html><head><meta charset='utf-8'>"
17                  "<meta name='viewport' content='width=device-width,initial-scale=1'>"
18                  "<title>ESP-01</title></head>"
19                  "<body style='font-family:sans-serif;text-align:center'>"
20                  "<h1>ESP-01 Röle / Relay</h1><p><b>");
21  html += relayOn ? "AÇIK / ON" : "KAPALI / OFF";
22  html += F("</b></p><p><a href='/on'><button>AÇ / ON</button></a> "
23            "<a href='/off'><button>KAPAT / OFF</button></a></p></body></html>");
24  server.send(200, "text/html", html);
25}
26
27void setRelay(bool on) {
28  relayOn = on;
29  digitalWrite(RELAY_PIN, on ? RELAY_ON : RELAY_OFF);
30  server.sendHeader("Location", "/");  // ana sayfaya dön / back to the main page
31  server.send(303, "text/plain", "");
32}
33
34void setup() {
35  digitalWrite(RELAY_PIN, RELAY_OFF);  // önce kapalı seviye / off level first
36  pinMode(RELAY_PIN, OUTPUT);
37  Serial.begin(115200);
38
39  WiFi.mode(WIFI_STA);
40  WiFi.begin(ssid, password);
41  while (WiFi.status() != WL_CONNECTED) {
42    delay(500);
43    Serial.print('.');
44  }
45  Serial.println();
46  Serial.println(WiFi.localIP());      // bu adresi tarayıcıda aç / open this address in a browser
47  MDNS.begin("esp01");                 // ya da http://esp01.local / or http://esp01.local
48
49  server.on("/", sendPage);
50  server.on("/on", []() { setRelay(true); });
51  server.on("/off", []() { setRelay(false); });
52  server.begin();
53}
54
55void loop() {
56  server.handleClient();
57  MDNS.update();
58}

Загрузив скетч в ESP-01S описанным выше способом, вставь модуль в релейную плату и подай на плату 5 V. IP-адрес можно прочитать в мониторе порта, пока подключён USB-TTL-преобразователь, или найти в списке подключённых устройств на роутере; с компьютера, который поддерживает mDNS, работает и адрес http://esp01.local. Если нужно добавить вход, например кнопку, лучший пин — GPIO3 (RX), потому что его уровень при старте не важен. В этом случае открой последовательный порт только на передачу с помощью Serial.begin(115200, SERIAL_8N1, SERIAL_TX_ONLY).

Если к контактам реле подключается сетевое напряжение, делай всю проводку при отключённом питании, не оставляй открытых контактов и помести схему в изолированный корпус. Даже если на реле написано 10 A, медные дорожки на маленьких платах могут не выдержать такой ток; не подключай к этому модулю нагрузку мощнее нескольких сотен ватт. Подробнее — в статье «Что такое релейный модуль?»

ESP-01 с Raspberry Pi Pico (MicroPython)

С помощью ESP-01 можно добавить беспроводную связь и к Raspberry Pi Pico без Wi-Fi. Pico работает от 3,3 V, поэтому делитель напряжения не нужен: RX модуля ESP-01 подключается к GP0 (UART0 TX), а TX — к GP1 (UART0 RX). Аппаратный UART у Pico спокойно читает 115200 бод, так что скорость модуля менять тоже не нужно; если она уже понижена до 9600 в разделе про Uno, поставь baudrate = 9600 и в коде. Запусти код MicroPython ниже в Thonny: модуль подключится к сети, выведет свой IP-адрес и будет каждые 30 секунд выводить список ближайших сетей. Если есть Pico W, проще пользоваться её встроенным Wi-Fi; об этом — статья «Веб-сервер на Pico W через Wi-Fi».

MicroPython
1from machine import UART, Pin
2import time
3
4# GP0 (TX) -> ESP-01 RX, GP1 (RX) <- ESP-01 TX
5uart = UART(0, baudrate=115200, tx=Pin(0), rx=Pin(1))
6
7def at(cmd, timeout=2000):
8    uart.write(cmd + "\r\n")                   # her komut \r\n ile biter / every command ends with \r\n
9    start = time.ticks_ms()
10    resp = b""
11    while time.ticks_diff(time.ticks_ms(), start) < timeout:
12        if uart.any():
13            resp += uart.read()
14            if b"OK" in resp or b"ERROR" in resp or b"FAIL" in resp:
15                break
16    print(cmd, "->", resp)                     # cevabı göster / show the reply
17    return resp
18
19at("ATE0")                                     # komut yankısını kapat / turn off echo
20at("AT")                                       # OK gelmeli / should answer OK
21at("AT+CWMODE=1")                              # istemci modu / station mode
22at('AT+CWJAP="AgAdi","Sifre123"', 20000)       # Wi-Fi'ye bağlan / join Wi-Fi
23at("AT+CIFSR")                                 # IP adresini sor / ask for the IP
24
25while True:
26    at("AT+CWLAP", 10000)                      # çevredeki ağları tara / scan nearby networks
27    time.sleep(30)

ESP-01, NodeMCU или ESP32?

ПараметрESP-01NodeMCU (ESP8266)ESP32 DevKit
ЧипESP8266ESP8266ESP32 (двухъядерный)
Доступные GPIO4 (два из них TX/RX)Около 11Около 25
Аналоговый входНет1 (A0)18 каналов, 12 бит
Программирование по USBНет, нужен USB-TTL-преобразовательДаДа
ПитаниеТолько 3,3 VUSB 5 V или VINUSB 5 V или VIN
BluetoothНетНетДа (Classic и BLE)
Размер24,8 × 14,3 ммПлата для макетной платыПлата для макетной платы
Лучше всего подходитДобавить Wi-Fi к Arduino, одно реле или датчикПервые шаги с Wi-Fi, несколько датчиковПроекты с большим числом пинов и Bluetooth

Главные плюсы ESP-01 — размер и цена; он идеален, чтобы добавить Wi-Fi к готовому проекту на Arduino или сделать беспроводным одно реле или один датчик. Но USB у него нет, поэтому перекидывать провода, ставить стабилизатор и замыкать GPIO0 на землю при каждой загрузке быстро надоедает. Аналогового входа нет, а поскольку GPIO16 не выведен, пробуждение из глубокого сна по таймеру не работает, пока не припаять тонкий проводок к ножке чипа. Если планируется проект на батарейках, введи средний ток в калькулятор времени работы от батареи и посмотри, на сколько дней её хватит. Для учёбы или если нужно больше трёх пинов, NodeMCU ESP8266 даёт тот же чип вместе с USB и стабилизатором. Если нужны Bluetooth, больше пинов и вычислительной мощности, правильный выбор — ESP32; платы мы сравниваем в статье «Arduino или ESP32?»

Идеи проектов на ESP-01

  • Умная Wi-Fi-розетка: включай и выключай лампу с телефона с помощью релейного модуля ESP-01S и скетча выше; добавь таймер, чтобы она загоралась вечером автоматически.
  • Беспроводной датчик температуры: подключи датчик DS18B20 к GPIO2; подтягивающий резистор 4,7 kΩ на линии данных заодно обеспечивает уровень HIGH, нужный при старте.
  • Монитор влажности и температуры: показывай показания DHT11 на веб-странице, которая открывается на телефоне.
  • Оповещение о движении: подключи PIR-датчик к GPIO3 и отправляй сообщение в Telegram, когда обнаружено движение; способ очень похож на тот, что в статье «Telegram-бот на ESP32».
  • Wi-Fi для проекта на Arduino: отправляй показания метеостанции на Uno в программу на компьютере или на сервер с помощью AT-команд.
  • Пульт для гаражных ворот: подключи контакты реле параллельно кнопке привода ворот и открывай ворота с телефона.

Частые ошибки и как их исправить

СимптомВероятная причинаРешение
«Failed to connect to ESP8266: Timed out waiting for packet header» (не удалось подключиться к ESP8266)Модуль не в режиме программирования, или перепутаны TX и RXСоедини GPIO0 с GND, отключи и снова подай питание, подключи TX к RXD, а RX к TXD
Мусорные символы в мониторе портаНе совпадает скорость; сообщения при старте идут на 74880 бодПопробуй 115200 и 9600; чтобы увидеть сообщение при старте, выбери 74880
На AT нет вообще никакого ответаНеверный конец строки, перепутаны TX и RX или не подключён ENВыбери Both NL & CR, подключи линии крест-накрест, подключи EN к 3,3 V
Модуль постоянно перезагружается, отваливается при подключении к Wi-FiНе хватает токаПоставь отдельный AMS1117-3.3 и конденсатор 100–470 µF, укороти провода
Ответ «busy p...»Новая команда отправлена до завершения предыдущейПосле каждой команды жди OK или ERROR
+CWJAP:3 и FAILСеть не найдена (сеть 5 GHz или неверное имя)Используй сеть 2,4 GHz и следи за заглавными и строчными буквами
Модуль сильно греется, светодиод не горитНа VCC подано 5 V или перепутаны VCC и GNDСразу отключи питание; скорее всего, модуль повреждён
С подключённым реле модуль не стартуетСхема на GPIO0 или GPIO2 тянет пин к LOW при стартеИспользуй подключение с активным LOW или перенеси вход на GPIO3
Релейный модуль на 5 V никогда не выключаетсяHIGH 3,3 V не до конца гасит оптопару 5-вольтового модуляИспользуй релейный модуль, совместимый с 3,3 V, или транзисторный драйвер
После загрузки из Arduino IDE AT-команды перестают работатьЗагруженная программа заменила AT-прошивкуЗаново запиши AT-прошивку Espressif с помощью esptool или Flash Download Tool
Чтобы проверить, действительно ли модуль стартует, поставь в мониторе порта скорость 74880 бод и сбрось модуль. Если видно boot mode:(3,x), он запустился в обычном режиме; boot mode:(1,x) означает режим программирования. Если не видно вообще ничего, проблема в питании, подключении EN или линиях TX-RX.

Несмотря на маленький размер, ESP-01 — отличный модуль, чтобы освоить все базовые понятия Wi-Fi: IP-адреса, TCP-соединения, веб-серверы и последовательную связь. Если что-то не работает, сначала проверь питание, затем линии TX-RX и уровень на GPIO0: подавляющее большинство проблем сводится к этим трём пунктам. В приложении BlueGrays есть проекты с пошаговыми схемами и кодом: подключение к Wi-Fi, веб-сервер, mDNS, обновление прошивки по воздуху (OTA) и умное освещение на реле.

Частые вопросы

Может ли ESP-01 работать от 5V?

Нет. ESP-01 работает в диапазоне от 3,0 до 3,6 V, и 5 V на пине VCC могут вывести его из строя навсегда. Чтобы питать модуль от 5 V Arduino, поставь между ними стабилизатор, например AMS1117-3.3, а сигнал 5 V с линии TX на Uno понизь до 3,3 V делителем напряжения.

Можно ли питать ESP-01 от пина 3,3 V на Arduino?

Не рекомендуется. Пин 3,3 V на Uno официально рассчитан на 50 mA, а ESP-01 при передаче потребляет 170 mA и в коротких пиках больше 300 mA. Даже если модуль отвечает на AT-команды, при подключении к сети он сбрасывается; используй отдельный стабилизатор 3,3 V, который выдаёт не меньше 300–500 mA.

Почему ESP-01 не отвечает на AT-команды?

Чаще всего причина в неверной скорости, в том, что в мониторе порта выбран не тот конец строки (нужен Both NL & CR), в том, что TX и RX не подключены крест-накрест, или в том, что пин EN (CH_PD) не подключён к 3,3 V. Если в модуль раньше загружали программу из Arduino IDE, AT-прошивка стёрта, и её нужно записать заново.

Стирает ли загрузка кода Arduino AT-прошивку ESP-01?

Да. Программа, загруженная из Arduino IDE, записывается во флеш-память на место AT-прошивки, и модуль больше не понимает AT-команды. Чтобы вернуться в режим AT, запиши AT-прошивку ESP8266 от Espressif с помощью esptool или Flash Download Tool по адресам, которые соответствуют объёму флеш-памяти модуля.

Чем ESP-01 отличается от ESP-01S?

Чип и распиновка одинаковые. ESP-01S обычно чёрный, у него 1 МБ флеш-памяти, нет светодиода питания, а синий светодиод подключён к GPIO2. У старого синего ESP-01 512 КБ флеш-памяти, красный светодиод питания, который горит постоянно, и синий светодиод на линии TX.

Какая скорость по умолчанию у ESP-01?

Большинство модулей с актуальной AT-прошивкой приходят со скоростью 115200 бод; у старых может быть 9600 или 57600. А первые сообщения при старте выводятся на 74880 бод. Если на Arduino Uno используется SoftwareSerial, связь станет надёжной, если навсегда понизить скорость до 9600 командой AT+UART_DEF=9600,8,1,0,0.

Все проекты
Подключение ESP32 к Wi-Fi в режиме STA (с экраном LCD)
#127Продвинутый

Подключение ESP32 к Wi-Fi в режиме STA (с экраном LCD)

В этом проекте ESP32 надёжно и устойчиво к сбоям подключается к домашней сети Wi-Fi в режиме станции (STA). SSID и пароль хранятся в отдельном файле secrets.h, чтобы не утекли в Git; настроено автоматическое переподключение, а уровень сигнала RSSI и IP-адрес выводятся на I2C LCD-экран. Встроенный светодиод служит индикатором состояния. Это менеджер подключения уровня реальных устройств.

4.4(21)
34
Асинхронный веб-сервер на ESP32 (с выводом IP на LCD)
#129Продвинутый

Асинхронный веб-сервер на ESP32 (с выводом IP на LCD)

В этом проекте ESP32 превращается в асинхронный веб-сервер, которым можно управлять с телефона или компьютера в той же сети Wi-Fi. Благодаря библиотеке ESPAsyncWebServer сервер может обрабатывать несколько запросов одновременно (в отличие от классического WebServer.h, который блокируется на одном запросе). Открыв IP-адрес ESP32 в браузере, ты нажимаешь кнопки ON/OFF (маршруты /on и /off) и включаешь и выключаешь светодиод на GPIO 5.

4.8(16)
26
mDNS на ESP32: доступ к устройству через bluegrays-esp.local (с экраном LCD)
#131Продвинутый
Premium

mDNS на ESP32: доступ к устройству через bluegrays-esp.local (с экраном LCD)

В этом проекте к ESP32 добавляется служба mDNS (Multicast DNS), и к устройству можно обращаться по понятному имени вроде bluegrays-esp.local вместо IP-адреса. Даже если IP, выданный DHCP, меняется, устройство всегда доступно по одному имени. На устройстве также работает маленький веб-сервер, через который по адресу http://bluegrays-esp.local/ из браузера отправляются команды светодиоду. I2C LCD показывает имя хоста, IP-адрес и состояние светодиода.

4.8(14)
23
Обновление ESP32 по воздуху (OTA): беспроводная установка прошивки (с экраном LCD)
#132Продвинутый
Premium

Обновление ESP32 по воздуху (OTA): беспроводная установка прошивки (с экраном LCD)

В этом проекте ты узнаешь, как загружать новую прошивку в ESP32 по Wi-Fi без USB-кабеля. С библиотекой ArduinoOTA ESP32 становится видна в сети и автоматически появляется как bluegrays-ota на вкладке «Сетевой порт» в Arduino IDE. Первая загрузка выполняется по USB, а все следующие обновления — без проводов: это важно для устройств в эксплуатации. I2C LCD показывает состояние Wi-Fi, IP-адрес, имя хоста, процент загрузки OTA и сообщения об ошибках.

4.6(14)
22
Точное время из интернета через NTP на ESP32
#128Продвинутый
Premium

Точное время из интернета через NTP на ESP32

ESP32 подключается к Wi-Fi и получает точное время с точностью до миллисекунд от серверов NTP (Network Time Protocol). Благодаря функции configTzTime() автоматически применяется часовой пояс Турции (TRT, UTC+3), а в странах с летним временем переходы обрабатываются автоматически по строке POSIX TZ. Время выводится в монитор порта и на необязательный I2C LCD. configTzTime() запускает службу SNTP, которая периодически пересинхронизирует часы.

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

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

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

4.3(6)
11
Включение лампы 220V кнопкой (вкл/выкл)
#20Продвинутый
Premium

Включение лампы 220V кнопкой (вкл/выкл)

Хочешь включать и выключать настоящую бытовую лампу крошечной кнопкой? При каждом нажатии кнопки Arduino переключает реле, и лампа загорается; нажмёшь снова — гаснет. Реле — посредник, который позволя

4.5(33)
44
Односторонняя связь между двумя Arduino
#57Средний
Premium

Односторонняя связь между двумя Arduino

Ты заставляешь две Arduino разговаривать по одному проводу: нажми кнопку на одной, и на другой загорится светодиод, нажми снова — погаснет. Плата-передатчик сообщает о нажатии кнопки коротким сообщени

4.4(37)
50