MotorStep V8 — Документация

Система управления поворотным столом · ESP32-C3 Mini · Wi-Fi AP + Web UI

1. Назначение

MotorStep V8 — прошивка для управления поворотным столом на шаговом моторе через драйвер TB6600. Предназначена для производственных задач, где требуется:

  • Точное позиционирование стола в диапазоне 0…360°
  • Плавное движение (трапециевидный профиль скорости) для тяжёлых столов (50–1500 кг)
  • Автоматический поиск нуля (концевик) при старте
  • Ручное управление через энкодер HW-040 и кнопки
  • Внешнее управление через Serial (Console) и Wi-Fi (Web UI)
  • Обратная связь по углу с оптического энкодера MBL3806
Архитектура V8: 8 независимых классов (Display, Buttons, EncoderHW040, Settings, Position, Motor, Console, WebUI), связанных через главный файл MotorStep_v8.ino. Классы не знают друг о друге — только через main.

2. Возможности V8

🌐 Wi-Fi AP

ESP32 создаёт сеть MotorStep_V8 / newpribor. Управление с телефона/ПК.

🖥️ Web UI

Полноценный интерфейс: управление, индикация, настройки плавности, лог событий.

📡 WebSocket

Живая передача данных через JSON-статус раз в секунду. Реальное время.

🎯 Точность

0.1° по MBL3806 (24000 импульсов на оборот стола при GEAR_RATIO=10).

⚡ Плавность

Трапециевидный профиль: разгон, плато, торможение. Настройка через Web/Console.

🏠 Автопоиск нуля

4 этапа + пауза 1 сек. Защита по углу (405°). Концевик обязателен.

🛑 Мгновенный stop

Остановка за один шаг (≤800 мкс). Без инерции, без «догонов».

📟 Дисплей TM1637

3 значения: цель, угол стола, MBL3806. Режимы d1/d2. Индикация Run, EROR, BLOC/OFF.

💾 NVS-память

Сохранение шага, флага findHome, accel/cruise/start в энергонезависимую память.

🔄 Двойной протокол

Один обработчик команд для Serial и WebSocket. Управление с обоих каналов одновременно.

🎛️ Инверсия MBL

Переключение направления через #define POSITION_INVERTED — без перепайки.

🔌 Модульность

Замена любого класса (например, Display на LCD) не требует изменений в других.

3. Подключение элементов

3.1. Карта пинов

GPIO Функция Что подключено Примечание
0EncoderHW040 CLKHW-040 CLKISR, CHANGE
1EncoderHW040 DTHW-040 DTISR, CHANGE
2Кнопка дисплеяКнопка (на GND)Strapping — свой опрос
3EncoderHW040 SWHW-040 SWGyverButton
4TM1637 CLKДисплей TM1637—
5TM1637 DIOДисплей TM1637—
6TB6600 STEPTB6600 PUL+Импульсы шага
7TB6600 DIRTB6600 DIR+Направление
8Концевик HOMEМеханический/индуктивныйINPUT_PULLUP, LOW = сработал
9Резерв—Свободен
10TB6600 ENATB6600 ENA+LOW = мотор включён
20MBL3806 AMBL3806 AUART0 RX — 1 кОм, INPUT_PULLUP
21MBL3806 BMBL3806 BUART0 TX — 1 кОм, INPUT_PULLUP
Внимание! GPIO 20 и 21 — это UART0 (RX/TX). В V8 Serial для Console использует USB CDC (виртуальный порт), который не занимает GPIO 20/21. Поэтому MBL3806 работает на этих пинах без конфликтов.

3.2. Схема соединений

TB6600 (драйвер шагового мотора)

ESP32-C3           TB6600
─────────────────────────────
GPIO 6  ──── 1кОм ──── PUL+ (STEP)
GPIO 7  ──── 1кОм ──── DIR+
GPIO 10 ──── 1кОм ──── ENA+
GND     ────────────── PUL- / DIR- / ENA- (общий)

MBL3806 (оптический энкодер на моторе)

ESP32-C3           MBL3806
─────────────────────────────
+5V     ────────────── VCC (красный)
GND     ────────────── GND (чёрный)
GPIO 20 ──── 1кОм ──── A (зелёный)
GPIO 21 ──── 1кОм ──── B (белый)
Важно: MBL3806 — с открытым коллектором (NPN). Подтяжка к 3.3 В — внутренняя (INPUT_PULLUP). Резистор 1 кОм в линии A/B защищает GPIO. Питание MBL3806 — строго 5 В.

HW-040 (энкодер ручного управления)

