Files
2026-10-27 17:47:54 +03:00

129 lines
6.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Регулятор громкости на ESP32
Регулятор крутит потенциометр громкости сервоприводом. Управлять им можно двумя способами: поворотом энкодера и через веб-интерфейс по Wi‑Fi. Кнопка энкодера включает и выключает питание через реле. Громкость и состояние реле видны на TFT-дисплее.
Прошивка написана на Arduino + FreeRTOS (PlatformIO, плата `esp32dev`).
## Подключение
### Энкодер (например, KY-040)
| Вывод энкодера | GPIO ESP32 | Примечание |
|---|---|---|
| CLK (A) | **32** | внутренняя подтяжка к 3.3 В |
| DT (B) | **33** | внутренняя подтяжка к 3.3 В |
| SW (кнопка) | **25** | активный уровень LOW, подтяжка к 3.3 В |
| + | 3.3V | |
| GND | GND | |
### Сервопривод
| Вывод серво | Подключение | Примечание |
|---|---|---|
| Сигнал (оранжевый/жёлтый) | **GPIO 13** | ШИМ 50 Гц, 500–2400 мкс |
| + (красный) | 5 В от отдельного источника | не от 3.3V ESP32 |
| GND (коричневый) | GND | общий с ESP32 |
### Реле
| Вывод модуля реле | Подключение | Примечание |
|---|---|---|
| IN | **GPIO 26** | уровень включения задаётся `RELAY_ACTIVE_LEVEL` |
| VCC | 5V / 3.3V (по модулю) | |
| GND | GND | |
### TFT-дисплей ILI9341 (240×320, SPI)
| Вывод дисплея | GPIO ESP32 |
|---|---|
| MOSI (SDI) | **23** |
| MISO (SDO) | **19** |
| SCK | **18** |
| CS | **5** |
| DC (RS) | **21** |
| RESET | **15** |
| LED (подсветка) | **22** |
| T_CS (тачскрин) | **4** |
| VCC | 3.3V |
| GND | GND |
Сенсор XPT2046 подключается к той же шине SPI: T_DIN к MOSI, T_DO к MISO, T_CLK к SCK, T_CS к GPIO 4. Вывод T_IRQ не нужен.
### Управление с сенсорного экрана
- Кнопки **−** и **+** меняют громкость на 1 %. Если держать кнопку нажатой, громкость меняется непрерывно.
- Тап по **полосе громкости** сразу ставит нужное значение, по полосе можно вести пальцем.
- Плашка **POWER** включает и выключает реле.
**Калибровка.** При первом включении на экране появятся стрелки в углах, нажимайте их по очереди. Калибровка сохраняется в NVS. Чтобы откалибровать заново, держите палец на экране при включении питания.
### Сводная таблица GPIO
| GPIO | Назначение |
|---|---|
| 4 | TFT T_CS |
| 5 | TFT CS |
| 13 | Серво, сигнал |
| 15 | TFT RESET |
| 18 | TFT SCK |
| 19 | TFT MISO |
| 21 | TFT DC |
| 22 | TFT подсветка |
| 23 | TFT MOSI |
| 25 | Энкодер, кнопка SW |
| 26 | Реле IN |
| 32 | Энкодер CLK |
| 33 | Энкодер DT |
Пины энкодера, серво и реле меняются в [include/config.h](include/config.h). Пины дисплея меняются в `build_flags` в [platformio.ini](platformio.ini).
## Настройка
Все параметры находятся в [include/config.h](include/config.h):
| Параметр | Что задаёт |
|---|---|
| `WIFI_SSID`, `WIFI_PASSWORD` | домашняя сеть Wi‑Fi |
| `AP_SSID`, `AP_PASSWORD` | собственная точка доступа. ESP32 включает её, если не смог подключиться к сети за 15 с |
| `MDNS_HOSTNAME` | имя в сети, по умолчанию `http://volume.local` |
| `ENCODER_REVERSE` | `1`, если громкость меняется в обратную сторону |
| `VOLUME_STEP` | шаг громкости за один щелчок энкодера, % |
| `SERVO_MIN_US`, `SERVO_MAX_US` | длительность импульса для 0 % и 100 %. Подберите под ход потенциометра |
| `SERVO_SPEED_US_PER_STEP` | скорость плавного хода серво |
| `RELAY_ACTIVE_LEVEL` | `HIGH` или `LOW`. Многие модули реле включаются уровнем `LOW` |
| `TOUCH_VOLUME_STEP` | шаг громкости для кнопок −/+ на экране, % |
| `TOUCH_REPEAT_DELAY_MS`, `TOUCH_REPEAT_MS` | задержка перед автоповтором при удержании −/+ и его период |
## Сборка и прошивка
```sh
pio run -t upload
pio device monitor
```
После запуска прошивка пишет в монитор порта IP-адрес. Тот же адрес виден в правом верхнем углу дисплея.
## Веб-интерфейс и API
Откройте `http://volume.local` или IP-адрес устройства. На странице есть ползунок громкости, кнопки ±5 и кнопка реле.
| Запрос | Действие |
|---|---|
| `GET /api/state` | вернуть текущее состояние: `{"volume":30,"relay":false}` |
| `POST /api/volume?value=N` | установить громкость 0–100 |
| `POST /api/volume?delta=N` | изменить громкость на N |
| `POST /api/relay?state=toggle\|1\|0` | переключить, включить или выключить реле |
Громкость и состояние реле сохраняются в памяти ESP32 (NVS) и восстанавливаются после перезагрузки.
## Устройство прошивки
| Задача FreeRTOS | Файл | Назначение |
|---|---|---|
| `control` | [src/control_task.cpp](src/control_task.cpp) | управляет серво, реле и сохранением в NVS. Только эта задача работает с этим оборудованием |
| `encoder` | [src/encoder_task.cpp](src/encoder_task.cpp) | опрашивает энкодер и кнопку раз в 1 мс |
| `web` | [src/web_task.cpp](src/web_task.cpp) | подключение к Wi‑Fi, HTTP-сервер, mDNS |
| `display` | [src/display_task.cpp](src/display_task.cpp) | выводит состояние на TFT, обрабатывает касания |
Энкодер, сенсорный экран и веб-интерфейс отправляют команды в общую очередь, а задача `control` их выполняет. Текущее состояние хранится в общей переменной, защищённой мьютексом.