В этой статье я расскажу, как можно управлять реле через браузер, применительно к модулю ESP32-WROOM-32E. Для Работы нам понадобится сам модуль, USB-UART преобразователь на чипе CH340G, соединительные провода, источник питания 12в 1А (модуль может работать в диапазоне от 7 до 30в, сила тока от 1А и выше, поскольку модуль достаточно прожорливый, плюс реле потребляют ток). Я использовал плату с 8 реле. Она называется ESP32_Relay_X8 (303E32DC810) В данной версии платы задействованы следующие выводы:
GPIO 0 – кнопка “IO 0”
GPIO 23 – светодиод
GPIO 32 – реле 1
GPIO 33 – реле 2
GPIO 25 – реле 3
GPIO 26 – реле 4
GPIO 27 – реле 5
GPIO 14 – реле 6
GPIO 12 – реле 7
GPIO 13 – реле 8
Вначале выполним подготовительные работы.
- установите на компьютер Arduino IDE (я использовал версию 2.3.8)
- Скачайте и установите драйвера для CH340G (легко находятся в поисковике)
- Запустите Arduino IDE и выберите в менеджере плат ESP32 Dev Module (возможно, потребуется установить дополнительные библиотеки, дождитесь, пока программа не загрузит необходимые дополнения.
Зайдите в инструменты и убедитесь, что пункт PSRAM имеет значение Disabled.
Далее приступим к подключению программатора к плате:
3V3 -> 3V3
TXD -> RX
RXD -> TX
GND -> GND

Проверьте, что вы правильно соединили программатор и плату ДО включения питания платы! Обратите внимание на положение перемычки на программаторе, она должна замыкать контакты S1 и 3V3! Еще раз проверьте правильность соединений проводников, далее подключите питание к плате. Для этого используйте стабилизированный источник питания. В моем случае это был адаптер питания 12в 4А. Он подключается к разъему питания 1 и 2 контакты, обозначенные 7-30v и GND соответственно. Подключите адаптер питания к сети, а программатор к USB порту компьютера. Переведите плату в режим прошивки, для этого выполните следующие действия:
Нажать кнопки EN и IO0 одновременно
Отпустить кнопку EN, удерживая IO0 нажатой
Отпустить кнопку IO0
После этого можно вставить код скетча в окно программы Arduino IDE:
#include <WiFi.h>
#include <WebServer.h>
// Конфигурация реле
#define RELAY_NO false // false = NC (нормально замкнутое), true = NO (нормально разомкнутое)
#define NUM_RELAYS 8
int relayGPIOs[NUM_RELAYS] = {32, 33, 25, 26, 27, 14, 12, 13};
// Настройки точки доступа Wi‑Fi
const char* ssidAP = "ESP32-Relay-Control";
const char* passwordAP = "1234567890";
WebServer server(80);
const char* index_html = R"rawliteral(
<!DOCTYPE HTML>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="UTF-8">
<style>
body {
font-family: Arial;
text-align: center;
margin: 20px;
background-color: #f5f5f5;
}
.relay {
margin: 15px 0;
padding: 12px;
border: 1px solid #ccc;
border-radius: 8px;
background-color: white;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
/* Стиль для чекбоксов (кнопок) */
input[type="checkbox"] {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
width: 50px;
height: 25px;
background: #d3d3d3; /* Серый цвет */
border-radius: 12px; /* Скруглённые углы */
position: relative;
outline: none;
cursor: pointer;
transition: background-color 0.3s;
}
input[type="checkbox"]:checked {
background: #4CAF50; /* Зелёный цвет при активации */
}
input[type="checkbox"]::before {
content: '';
position: absolute;
top: 2px;
left: 2px;
width: 21px;
height: 21px;
background: white;
border-radius: 50%;
transition: transform 0.3s;
}
input[type="checkbox"]:checked::before {
transform: translateX(25px);
}
label {
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
cursor: pointer;
}
.footer {
margin-top: 30px;
padding: 10px;
color: #666;
font-size: 14px;
border-top: 1px solid #ddd;
}
</style>
</head>
<body>
<h1>Управление реле ESP32</h1>
<p>IP: %IP%</p>
%BUTTONS%
<!-- Текст внизу страницы -->
<div class="footer">
<p>Управление реле</p>
</div>
<script>
function toggleRelay(id) {
const xhr = new XMLHttpRequest();
const state = document.getElementById('relay' + id).checked ? 1 : 0;
xhr.open('GET', '/update?relay=' + id + '&state=' + state, true);
xhr.send();
}
</script>
</body>
</html>
)rawliteral";
String getRelayButtons() {
String buttons = "";
for (int i = 1; i <= NUM_RELAYS; i++) {
String checked = relayState(i) == "checked" ? "checked" : "";
buttons += "<div class='relay'>";
buttons += "<h3>Реле #" + String(i) + " (GPIO " + String(relayGPIOs[i - 1]) + ")</h3>";
buttons += "<label>";
buttons += " <input type='checkbox' id='relay" + String(i) + "' " + checked + " onchange='toggleRelay(" + String(i) + ")'>";
String stateText = (checked == "checked") ? "ВКЛ" : "ВЫКЛ";
buttons += " <span>" + stateText + "</span>";
buttons += "</label>";
buttons += "</div>";
}
return buttons;
}
String processor(const String& var) {
if (var == "IP") {
return WiFi.softAPIP().toString();
} else if (var == "BUTTONS") {
return getRelayButtons();
}
return String();
}
String relayState(int numRelay) {
int pin = relayGPIOs[numRelay - 1];
if (RELAY_NO) {
if (digitalRead(pin) == HIGH) return "";
else return "checked";
} else {
if (digitalRead(pin) == LOW) return "";
else return "checked";
}
}
void setup() {
Serial.begin(115200);
delay(1000);
Serial.printf("Свободная память до инициализации: %d байт\n", ESP.getFreeHeap());
// Инициализация реле
for (int i = 0; i < NUM_RELAYS; i++) {
pinMode(relayGPIOs[i], OUTPUT);
digitalWrite(relayGPIOs[i], RELAY_NO ? HIGH : LOW);
}
// Настройка Wi‑Fi в режиме точки доступа
WiFi.mode(WIFI_AP);
WiFi.softAP(ssidAP, passwordAP);
server.on("/", HTTP_GET, []{
String page = index_html;
page.replace("%IP%", WiFi.softAPIP().toString());
page.replace("%BUTTONS%", getRelayButtons());
server.send(200, "text/html; charset=UTF-8", page);
});
server.on("/update", HTTP_GET, []{
int relayNum = server.arg("relay").toInt();
int state = server.arg("state").toInt();
if (relayNum >= 1 && relayNum <= NUM_RELAYS) {
int pin = relayGPIOs[relayNum - 1];
digitalWrite(pin, RELAY_NO ? (state == 1 ? LOW : HIGH) : (state == 1 ? HIGH : LOW));
}
server.sendHeader("Location", "/");
server.send(303);
});
server.begin();
Serial.println("ESP32 Web Server запущен");
Serial.print("Точка доступа: "); Serial.println(ssidAP);
Serial.print("Пароль: "); Serial.println(passwordAP);
Serial.print("IP адрес: "); Serial.println(WiFi.softAPIP());
}
void loop() {
server.handleClient();
}
В указанном выше коде следует изменить параметры точки доступа (сменив ее имя и пароль для подключения). Дополнительно можно внести изменения в шаблон HTML разметки страницы для изменения интерфейса и оптимизации кода.
Так, например я использовал библиотеку WebServer.h, хотя многие задействуют для этого ESPAsyncWebServer, но у меня он выдавал ошибку после загрузки кода в ESP32, после чего плата уходила в циклическую перезагрузку. Так же в коде я использовал явное указание использовать кодировку UTF-8 для корректного отображения русского текста. Загружать скетч следует на скорости 115200 бод. После завершения компиляции скетча и загрузки кода в плату – перезагрузите ее нажатием кнопки EN на плате. После этого в мониторе Arduino IDE вы увидите назначенный IP адрес платы, что говорит о ее готовности к работе. Подключитесь к WiFi сети, используя параметры, указанные в Вашем коде, и откройте страницу по указанному в мониторе IP адресу. Если все сделано правильно, то откроется интерфейс управления реле.
Данный код можно модифицировать под свои нужды, указывать первоначальное состояние реле, добавлять таймеры работы и многое другое.
Администратор сайта (C) 2026