ESP32-C3           HW-040
─────────────────────────────
+3.3V   ────────────── VCC
GND     ────────────── GND
GPIO 0  ────────────── CLK
GPIO 1  ────────────── DT
GPIO 3  ────────────── SW (кнопка)

TM1637 (дисплей)

ESP32-C3           TM1637
─────────────────────────────
+5V     ────────────── VCC
GND     ────────────── GND
GPIO 4  ────────────── CLK
GPIO 5  ────────────── DIO

Кнопка дисплея

ESP32-C3
─────────────────────────────
GPIO 2 ──[Кнопка]── GND

Концевик HOME

ESP32-C3
─────────────────────────────
GPIO 8 ──[Концевик NO]── GND

При срабатывании замыкается на GND → LOW. В покое — HIGH (INPUT_PULLUP).

3.3. Питание

ПотребительНапряжениеТокИсточник
ESP32-C3 Mini5 В (USB)~250 мАUSB или БП
TB6600 (логика)5 В~20 мАБП 5 В
TB6600 (мотор)24–48 Вдо 3 АОтдельный БП
MBL38065 В~50 мАБП 5 В
TM16375 В~30 мАБП 5 В
HW-0403.3 В~5 мАESP32
Общий GND обязателен! GND всех устройств (ESP32, TB6600, MBL3806, TM1637, БП) должны быть соединены.

4. Настройки

4.1. Пины и механика (в коде)

Пины — в соответствующих .cpp файлах классов

КлассФайлЧто настраивается
DisplayDisplay.cppPIN_CLK_DISP=4, PIN_DIO_DISP=5
ButtonsButtons.cppPIN_ENC_SW=3, PIN_DISP_BTN=2, PIN_HOME=8
EncoderHW040EncoderHW040.cppPIN_ENC_CLK=0, PIN_ENC_DT=1
PositionPosition.cppPIN_MBL_A=20, PIN_MBL_B=21
MotorMotor.cppPIN_STEP=6, PIN_DIR=7, PIN_ENA=10
WebUIWebUI.cppHTTP 80, WebSocket 81

Motor.cpp — в начале файла

static const int32_t STEPS_PER_REV = 800;   // шагов мотора на оборот (1/4 микрошаг)
static const float   GEAR_RATIO    = 10.0;  // ← РЕДУКТОР (мотор:стол = 10:1)
static const int32_t ANGLE_MIN = 0;
static const int32_t ANGLE_MAX = 360;
GEAR_RATIO — главный механический параметр. Зависит от производства (1..100). Меняется в коде — перепрошивка.

Position.cpp — инверсия MBL

#define POSITION_INVERTED  0   // 0 = прямой, 1 = инверсный (A/B поменяны)

main — Wi-Fi AP

#define WIFI_SSID  "MotorStep_V8"
#define WIFI_PASS  "newpribor"

4.2. NVS (энергонезависимая память)

Сохраняются в NVS (namespace "motorstep"):

КлючТипДефолтЧто значит
stepint5Текущий шаг (1..360°)
findHomebooltrueИскать ноль при старте
accelint1000Шагов на разгон/торможение
cruiseint800Задержка на плато (мкс) — макс. скорость
startint5000Задержка на старте/стопе (мкс)

Управление — командами accel, cruise, start (с сохранением в NVS).

5. Console (Serial)

Скорость: 115200. Line Ending: Newline или Both NL & CR.

5.1. Команды

КомандаЧто делаетОтвет
move <angle>Перейти к углу (0..360)OK / BUSY
homeПоиск нуляOK
resetСброс позиции в 0OK
holdУдержание/освобождение мотораOK
stopМгновенный стоп (без сбросов)OK
stop!Стоп с ошибкой (мотор освобождён)OK
clearСброс ошибкиOK
nextСледующий шаг (180→90→10→5→1→180)OK
setstep <n>Установить шаг 1..360 (сохр. в NVS)OK
accel <n>Установить accel (сохр. в NVS)OK
cruise <n>Установить cruise (сохр. в NVS)OK
start <n>Установить start (сохр. в NVS)OK
saveСохранить в NVSOK
loadЗагрузить из NVSOK
hb <0|1>Heartbeat вкл/выклOK
helpСписок командOK + help

5.2. Запросы

КомандаОтвет
ready?READY / BUSY
status?IDLE / MOVING
angle?Целевой угол
motor?Угол стола (факт)
mbl?Угол MBL3806
step?Текущий шаг (1..360)
error?OK / ERROR
hold?ON / OFF
hb?ON / OFF
accel? / cruise? / start?Значение параметра

Асинхронные события (ESP → ПК)

СобытиеКогда
DONEМотор завершил движение
READYКонтроллер свободен
HBHeartbeat (если включён)

6. Web UI (Wi-Fi)

