# MKS SERVO42C Arduino Library 

Легкая библиотека для управления умными шаговыми моторами MKS SERVO42C через интерфейс RS485/UART. Поддерживает чтение высокоточного энкодера (16 бит) и управление движением в реальном времени.
🚀 Основные возможности

    Движение: Поворот на заданный угол, бесконечное вращение, мгновенная остановка.

    Обратная связь: Чтение текущего угла (0-360°) и абсолютной позиции (с учетом полных оборотов).

    Умный статус: Отслеживание завершения движения (isBusy) через анализ данных энкодера.

🛠 Описание функций (API)
Конструктор

MKS42C(HardwareSerial& serial, uint8_t address = 0xE0);

    serial: Ссылка на аппаратный Serial (например, Serial2 для ESP32).

    address: CAN/RS485 адрес мотора (по умолчанию 0xE0).

Управление движением
void setEnable(bool state);

Включает (true) или выключает (false) ток в обмотках. При false вал можно вращать рукой, при true мотор удерживает позицию.
void run(int16_t speed);

Самый удобный способ вращения. * Передавай положительное значение (например, 40) для вращения по часовой стрелке.

    Передавай отрицательное значение (например, -40) для вращения против часовой стрелки.

    Диапазон скорости: от -127 до 127.

void rotateDegrees(float degrees, uint8_t speed);

Поворот на точный угол относительно текущей позиции.

    degrees: Угол (например, 90.0 или -720.0).

    speed: Скорость движения (1-127).

void stop();

Мгновенная программная остановка мотора.
Чтение данных
float readPosition();

Возвращает текущий угол вала в диапазоне 0.00° ... 359.99°.

    Если возвращает -1.0, значит возникла ошибка связи (CRC или таймаут).

long readAbsolutePosition();

Возвращает общее количество импульсов энкодера с момента включения.

    1 оборот = 65536 единиц.

    Значение может быть отрицательным. Это лучший способ отслеживать пройденный путь.

bool isBusy();

Проверяет, движется ли мотор.

    Библиотека анализирует пакеты статуса от мотора и изменение данных энкодера.

    Возвращает true, если вал еще вращается.

📐 Формулы для ручного управления

Если ты хочешь реализовать свою логику в основном коде:

    Градусы в импульсы: Pulses=360Degrees×65536​

    Импульсы в градусы: Degrees=65536Pulses×360​

📋 Пример: Возврат в абсолютный ноль

Этот код заставляет мотор крутиться в сторону «нулевой» точки, пока он ее не достигнет.
C++

void backToZero() {
  long currentPos = motor.readAbsolutePosition();
  
  // Выбираем скорость: если мы в плюсе, едем назад (-40), если в минусе — вперед (40)
  int16_t speed = (currentPos > 0) ? -40 : 40;
  motor.run(speed);

  while (true) {
    currentPos = motor.readAbsolutePosition();
    // Останавливаемся, когда пересекли ноль или подошли очень близко
    if (speed < 0 && currentPos <= 10) break;
    if (speed > 0 && currentPos >= -10) break;
    delay(10);
  }
  motor.stop();
}

⚠️ Важные замечания

    Общая земля: Обязательно соедини GND контроллера и GND драйвера мотора.

    Скорость UART: Убедись, что в коде Serial.begin(38400) и в настройках на экране мотора скорость совпадает.

    Резисторы: Для длинных линий UART (более 1 метра) рекомендуется использовать подтягивающие резисторы или модули RS485