[SLOT_n] ;доступные слоты: 0-5
mode = stepper

Программный модуль управления шаговым двигателем сигналами step-dir через драйвер.

Совместимость

Сигнал DIR выводится на канал ch_0 слота, STEP — на ch_1. Концевые датчики и датчик нуля подключаются к другим слотам (например in_2ch) и передают состояние командами setHomingSensor, setUpLimit и setDownLimit через crossLink.

Ограничения по периферии

Импульсы step генерирует MCPWM, а положение считает PCNT — обе периферии в ESP32-S3 ограничены:

  • MCPWM — три таймера, поэтому одновременно работает не более трёх моторов stepper;
  • PCNT — четыре счётчика, и они делятся между stepper, encoderInc и tachometer. Суммарно этих модулей в конфигурации может быть не больше четырёх.

Если периферии не хватило, модуль в этом слоте не запускается: в консоль и лог на SD-карте пишется ошибка, а после подключения к брокеру публикуется событие stepper_<slot>/event/warning с текстом причины (init failed, no free MCPWM timer (max 3 steppers) или init failed, no free PCNT unit ...). Остальные слоты продолжают работать.

Принцип работы

Модуль формирует импульсы step с трапецеидальным профилем скорости: разгон и торможение идут с ускорением accel, максимальная скорость ограничена опцией maxSpeed. Длительность импульса и стартовая скорость трапеции вычисляются автоматически из maxSpeed.

Базирование. Если задано направление homingDir, модуль ищет датчик нуля — при старте (флаг goHomeOnStart) или по команде goHome. С флагом goHomeOnStart процедура начинается через 2 секунды после запуска: слоты стартуют одновременно, и за это время датчик нуля и концевики успевают передать своё состояние по crossLink — иначе мотор, стоящий на датчике, поехал бы не в ту сторону. Во время паузы команды принимаются как обычно, движение откладывается в очередь (см. ниже). Процедура идёт со скоростью homingSpeed: если датчик уже активен — мотор сначала съезжает с него, затем возвращается; в момент срабатывания датчика позиция обнуляется, мотор тормозит по трапеции, homingState становится done. Во время базирования программные и аппаратные лимиты не действуют.

Пока ось не базирована (homingState = waitingCommand), команды движения moveToAbs, moveToInc, runSpeed, setMaxSpeed и setAccel игнорируются, а в event/warning публикуется command ignored, motor is not homed. Так же ведёт себя ось после отмены базирования командами stop, break или enable 0. Флаг allowUnhomed снимает этот запрет: команды исполняются, координаты отсчитываются от положения при включении.

Команды движения, пришедшие во время базирования, не теряются: они копятся в очереди (до 8 штук) и исполняются по порядку сразу после done.

Таймаут базирования. Если датчик не найден за homingTimeout секунд, homingState становится homingTimeout, мотор останавливается, накопленная очередь сбрасывается. Без флага allowUnhomed модуль уходит в режим ожидания: любые команды движения игнорируются (event/warning: command ignored, homing timeout, send goHome), принимаются только goHome, enable и обновления датчиков; светодиод DIR при этом мигает с периодом 1 с — так режим видно снаружи. Выход — повторная команда goHome. С флагом allowUnhomed ось просто остаётся небазированной и продолжает принимать команды.

Ограничения хода. Программно ход ограничивается опциями minVal и maxVal: цель moveToAbs/moveToInc обрезается по границам, а в режиме runSpeed мотор заранее начинает торможение и плавно встаёт на границе. Аппаратно ход ограничивают команды setUpLimit и setDownLimit от концевых датчиков: 1 запрещает движение в соответствующую сторону и немедленно останавливает мотор, если он туда едет; из-под концевика всегда можно уехать в обратную сторону. В режиме circularCounter программные границы не действуют, позиция зацикливается в диапазоне minVal–maxVal, а moveToAbs идёт к цели кратчайшим путём (нужно maxVal > minVal).

Положение, скорость и состояние рапортуются при включённых флагах posReport, speedReport и stateReport — при старте и далее при каждом изменении, не чаще refreshRate раз в секунду.

Топики

База топика события:

  • <deviceName>/stepper_<slot> — например moduleBox/stepper_0

База топика действия:

  • <deviceName>/stepper_<slot> — например moduleBox/stepper_0

Полный топик — база плюс направление и имя: moduleBox/stepper_0/event/pos.

Опции

Доступные опции:

  • disableOnStart — флаг, стартовать в выключенном состоянии и ждать action/enable со значением 1. По умолчанию модуль активен сразу.
  • dirInverse — флаг, инверсия направления вращения.
  • posReport — флаг, включить рапорты положения.
  • circularCounter — флаг, режим кругового счётчика: положение зацикливается между minVal и maxVal, ограничение хода отключено.
  • goHomeOnStart — флаг, базировать при старте (через 2 с — пауза на сбор состояний датчиков), иначе ждать команду goHome.
  • allowUnhomed — флаг, разрешить движение без базирования: команды движения исполняются, даже если ноль не найден; координаты отсчитываются от положения при включении. Без флага небазированная ось игнорирует команды движения.
  • speedReport — флаг, включить рапорты скорости.
  • stateReport — флаг, включить рапорты состояния.
  • homingDir — строка(enum), направление базирования. Значения: up, down. По умолчанию базирование выключено.
  • accel — число(int), ускорение и замедление в . Диапазон 1–2147483647. По умолчанию 100.
  • maxSpeed — число(int), максимальная скорость в . Диапазон 1–2147483647. По умолчанию 100.
  • refreshRate — число(int), частота обновления в Гц. Диапазон 1–100. По умолчанию 20.
  • homingSpeed — число(int), скорость базирования в . Диапазон 1–2147483647. По умолчанию четверть от maxSpeed.
  • homingTimeout — число(int), таймаут базирования в , 0 отключает. По умолчанию 30.
  • maxVal — число(int), максимальное положение в шагах — программное ограничение хода. Диапазон -2147483648–2147483647. По умолчанию ограничение снято.
  • minVal — число(int), минимальное положение в шагах — программное ограничение хода. Диапазон -2147483648–2147483647. По умолчанию ограничение снято.

