1. Ідентифікація та основні компоненти
ESP-WROOM-32 (ESP-32S) — це потужний модуль на базі двоядерного процесора ESP32 з вбудованими модулями Wi-Fi та Bluetooth, що робить його ідеальним вибором для різноманітних IoT проєктів.
flowchart TD
subgraph ESP32["ESP-WROOM-32 (ESP-32S) з CP2102"]
direction TB
subgraph Components["Основні компоненти"]
ESP["ESP32
двоядерний процесор"]
CP["CP2102
USB-UART конвертер"]
AMS["AMS1117
стабілізатор 3.3В"]
LUSB["MicroUSB
порт"]
FLASH["4MB Flash
пам'ять"]
ANT["Wi-Fi/BT
антена"]
BOOT["Кнопка BOOT/FLASH
(GPIO0)"]
EN["Кнопка EN
(RESET)"]
LED["Світлодіод
(GPIO2)"]
end
subgraph Pins["Виводи"]
direction TB
subgraph LeftPins["Ліва сторона"]
direction TB
L1["3V3"] --- L2["EN"] --- L3["VP"] --- L4["VN"] --- L5["IO34"] --- L6["IO35"] --- L7["IO32"] --- L8["IO33"] --- L9["IO25"] --- L10["IO26"] --- L11["IO27"] --- L12["IO14"] --- L13["IO12"] --- L14["GND"] --- L15["IO13"]
end
subgraph RightPins["Права сторона"]
direction TB
R1["VIN"] --- R2["GND"] --- R3["IO23"] --- R4["IO22"] --- R5["IO1"] --- R6["IO3"] --- R7["IO21"] --- R8["GND"] --- R9["IO19"] --- R10["IO18"] --- R11["IO5"] --- R12["IO17"] --- R13["IO16"] --- R14["IO4"] --- R15["IO0"] --- R16["IO2"] --- R17["IO15"] --- R18["GND"] --- R19["3V3"]
end
end
end
classDef comp fill:#b3e0ff,stroke:#333,stroke-width:2px
classDef pin fill:#f96,stroke:#333,stroke-width:2px
class ESP,CP,AMS,LUSB,FLASH,ANT,BOOT,EN,LED comp
class L1,L2,L3,L4,L5,L6,L7,L8,L9,L10,L11,L12,L13,L14,L15,R1,R2,R3,R4,R5,R6,R7,R8,R9,R10,R11,R12,R13,R14,R15,R16,R17,R18,R19 pin
Особливості виводів ESP32:
Вивід |
Функція |
Примітки |
3V3 |
Живлення 3.3В |
Вихід внутрішнього стабілізатора |
EN (Enable) |
Сигнал увімкнення |
Рівень LOW вимикає ESP32 |
VP (GPIO36) |
Аналоговий вхід 1 |
Високочутливий АЦП |
VN (GPIO39) |
Аналоговий вхід 2 |
Високочутливий АЦП |
IO34-IO39 |
Вхідні GPIO |
Тільки вхідні, без внутрішніх підтягувальних резисторів |
IO0 |
GPIO / Boot режим |
LOW при завантаженні = режим прошивки |
IO2 |
GPIO / LED |
Часто підключений до вбудованого світлодіоду |
VIN |
Вхід живлення |
5-12В, з'єднаний з USB через діод |
На відміну від більшості мікроконтролерів, ESP32 має лише деякі піни, що підтримують аналогове введення (ADC). Піни GPIO34-GPIO39 є вхідними, вони не можуть працювати як виходи. Також ESP32 має два вбудованих 8-бітних ЦАП (GPIO25 та GPIO26).
2. Необхідні компоненти для початку роботи
2.1. Апаратне забезпечення
- Плата ESP-WROOM-32 (ESP-32S) з CP2102
- Кабель Micro-USB
- Комп'ютер з USB-портом
- Макетна плата та з'єднувальні дроти (опціонально для проєктів)
2.2. Програмне забезпечення
- Visual Studio Code (VS Code)
- Розширення PlatformIO IDE для VS Code
- Драйвери для CP2102 (при необхідності)
Використання PlatformIO у VS Code надає більш професійне середовище розробки порівняно зі стандартним Arduino IDE, включаючи автодоповнення коду, багатоплатформову підтримку та кращу організацію проєктів.
3. Підключення та налаштування
3.1. Фізичне підключення
flowchart LR
PC["Комп'ютер
USB-порт"] --> |"Micro-USB
кабель"| ESP32["ESP-WROOM-32
Micro-USB порт"]
subgraph Internal["Внутрішні з'єднання в ESP-WROOM-32"]
direction TB
USBP["Micro-USB
порт"] --> CP2102["CP2102
USB-UART
конвертер"]
CP2102 --> |"UART
(TX/RX)"| ESP32Core["ESP32
процесор"]
CP2102 --> |"DTR/RTS"| AutoReset["Схема
авто-скидання"]
AutoReset --> |"EN/GPIO0"| ESP32Core
USBP --> |"5V"| AMS1117["AMS1117
3.3V стабілізатор"]
AMS1117 --> |"3.3V"| ESP32Core
end
ESP32 --- Internal
classDef pc fill:#f9f,stroke:#333,stroke-width:2px
classDef board fill:#9cf,stroke:#333,stroke-width:2px
classDef comp fill:#fc9,stroke:#333,stroke-width:2px
class PC pc
class ESP32 board
class USBP,CP2102,ESP32Core,AutoReset,AMS1117 comp
- Підключіть кабель Micro-USB до порту на платі ESP-WROOM-32.
- Підключіть інший кінець кабелю до USB-порту вашого комп'ютера.
- На платі має загорітися світлодіод живлення, що свідчить про правильне підключення.
3.2. Встановлення драйверів CP2102 (якщо потрібно)
Більшість сучасних операційних систем автоматично встановлюють драйвери для CP2102, але якщо ваша плата не визначається, виконайте наступні кроки:
Для Windows:
- Завантажте драйвери CP210x з офіційного сайту Silicon Labs.
- Розпакуйте архів та запустіть файл інсталятора.
- Дотримуйтесь інструкцій для завершення встановлення.
- Перевірте "Диспетчер пристроїв" (Device Manager) у розділі "Порти (COM та LPT)", де має з'явитися "Silicon Labs CP210x USB to UART Bridge (COMx)".
Для macOS та Linux:
Для macOS драйвери можна знайти на тому ж сайті Silicon Labs. У більшості дистрибутивів Linux CP2102 підтримується з коробки, але можуть знадобитися права для доступу до послідовного порту:
sudo usermod -a -G dialout $USER # Для Ubuntu/Debian
sudo usermod -a -G uucp $USER # Для Arch Linux
3.3. Встановлення VS Code та PlatformIO
- Завантажте та встановіть VS Code з офіційного сайту.
- Відкрийте VS Code.
- Перейдіть до розділу розширень (Extensions): натисніть на іконку з квадратиками на бічній панелі ліворуч або використовуйте комбінацію Ctrl+Shift+X (Cmd+Shift+X на Mac).
- У полі пошуку введіть "PlatformIO IDE".
- Знайдіть розширення від PlatformIO.org та натисніть "Install".
- Дочекайтеся завершення інсталяції та активації розширення.
- Після інсталяції може знадобитися перезавантажити VS Code.
4. Створення першого проєкту
4.1. Створення проєкту "Blink" у PlatformIO
- Відкрийте VS Code з встановленим PlatformIO.
- Натисніть на іконку PlatformIO (логотип з головою прибульця) на бічній панелі.
- На вкладці "PIO Home" натисніть "New Project".
- Заповніть поля для створення проєкту:
- Name: введіть назву проєкту (наприклад, "ESP32_Blink")
- Board: у полі пошуку введіть "ESP32 DEVKIT" та виберіть "DOIT ESP32 DEVKIT V1"
- Framework: виберіть "Arduino"
- Location: можете залишити прапорець "Use default location" або вибрати іншу папку
- Натисніть "Finish".
- Зачекайте, поки PlatformIO створить структуру проєкту та завантажить необхідні інструменти.
flowchart TD
A["Відкрийте VS Code"] --> B["Натисніть на іконку PlatformIO"]
B --> C["Виберіть 'New Project'"]
C --> D["Заповніть дані проєкту:"]
D --> D1["Name: ESP32_Blink"]
D --> D2["Board: DOIT ESP32 DEVKIT V1"]
D --> D3["Framework: Arduino"]
D --> E["Натисніть 'Finish'"]
E --> F["Дочекайтеся завершення
створення проєкту"]
4.2. Створення тестового скетчу
- У провіднику файлів VS Code (ліва панель) розкрийте папку вашого проєкту.
- Перейдіть до папки src і відкрийте файл main.cpp.
- Видаліть весь існуючий код та вставте наступний скетч для блимання світлодіодом:
#include
// Визначення піну для вбудованого світлодіода
// На більшості плат ESP32 DevKit V1 це GPIO2
#define LED_BUILTIN 2
void setup() {
// Налаштовуємо серійний порт для відлагодження
Serial.begin(115200);
Serial.println("ESP32 Тест світлодіода");
// Налаштовуємо пін світлодіода як вихід
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
// Вмикаємо світлодіод
digitalWrite(LED_BUILTIN, HIGH);
Serial.println("LED ON");
delay(1000); // Чекаємо 1 секунду
// Вимикаємо світлодіод
digitalWrite(LED_BUILTIN, LOW);
Serial.println("LED OFF");
delay(1000); // Чекаємо 1 секунду
}
4.3. Завантаження прошивки на ESP32
- Переконайтеся, що плата ESP32 підключена до комп'ютера.
- У VS Code натисніть на іконку PlatformIO у лівій бічній панелі.
- У розділі "Project Tasks" знайдіть ваш проєкт та розгорніть його.
- Натисніть на "Build" для компіляції проекту (без завантаження).
- Після успішної збірки натисніть на "Upload" для завантаження прошивки на плату.
Деякі плати ESP32 не мають функціонального автоматичного скидання у режим завантаження. Якщо завантаження зупиняється на етапі "Connecting..." або "Waiting for device", потрібно перевести плату в режим завантаження вручну.
4.4. Ручний режим завантаження (якщо потрібно)
sequenceDiagram
participant User as Користувач
participant IDE as PlatformIO IDE
participant ESP as ESP32
Note over User,ESP: Якщо процес завантаження зупиняється на "Connecting..."
User->>IDE: Натискає "Upload"
IDE->>ESP: Спроба підключення (не вдається)
Note over IDE: Чекає на з'єднання...
User->>ESP: Натискає та утримує кнопку BOOT
User->>ESP: Натискає кнопку EN (Reset), не відпускаючи BOOT
User->>ESP: Відпускає кнопку EN
User->>ESP: Відпускає кнопку BOOT
ESP->>IDE: Режим завантаження активовано
IDE->>ESP: Передача прошивки
IDE->>User: Повідомлення про успіх [SUCCESS]
- Коли в консолі PlatformIO з'явиться повідомлення "Connecting...", виконайте наступні дії:
- Натисніть і утримуйте кнопку "BOOT" (або "FLASH") на платі ESP32.
- Не відпускаючи "BOOT", коротко натисніть кнопку "EN" (або "RST") і відпустіть її.
- Відпустіть кнопку "BOOT".
- PlatformIO має продовжити процес завантаження.
Після першого завантаження прошивки, за наявності схеми автоматичного скидання на вашій платі, наступні завантаження можуть відбуватися автоматично, без ручного режиму
4.5. Перевірка роботи скетчу
- Після успішного завантаження прошивки (побачите повідомлення "[SUCCESS]" у терміналі) вбудований світлодіод на платі ESP32 (зазвичай підключений до GPIO2) почне блимати з інтервалом в 1 секунду.
- Додатково можна відкрити монітор послідовного порту для перегляду повідомлень від ESP32:
- В PlatformIO: натисніть на "Monitor" у розділі "Project Tasks"
- Або натисніть на іконку розетки в нижній панелі VS Code
- У моніторі має відображатися повідомлення "LED ON" та "LED OFF" при кожному перемиканні світлодіода.
Якщо світлодіод блимає і ви бачите повідомлення в моніторі порту, це означає, що ваша плата ESP-WROOM-32 правильно підключена і налаштована!
5. Робота з Wi-Fi
5.1. Приклад сканування Wi-Fi мереж
Наступний скетч демонструє, як використовувати модуль Wi-Fi ESP32 для сканування доступних мереж:
#include
#include
void setup() {
Serial.begin(115200);
// Встановлюємо режим Wi-Fi як станція (клієнт)
WiFi.mode(WIFI_STA);
WiFi.disconnect(); // Відключаємось від будь-яких попередніх підключень
delay(100);
Serial.println("Налаштування ESP32 Wi-Fi завершено");
}
void loop() {
Serial.println("Початок сканування Wi-Fi мереж...");
// Скануємо доступні мережі
int networksFound = WiFi.scanNetworks();
if (networksFound == 0) {
Serial.println("Не знайдено жодної Wi-Fi мережі");
} else {
Serial.print("Знайдено ");
Serial.print(networksFound);
Serial.println(" мереж(і):");
for (int i = 0; i < networksFound; ++i) {
// Виводимо SSID, RSSI та тип шифрування для кожної мережі
Serial.print(i + 1);
Serial.print(": ");
Serial.print(WiFi.SSID(i));
Serial.print(" (");
Serial.print(WiFi.RSSI(i));
Serial.print(" дБм) ");
// Позначаємо зашифровані мережі
Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN) ? "відкрита" : "зашифрована");
delay(10); // Невелика пауза між виведенням мереж
}
}
Serial.println("");
// Чекаємо 5 секунд перед наступним скануванням
delay(5000);
}
5.2. Підключення до Wi-Fi мережі
Цей приклад демонструє, як підключити ESP32 до Wi-Fi мережі:
#include
#include
// Налаштування Wi-Fi
const char* ssid = "Ваша_WiFi_Мережа"; // Замініть на ім'я вашої мережі
const char* password = "Ваш_WiFi_Пароль"; // Замініть на пароль вашої мережі
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("\nПочаток підключення до Wi-Fi");
Serial.printf("Підключення до мережі: %s\n", ssid);
// Підключення до Wi-Fi мережі
WiFi.begin(ssid, password);
// Очікування підключення
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
// Відображення інформації про підключення
Serial.println("\nWi-Fi підключено!");
Serial.print("IP-адреса: ");
Serial.println(WiFi.localIP());
Serial.print("Шлюз: ");
Serial.println(WiFi.gatewayIP());
Serial.print("Маска підмережі: ");
Serial.println(WiFi.subnetMask());
Serial.print("DNS: ");
Serial.println(WiFi.dnsIP());
Serial.print("Сила сигналу: ");
Serial.print(WiFi.RSSI());
Serial.println(" дБм");
}
void loop() {
// Перевірка стану підключення
if (WiFi.status() != WL_CONNECTED) {
Serial.println("З'єднання з Wi-Fi втрачено! Повторне підключення...");
WiFi.begin(ssid, password);
// Очікування повторного підключення
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWi-Fi підключено повторно!");
}
// Ваш код для роботи з мережею...
delay(10000); // Перевірка підключення кожні 10 секунд
}
Замініть "Ваша_WiFi_Мережа" та "Ваш_WiFi_Пароль" на реальні дані вашої Wi-Fi мережі перед завантаженням скетчу.
6. Використання Bluetooth
6.1. Приклад простого Bluetooth-сервера
#include
#include
// Перевірка, чи підтримується Bluetooth
#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth не ввімкнено! Будь ласка, увімкніть його в menuconfig.
#endif
BluetoothSerial SerialBT;
const int ledPin = 2; // Вбудований світлодіод на GPIO2
void setup() {
Serial.begin(115200);
pinMode(ledPin, OUTPUT);
// Ініціалізуємо Bluetooth з іменем "ESP32BT"
SerialBT.begin("ESP32BT");
Serial.println("Bluetooth запущено! Підключіться до 'ESP32BT' зі свого телефону");
Serial.println("Доступні команди:");
Serial.println("1: Увімкнути світлодіод");
Serial.println("0: Вимкнути світлодіод");
Serial.println("s: Отримати статус");
}
void loop() {
// Перевірка наявності даних з Bluetooth
if (SerialBT.available()) {
char incomingChar = SerialBT.read();
Serial.printf("Отримано: %c\n", incomingChar);
// Обробка команд
switch (incomingChar) {
case '1':
digitalWrite(ledPin, HIGH);
SerialBT.println("Світлодіод увімкнено");
break;
case '0':
digitalWrite(ledPin, LOW);
SerialBT.println("Світлодіод вимкнено");
break;
case 's':
case 'S':
SerialBT.printf("Стан світлодіода: %s\n",
digitalRead(ledPin) ? "увімкнено" : "вимкнено");
break;
default:
SerialBT.println("Невідома команда. Використовуйте: 1, 0 або s");
break;
}
}
// Перевірка наявності даних з послідовного порту (для відлагодження)
if (Serial.available()) {
char incomingChar = Serial.read();
SerialBT.write(incomingChar);
}
delay(20); // Невелика затримка для стабільності
}
Для підключення до ESP32 через Bluetooth:
- Завантажте на свій смартфон програму Bluetooth-термінала (наприклад, "Serial Bluetooth Terminal" для Android або "Bluetooth Terminal" для iOS).
- Увімкніть Bluetooth на смартфоні та виконайте пошук пристроїв.
- Знайдіть та підключіться до пристрою "ESP32BT".
- Використовуйте термінал для надсилання команд: "1" для увімкнення світлодіода, "0" для вимкнення та "s" для перевірки статусу.
7. Використання датчиків та периферії
7.1. Аналоговий ввід (ADC)
ESP32 має кілька каналів аналого-цифрового перетворення. Ось приклад зчитування напруги з аналогового входу:
#include
// Визначаємо пін для аналогового зчитування
const int analogPin = 34; // GPIO34 (також VP) на ESP32
// Налаштування ADC
const int adcResolution = 12; // ESP32 має 12-бітний АЦП (0-4095)
const float adcMaxValue = 4095.0; // Максимальне значення для 12-бітного АЦП
const float adcReferenceVoltage = 3.3; // Опорна напруга ESP32
void setup() {
Serial.begin(115200);
// Налаштовуємо роздільну здатність ADC (від 9 до 12 біт)
analogReadResolution(adcResolution);
// Опціонально можна налаштувати згладжування
analogSetWidth(adcResolution);
analogSetAttenuation(ADC_11db); // Повний діапазон: 0-3.3В
Serial.println("ESP32 ADC Тест");
}
void loop() {
// Зчитуємо сире значення ADC
int adcRaw = analogRead(analogPin);
// Перетворюємо сире значення у напругу
float voltage = (adcRaw / adcMaxValue) * adcReferenceVoltage;
// Виводимо результати
Serial.print("Сире значення ADC: ");
Serial.print(adcRaw);
Serial.print(" | Напруга: ");
Serial.print(voltage, 2); // Два знаки після коми
Serial.println("В");
delay(1000); // Зчитування кожну секунду
}
На ESP32 аналогові входи GPIO32-GPIO39 є найкращим вибором для ADC. Піни GPIO0, GPIO2, GPIO4, GPIO12-GPIO15 також підтримують аналоговий ввід, але їх використання може впливати на Wi-Fi/Bluetooth та взаємодіяти з іншими функціями.
7.2. ШІМ (PWM) виводи
ESP32 має 16 каналів ШІМ, які можна налаштувати на різні частоти та роздільну здатність:
#include
// Налаштування ШІМ
const int pwmPin = 16; // GPIO-пін для ШІМ
const int pwmChannel = 0; // ШІМ-канал (0-15)
const int pwmFreq = 5000; // Частота ШІМ в Гц
const int pwmResolution = 8; // Роздільна здатність (1-16 біт)
const int maxDutyCycle = (1 << pwmResolution) - 1; // 255 для 8-біт
void setup() {
Serial.begin(115200);
// Налаштовуємо ШІМ
ledcSetup(pwmChannel, pwmFreq, pwmResolution);
// Підключаємо GPIO-пін до ШІМ-каналу
ledcAttachPin(pwmPin, pwmChannel);
Serial.println("ESP32 PWM Тест");
}
void loop() {
// Плавне збільшення яскравості (ефект "дихання")
Serial.println("Збільшення яскравості...");
for (int dutyCycle = 0; dutyCycle <= maxDutyCycle; dutyCycle++) {
ledcWrite(pwmChannel, dutyCycle);
delay(5);
}
// Плавне зменшення яскравості
Serial.println("Зменшення яскравості...");
for (int dutyCycle = maxDutyCycle; dutyCycle >= 0; dutyCycle--) {
ledcWrite(pwmChannel, dutyCycle);
delay(5);
}
}
7.3. Використання цифро-аналогового перетворювача (DAC)
ESP32 має два 8-бітних канали DAC на пінах GPIO25 (DAC1) та GPIO26 (DAC2):
#include
#include
// Налаштування DAC
const int sineWaveFreq = 1; // Частота хвилі в Гц
void setup() {
Serial.begin(115200);
// Ініціалізуємо обидва канали DAC
dac_output_enable(DAC_CHANNEL_1); // GPIO25
dac_output_enable(DAC_CHANNEL_2); // GPIO26
Serial.println("ESP32 DAC Тест - генерація синусоїди");
}
void loop() {
// Генеруємо синусоїду на DAC1 і косинусоїду на DAC2
for (int degree = 0; degree < 360; degree++) {
// Розрахунок значень для синуса і косинуса
// від 0 до 255 (8-біт DAC)
int sinValue = 127 + 127 * sin(degree * PI / 180);
int cosValue = 127 + 127 * cos(degree * PI / 180);
// Виведення на DAC
dac_output_voltage(DAC_CHANNEL_1, sinValue); // GPIO25
dac_output_voltage(DAC_CHANNEL_2, cosValue); // GPIO26
// Затримка для контролю частоти
delayMicroseconds(1000000 / 360 / sineWaveFreq);
}
}
8. Використання багатозадачності на ESP32
8.1. Багатозадачність з FreeRTOS
ESP32 має двоядерний процесор і підтримує реальну багатозадачність за допомогою FreeRTOS:
#include
// Налаштування завдань RTOS
TaskHandle_t Task1;
TaskHandle_t Task2;
// Пін для світлодіода
const int led1 = 2; // Вбудований світлодіод на GPIO2
const int led2 = 4; // Додатковий світлодіод на GPIO4 (якщо підключено)
// Коди завдань
void Task1code(void *pvParameters) {
Serial.print("Завдання 1 працює на ядрі ");
Serial.println(xPortGetCoreID());
while(true) {
digitalWrite(led1, HIGH);
delay(1000);
digitalWrite(led1, LOW);
delay(1000);
}
}
void Task2code(void *pvParameters) {
Serial.print("Завдання 2 працює на ядрі ");
Serial.println(xPortGetCoreID());
while(true) {
digitalWrite(led2, HIGH);
delay(500);
digitalWrite(led2, LOW);
delay(500);
}
}
void setup() {
Serial.begin(115200);
// Налаштовуємо піни
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
// Створюємо завдання на різних ядрах ESP32
// Параметри: (ім'я завдання, розмір стеку, вказівник на параметри, пріоритет, &ідентифікатор, ядро)
// Запуск завдання 1 на ядрі 0
xTaskCreatePinnedToCore(
Task1code, // Функція завдання
"Task1", // Ім'я завдання
10000, // Розмір стеку (в словах)
NULL, // Параметри
1, // Пріоритет (більше число = вищий пріоритет)
&Task1, // Ідентифікатор завдання
0); // Ядро 0
delay(500); // Затримка для стабільності
// Запуск завдання 2 на ядрі 1
xTaskCreatePinnedToCore(
Task2code, // Функція завдання
"Task2", // Ім'я завдання
10000, // Розмір стеку
NULL, // Параметри
1, // Пріоритет
&Task2, // Ідентифікатор завдання
1); // Ядро 1
Serial.println("Обидва завдання запущено");
}
void loop() {
// Ніякого коду не потрібно в loop(), оскільки все виконують завдання
// Можна використовувати loop() для моніторингу, якщо потрібно
delay(1000);
}
Використання багатозадачності дозволяє ESP32 одночасно виконувати декілька складних операцій, таких як обробка датчиків, керування виводами та підтримка мережевих з'єднань, без блокування основного циклу програми.
9. Режими енергозбереження
9.1. Використання режиму глибокого сну (Deep Sleep)
#include
// Визначення пінів
#define WAKE_PIN GPIO_NUM_33 // Пін для пробудження (RTC GPIO)
// Час сну (в мікросекундах)
#define uS_TO_S_FACTOR 1000000 // Коефіцієнт переведення мікросекунд в секунди
#define TIME_TO_SLEEP 10 // Час сну в секундах
// Лічильник пробуджень
RTC_DATA_ATTR int bootCount = 0;
void setup() {
Serial.begin(115200);
delay(1000); // Час для відкриття серійного монітора
// Збільшуємо лічильник пробуджень (зберігається в RTC пам'яті)
++bootCount;
// Виводимо інформацію про пробудження
Serial.println("ESP32 прокинувся!");
Serial.print("Кількість пробуджень: ");
Serial.println(bootCount);
// Вивід причини пробудження
esp_sleep_wakeup_cause_t wakeup_reason;
wakeup_reason = esp_sleep_get_wakeup_cause();
switch(wakeup_reason) {
case ESP_SLEEP_WAKEUP_EXT0 :
Serial.println("Пробудження через зовнішній сигнал на пін RTC_IO");
break;
case ESP_SLEEP_WAKEUP_EXT1 :
Serial.println("Пробудження через зовнішній сигнал на пін RTC_CNTL");
break;
case ESP_SLEEP_WAKEUP_TIMER :
Serial.println("Пробудження через таймер");
break;
case ESP_SLEEP_WAKEUP_TOUCHPAD :
Serial.println("Пробудження через сенсорну кнопку");
break;
default :
Serial.printf("Пробудження не через Deep Sleep: %d\n", wakeup_reason);
break;
}
// Виконати корисну роботу перед сном
// Наприклад, зчитати датчики, відправити дані тощо
Serial.println("Виконання задач перед сном...");
delay(1000);
// Налаштування пробудження
// 1. Налаштування таймера пробудження
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
Serial.printf("Налаштовано пробудження через %d секунд\n", TIME_TO_SLEEP);
// 2. Налаштування пробудження від зовнішнього сигналу (опціонально)
esp_sleep_enable_ext0_wakeup(WAKE_PIN, 1); // 1 = HIGH для пробудження
// Перехід у глибокий сон
Serial.println("Перехід у режим глибокого сну");
Serial.flush(); // Чекаємо завершення передачі даних через UART
esp_deep_sleep_start();
// Цей код не виконається після виклику esp_deep_sleep_start()
Serial.println("Цей текст ніколи не буде виведено");
}
void loop() {
// Не використовується при використанні deep sleep
}
При використанні режиму глибокого сну, всі дані в пам'яті та стан GPIO втрачаються. Лише RTC-пам'ять (позначена атрибутом RTC_DATA_ATTR) зберігає дані між циклами сну. Також пам'ятайте, що не всі GPIO-піни можуть бути використані для пробудження (тільки піни RTC GPIO, такі як GPIO32, GPIO33, GPIO34, тощо).
10.1. Обмеження ESP32
- ADC2 під час Wi-Fi: Аналогові входи ADC2 (пов'язані з GPIO0, 2, 4, 12-15, 25-27) неможливо використовувати під час активності Wi-Fi.
- Піни під час завантаження: GPIO0, GPIO2 і GPIO12 мають спеціальні функції під час завантаження і повинні мати певні рівні сигналу для нормального запуску.
- Обмеження вхідних пінів: GPIO34-GPIO39 можуть використовуватися тільки як входи і не мають внутрішніх підтягувальних резисторів.
- Обмеження Flash: Піни GPIO6-GPIO11 використовуються для підключення Flash-пам'яті і не доступні для використання.
11. Корисні поради та рекомендації
11.1. Оптимізація споживання енергії
- Відключення невикористовуваних модулів: Якщо не використовуєте Wi-Fi або Bluetooth, вимкніть їх для зменшення споживання енергії.
- Зменшення частоти процесора: Використовуйте
setCpuFrequencyMhz(80)
для зменшення тактової частоти, коли не потрібна повна потужність.
- Легкий сон: Використовуйте
esp_light_sleep_start()
замість глибокого сну, коли потрібно швидко "прокинутися" без перезавантаження.
- Оптимізація циклів: Уникайте busy waiting та використовуйте події та таймери замість регулярних перевірок.
11.2. Стабільність та надійність
- Запобігання перезавантаженням: Використовуйте конденсатор великої ємності (100-220 мкФ) між 3.3В та GND для стабілізації живлення.
- Watchdog Timer: Налаштуйте сторожовий таймер для автоматичного відновлення у випадку зависання.
- Збереження даних: Регулярно зберігайте критичні дані в NVS (Non-Volatile Storage) або SPIFFS.
- Контроль баферів: Перевіряйте наявність вільної пам'яті перед операціями з великими буферами за допомогою
ESP.getFreeHeap()
.
- Уникнення довгих блокувань: Вибирайте неблокуючі алгоритми для збереження респонсивності системи.
11.3. Робота з Wi-Fi та Bluetooth
- Перевірка з'єднання: Регулярно перевіряйте стан Wi-Fi з'єднання та виконуйте перепідключення при необхідності.
- Обробка подій: Використовуйте обробники подій Wi-Fi (WiFi.onEvent()) замість постійних перевірок стану.
- Енергозбереження: Використовуйте Wi-Fi в автоматичному режимі енергозбереження (WIFI_PS_MODEM).
- Підтримка одного інтерфейсу: Якщо можливо, використовуйте або Wi-Fi, або Bluetooth одночасно, що покращує стабільність і зменшує споживання.
При розробці IoT-пристроїв з ESP32 завжди плануйте механізми віддаленого оновлення прошивки (OTA) та відновлення при збоях. Це значно спростить підтримку пристроїв у польових умовах.
12. Практичні застосування ESP32
12.1. Розумний будинок
- Контролери розумного дому: Керування освітленням, опаленням, кондиціонуванням за допомогою реле та датчиків.
- Моніторинг енергоспоживання: Підключення до лічильників електроенергії через оптичні або імпульсні входи.
- Системи безпеки: Керування сенсорами руху, дверними/віконними датчиками, камерами спостереження.
- Системи автоматичного поливу: Керування клапанами з урахуванням вологості ґрунту та прогнозу погоди.
12.2. Промислова автоматизація
- Моніторинг обладнання: Збір даних з промислових датчиків та передача їх на сервер або хмару.
- Локальні шлюзи: Перетворення даних між різними протоколами (Modbus, I2C, SPI, RS-485) та Ethernet/Wi-Fi мережами.
- Прогнозоване обслуговування: Аналіз даних з датчиків вібрації, температури для передбачення збоїв.
12.3. Системи моніторингу
- Метеостанції: Підключення датчиків температури, вологості, тиску та вітру з відправкою даних в інтернет.
- Моніторинг якості повітря: Збір даних про концентрацію CO2, PM2.5, PM10 та інших забруднювачів.
- Інтернет-логгери: Запис показників датчиків з підтримкою точного часу через NTP.
flowchart TD
ESP32[ESP-WROOM-32] --> Sensors["Сенсори
(DHT22, BMP280, etc.)"]
ESP32 --> Actuators["Виконавчі пристрої
(Реле, Мотори)"]
ESP32 --> Display["Дисплеї
(OLED, TFT)"]
ESP32 --> |"Wi-Fi
Bluetooth"| Connectivity{"Підключення"}
Connectivity --> |"Local"| LocalDevices["Локальні пристрої
(Смартфон, ПК)"]
Connectivity --> |"Internet"| Cloud["Хмарні сервіси
(AWS IoT, ThingSpeak)"]
Cloud --> Dashboard["Веб-дашборди
Мобільні додатки"]
classDef esp32 fill:#f96,stroke:#333,stroke-width:2px
classDef devices fill:#9cf,stroke:#333,stroke-width:2px
classDef cloud fill:#f9f,stroke:#333,stroke-width:2px
class ESP32 esp32
class Sensors,Actuators,Display,LocalDevices devices
class Cloud,Dashboard cloud
13. Усунення типових проблем
13.1. Проблеми при завантаженні
Проблема |
Можливі причини |
Вирішення |
Помилка "Connecting..." |
Плата не в режимі завантаження |
Утримуйте кнопку BOOT, натисніть і відпустіть EN, потім відпустіть BOOT |
Помилка "A fatal error occurred: Failed to connect to ESP32" |
Проблеми з драйвером або підключенням |
Перевірте кабель, встановіть/переінсталюйте драйвери CP2102 |
Помилка компіляції з Arduino.h |
Неправильно вибрана плата |
Переконайтеся, що вибрано ESP32 в налаштуваннях проєкту |
Помилка "Brownout detector" |
Недостатнє живлення |
Використовуйте якісний кабель, інший USB-порт або зовнішнє живлення через VIN |
13.2. Проблеми з Wi-Fi
Проблема |
Можливі причини |
Вирішення |
Непостійне підключення |
Слабкий сигнал або нестабільне живлення |
Перемістіть ближче до точки доступу, перевірте живлення |
Wi-Fi не підключається |
Неправильні дані або несумісність |
Перевірте SSID та пароль, спробуйте підключитися до іншої мережі |
Повільне підключення |
Конфлікт з Bluetooth або перевантаження |
Вимкніть Bluetooth, якщо він не використовується |
Проблеми з підключенням до деяких мереж |
Обмеження корпоративного Wi-Fi |
Використовуйте WPA2 Personal або створіть власну точку доступу |
13.3. Проблеми зі стабільністю
- Випадкові перезавантаження: Зменшіть частоту процесора, перевірте живлення, уникайте доступу до неініціалізованої пам'яті.
- Витоки пам'яті: Уникайте динамічного виділення пам'яті в основному циклі, перевіряйте доступну пам'ять з
ESP.getFreeHeap()
.
- Невідповідність з датчиками і периферією: Переконайтеся, що використовуєте правильний рівень напруги (ESP32 працює з 3.3В).
- Патерни скидань: Використовуйте сторожовий таймер ESP32 для відновлення при збоях.
14. Корисні бібліотеки та інструменти
14.1. Бібліотеки ESP32 для PlatformIO
- AsyncTCP і ESPAsyncWebServer: Для створення асинхронних веб-серверів з ефективним використанням ресурсів.
- ArduinoJson: Для обробки JSON-даних при взаємодії з API та веб-сервісами.
- WiFiManager: Спрощує налаштування Wi-Fi через веб-інтерфейс.
- PubSubClient: Для роботи з MQTT-протоколом для I