A3949 подходит, если ток мотора не превышает максимальный ток драйвера.
В общем случае я вижу следующие проблемы:
0) В двигателе есть собственная обратная связь через коллектор, и её отменить нельзя. Это выливается в то что двигатель крутится пока есть ток., если тока нет, двигатель может крутиться по инерции, или под действием внешних сил, и удерживать его на одном месте как шаговый практически невозможно, но можно включить режим тормоза, закоротив двигатель через землю.
1) Зависимость "ШИМ - скорость" двигателя не линейная
2) Для того чтобы стронуть двигатель с места нужно подать больше тока, чем поддерживать движение.
3)
byte motor_speed = 0;
int distance = abs(position-target);
if (distance > 255)
motor_speed = 255;
else
motor_speed = distance;
этот код задаёт ШИМ на основе ошибки abs(position-target), т.е. сам алгоритм подразумевает что всё время есть ошибка.
Рассмотрим пример, я с проблемой точного управления много работал когда делал pid для своего бесколлекторного двигателя.
для того чтобы сдвинуть двигатель с места нужно подать шим 30%, для того чтобы он дальше крутился на малых оборотах тостаточно ШИМ 8-10%
и того, самый плохой вариант.
если твой двигатель стоит то он не стронется с места пока не набежит ошибка в 30 шагов.
если шаги идут очень редко, то двигатель будет дёргаться , т.к. будет перелетать позицию и опять ждать когда набежит ошибка.
Помочь решить данные проблемы может редуктор с небольшим передаточным числом,
в этом случае, если двигатель выключен то удержание будет происходить за счёт (инерции ротора + магнитное сопротивление) * на передаточное число редуктора
дополнительно, ошибка на валу двигателя будет меньше ошибки на выходном валу редуктора пропорционально передаточному числу.
Дополнительно в программу можно добавить константу в управляющий сигнал, которая будет задавать ШИМ для старта.
Например (точные константы нужно подобрать)
byte motor_speed = 0;
int distance = abs(position-target);
if (distance < 5)
motor_speed = 15+distance;
else
if (distance > 255)
motor_speed = 255;
else
motor_speed = distance;
Надеюсь я тебя не запутал.
Я хотел показать какие сложности возможны при реализации сервомотора.
Добавлено спустя 4 минуты 36 секунд:Тьфу ты
Загнался сорри, конечно удерживать можно, если закоротить выходы двигателя на землю.
Сила удержания будет пропорциональна скорости вращения ротора
Добавлено спустя 8 минут 40 секунд:Проблему с обратным ходом можно решить так:
Дописываем (+ это добавленные строки, сами плюсы в начале не нужны)
....
bool dir = false;
+bool olddir = false;
....
+if (olddir != dir) {
+target=0;
+position=0;
+}
if (!oldStep && newStep)
{
....
oldEnable = newEnable;
+olddir=dir;