6.1. Подключение

  1. Прошейте плату
  2. На телефоне/ПК подключитесь к Wi-Fi: SSID MotorStep_V8, пароль newpribor
  3. Откройте браузер → http://192.168.4.1/
  4. Индикатор ONLINE (зелёный) — соединение установлено
Порты: HTTP — 80, WebSocket — 81. Wi-Fi AP работает параллельно с Serial (Console).

6.2. Блоки интерфейса

📊 Индикатор

ПолеЧто показывает
Задано (крупно)Целевой угол _targetAngle
Факт (энкодер) (крупно)Угол MBL3806 position.getAngle()
СтатусГОТОВ / ДВИЖЕНИЕ
ОшибкаНЕТ / ОШИБКА
УдержаниеДА / НЕТ
ШагТекущий шаг (1..360°)

📏 Шаг

  • ◀ НАЗАД — движение на шаг назад
  • NEXT STEP — переключение шага по циклу 180→90→10→5→1→180
  • ВПЕРЁД ▶ — движение на шаг вперёд
  • В заголовке отображается текущий шаг

🎛️ Управление

  • Поле угла + ПЕРЕЙТИ — переход к заданному углу
  • 🏠 — HOME (поиск нуля)
  • STOP — мгновенная остановка
  • СБРОС — сброс позиции в 0
  • HOLD — удержание/освобождение мотора
  • STOP! — стоп с ошибкой (мотор освобождён)
  • CLEAR — сброс ошибки

⚡ Плавность

  • accel + ПРИМЕНИТЬ — шагов на разгон/торможение
  • cruise + ПРИМЕНИТЬ — задержка на плато (мкс)
  • start + ПРИМЕНИТЬ — задержка на старте/стопе (мкс)
Автосинхронизация: поля плавности автоматически обновляются раз в секунду из JSON-статуса. Изменения через консоль — тоже подтягиваются.

📜 Лог событий

  • Показывает последние 50 сообщений от ESP
  • Синий — отправленные команды (>>)
  • Зелёный — ответы (OK, DONE, READY)
  • Красный — ошибки

7. Кнопки и энкодер

HW-040 SW (кнопка энкодера, GPIO 3)

ДействиеЧто происходит
Короткий кликСмена шага (180→90→10→5→1→180)
Двойной кликУдержание мотора (BLOC / OFF)
Длинное удержаниеСброс позиции. Если ошибка — сброс ошибки

GPIO 2 (кнопка дисплея)

ДействиеЧто происходит
КликПереключение режима дисплея (d1 ↔ d2)

Энкодер HW-040 (вращение)

Вращение накапливает целевой угол. После паузы (1 сек) — мотор плавно едет к цели.

8. Дисплей TM1637

Режимы (переключаются кнопкой GPIO 2)

РежимИндикаторФорматЧто показывает
d1d 1XXXУгол стола (факт мотора)
d2d 2_XXXУгол MBL3806 (с подчёркиванием)

Приоритет отображения

  1. EROR — мигает при ошибке
  2. Run — во время движения мотора
  3. S XX — 1 сек после смены шага
  4. BLOC / OFF — 1 сек после переключения удержания
  5. d1 / d2 — 1 сек после переключения режима
  6. Цель — 1 сек после вращения энкодера
  7. Угол — основное (d1: мотор, d2: MBL)

Специальные сообщения

ТекстЧто значит
RunМотор движется (R большая, u n маленькие)
ERORОшибка (мигает)
S 90Выбран шаг 90°
BLOCМотор удерживается
OFFМотор освобождён
d 1 / d 2Режим дисплея

9. Компиляция

9.1. Плата

ПараметрЗначение
BoardESP32C3 Dev Module
ЧипESP32-C3
ПлатаESP32-C3 Mini V1 (или аналог)

9.2. Библиотеки

Установить через Library Manager (Sketch → Include Library → Manage Libraries):

БиблиотекаАвторДля чего
TM1637DisplayAvishay OrpazДисплей
GyverButtonAlexGyverКнопка энкодера (SW)
WebSocketsMarkus Sattler (Links2004)WebSocket-сервер
WebSockets: при установке убедитесь, что папка называется именно WebSockets (не arduinoWebSockets-master). Arduino IDE ищет по имени папки.
Встроенные (не требуют установки): WiFi.h, WebServer.h — входят в пакет ESP32.

9.3. Настройки Arduino IDE (Tools)

НастройкаЗначениеПочему
BoardESP32C3 Dev ModuleПравильный чип
USB CDC On BootEnabledSerial через USB (Console работает)
CPU Frequency160 MHzСкорость
Flash Size4MB (32Mb)Стандарт
Upload Speed921600Быстрая прошивка
JTAG AdapterDisabledНе занимает GPIO 0-5
USB DFU On BootDisabledНе нужно
USB CDC On Boot = Enabled обязателен! Без него Serial не работает, Console не принимает команды.

