129 lines
6.9 KiB
Markdown
129 lines
6.9 KiB
Markdown
# Регулятор громкости на 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` их выполняет. Текущее состояние хранится в общей переменной, защищённой мьютексом.
|