События

ТопикPayloadОписание
stepper_<slot>/event/posцелое, Текущее положение в шагах
stepper_<slot>/event/speedцелое, Текущая скорость в шаг-сек
stepper_<slot>/event/stateстрокаСостояние мотора: run, stop, maxVal, minVal, upLimit или downLimit
stepper_<slot>/event/homingStateстрокаСостояние базирования: disable, waitingCommand, homing, done или homingTimeout
stepper_<slot>/event/warningстрокаПредупреждение — текст причины: команда проигнорирована или модуль не запустился
stepper_<slot>/event/enable0 / 1Состояние модуля - активен 1 или спит 0

Пример: топик moduleBox/stepper_0/event/pos, payload 1200.

Значения event/state: run/stop — мотор едет/стоит; maxVal/minVal — стоит на программной границе; upLimit/downLimit — активен концевой датчик. Аппаратный лимит имеет приоритет над программной границей.

Тексты event/warning:

  • command ignored, motor is not homed — ось не базирована, команда движения отброшена;
  • command ignored, homing timeout, send goHome — базирование не удалось, модуль ждёт goHome;
  • command ignored, homing in progress, deferred queue full — во время базирования пришло больше 8 команд движения;
  • init failed, no free MCPWM timer (max 3 steppers) — в конфигурации больше трёх моторов;
  • init failed, no free PCNT unit (4 total for encoderInc, tachometer, stepper) — не хватило счётчиков PCNT.

Одинаковое предупреждение публикуется не чаще раза в секунду.

Команды

ТопикPayloadОписание
stepper_<slot>/action/goHome—Запустить базирование
stepper_<slot>/action/moveToAbsцелое, Перейти в абсолютную позицию
stepper_<slot>/action/moveToIncцелое, Сместиться на приращение
stepper_<slot>/action/runSpeedцелое, Вращать с заданной скоростью, знак задаёт направление
stepper_<slot>/action/setMaxSpeedцелое, Установить максимальную скорость
stepper_<slot>/action/setAccelцелое, Установить ускорение
stepper_<slot>/action/stop—Экстренная остановка; прерывает базирование
stepper_<slot>/action/break—Остановка с торможением; прерывает базирование
stepper_<slot>/action/setHomingSensor0 / 1Состояние датчика нуля — передаётся из слота, к которому он подключён
stepper_<slot>/action/setUpLimit0 / 1Аппаратный лимит хода вверх: 1 запрещает движение в плюс
stepper_<slot>/action/setDownLimit0 / 1Аппаратный лимит хода вниз: 1 запрещает движение в минус
stepper_<slot>/action/enable0 / 1Включить (1) или выключить (0) модуль; выключение — экстренная остановка

Пример: топик moduleBox/stepper_0/action/moveToAbs, payload 1200.

Примеры

[SLOT_0]
mode = stepper
options = maxSpeed:5000, accel:5000, homingDir:down, goHomeOnStart, posReport, stateReport
 
[SLOT_1]
mode = in_2ch
;датчик нуля на входе 0 слота 1 передаёт своё состояние мотору
crosslink = in_1/event/ch_0:@->stepper_0/action/setHomingSensor:@

Максимальная скорость 5000 шагов в секунду при ускорении 5000 — на разгон уходит секунда. При старте двигатель базируется вниз до датчика нуля, до этого команды движения игнорируются.

[SLOT_2]
mode = stepper
options = maxSpeed:2000, accel:1000, minVal:0, maxVal:8000, allowUnhomed
 
[SLOT_3]
mode = encoderInc
options = absolute, linearCounter, minVal:0, maxVal:8000
;позиция энкодера задаёт целевую позицию двигателя
crosslink = encoder_3/event/val:@->stepper_2/action/moveToAbs:@

Базирование не задано, двигатель отсчитывает координаты от положения при включении и следует за энкодером в пределах 0–8000 шагов.

[SLOT_4]
mode = stepper
options = maxSpeed:3000, accel:2000, homingDir:up, stateReport
 
[SLOT_5]
mode = in_2ch
;верхний концевик - вход 0, нижний - вход 1
crosslink = in_5/event/ch_0:@->stepper_4/action/setUpLimit:@, in_5/event/ch_1:@->stepper_4/action/setDownLimit:@

Концевые датчики запрещают движение за пределы механики. Базирование запускается по команде goHome; пока её не было, мотор стоит и отвечает на команды движения предупреждением command ignored, motor is not homed.

Подробнее — внутренние связи (crossLink).

Пример подключения