9.4. Прошивка

  1. Подключить ESP32-C3 через USB
  2. Выбрать порт в Tools → Port
  3. Нажать Upload (Ctrl+U)
  4. Если не прошивается: зажать BOOT, нажать RESET, отпустить RESET, отпустить BOOT, затем Upload
  5. После прошивки — нажать RESET
Первое подключение: после прошивки ESP32-C3 перезагружается, USB-порт пересоздаётся. Serial Monitor открывать через 2-3 сек.

10. Известные проблемы и особенности

Плавность vs Wi-Fi

Wi-Fi-стек и WebSocket занимают время CPU при каждом вызове. Решение: webui.update() вызывается раз в 20 мс (не каждый loop). Без этого мотор пропускает шаги.

// В loop() main
static uint32_t lastWebUiUpdate = 0;
if (millis() - lastWebUiUpdate > 20) {
  lastWebUiUpdate = millis();
  webui.update();
}

Пропуски энкодера HW-040

Механический энкодер даёт дребезг. Решение: антидребезг 2000 мкс в ISR + REPORT_MIN_INTERVAL_MS = 50 мс. Редкие пропуски возможны.

Двойное срабатывание кнопки GPIO 2

Strapping-пин, дешёвая кнопка. Решение: state machine в Buttons.cpp, антидребезг 50 мс.

Конфликт GPIO 20/21 (UART0)

GPIO 20/21 — UART0 (RX/TX). Serial для Console использует USB CDC (виртуальный COM-порт), не занимает эти пины. Поэтому MBL3806 работает без конфликтов.

Кнопка HW-040 SW на GPIO 3

Strapping-пин (JTAG source). С JTAG Adapter = Disabled работает нормально.

11. Проверено и однозначно не работает

ЧтоРезультатПричина
GyverButton на GPIO 2 НЕ работает GPIO 2 — strapping. Заменено на state machine.
GyverEncoder на ESP32-C3 НЕ работает Библиотека под AVR/ESP8266. Заменено на собственный ISR-декодер.
Точка на TM1637 НЕ работает Библиотека не выводит точку корректно. Заменено на _ перед числом для MBL.
PROGRESS каждые 1° НЕ работает плавно Serial блокирует loop → рывки. Отключено.
webui.update() каждый loop НЕ работает плавно Wi-Fi стек ест время. Вызывать раз в 20 мс.
GPIO 0, 1 при загрузке Осторожно HW-040 CLK/DT. Если крутить при загрузке — может помешать.
GPIO 8 при загрузке Осторожно Концевик HOME. Должен быть HIGH (разомкнут) при загрузке.
GPIO 9 при загрузке ОК Strapping (BOOT). Не используется.

12. Состав проекта

MotorStep_v8/
├── MotorStep_v8.ino       ← main (дирижёр)
├── Display.h  / Display.cpp        ← TM1637
├── Buttons.h  / Buttons.cpp        ← HW-040 SW + GPIO 2 + концевик
├── EncoderHW040.h / EncoderHW040.cpp ← HW-040 (ISR-декодер)
├── Settings.h / Settings.cpp       ← NVS
├── Position.h / Position.cpp       ← MBL3806
├── Motor.h    / Motor.cpp          ← шаговый мотор
├── Console.h  / Console.cpp        ← Serial-протокол
└── WebUI.h    / WebUI.cpp          ← Wi-Fi AP + HTTP + WebSocket

Зависимости

Классы не знают друг о друге. Все связи — через main:

main → motor.moveTo(angle)
main → display.setMotorAngle()
main → settings.getStep()
main → position.getAngle()
main → console.sendDone()
main → webui.sendFullStatus()
Архитектура V8: каждый класс — независимый модуль. Замена одного класса не требует изменений в других.

13. История версий

ВерсияЧто нового
V6 • Классовая архитектура (7 классов)
• Console (Serial-протокол)
• NVS (Settings)
• GEAR_RATIO
• Индикация d1/d2, Run, EROR
• findHome с 4 этапами
V8 • WebUI (Wi-Fi AP + HTTP + WebSocket)
• JSON-статус раз в 1 сек
• Web-интерфейс с управлением и индикацией
• Поля плавности в Web (авто-обновление)
• webui.update() раз в 20 мс (ключ к плавности)
• Шаг как число (1..360), команда setstep
• findHome — пауза 1 сек после отхода
• stop — без сбросов, возврат к старому нулю
• STOP! при концевике вне 0/360
• Новый дизайн Web UI