sadr0b0t / stepper_h

Stepper motor control library for ChipKIT/Arduino
GNU Lesser General Public License v3.0
3 stars 1 forks source link

Добавить возможность делать серии с пропуском шагов в prepare_buffered_steps #35

Open sadr0b0t opened 1 week ago

sadr0b0t commented 1 week ago

Сейчас элементы в параметре step_buffer содержат количество шагов для серии - знак элемента в этом же массиве определяет направление вращения. Для ситуаций, когда какие-то моторы должны вращаться, а другие в это же время стоять, может быть удобно не останавливать моторы руками (с prepare_buffered_steps для нескольких моторов это вообще будет морока), а добавить возможность устанавливать холостые циклы, когда таймер будет считать тики, но мотор будет стоять.

Простой вариант (без правки API) - можно задать специальное значение "0" для элемента step_buffer - в таком случае эта пустая серия будет продолжаться столько, сколько времени задано в соответствующем элементе step_delay. Минус в том, что с таким вариантом не получится единообразия с нехолостыми шагами. В каждой серии можно задать несколько нехолостых шагов (знак определит направление), вся нехолостая серия будет продолжаться step_delay[i]*step_buffer[i]. Для пропуска шагов одна серия сможет включить только один холостой шаг.

Другой более "явный" вариант - добавить еще один параметр dir или action, который задаст параметр движения для текущей серии (i-й элемент массива): dir[i]=1 - двигаться вперед, dir[i]=-1 - двигаться обратно, dir[i]=0 - пропустить шаг. Количество шагов step_buffer[i] сделать всегда положительное.

сейчас общее пройденное расстояние в цикле по всем сериям можно посчитать так (движение вперед/назад будет сокращаться благодаря знаку):

dist += m1_distance_per_step*m1_step_buffer[i];

с новым параметром тоже норм (знак будет браться из dir[i], в случае с простоем - слагаемое будет просто обнуляться):

dist += m1_distance_per_step*m1_step_buffer[i]*dir[i];
sadr0b0t commented 6 days ago

ок, делаю отдельный параметр dir_buffer с вариантами направлений 1, -1, 0

основная история разворачивается в stepper_timer.cpp в структуре motor_cycle_info_t

у нее уже есть поле int dir (для текущего цикла) с вариантами значений 1,-1. Заполняется из знака параметра step_count во всех "подготовительных методах", поэтому 0 туда не проблема добавить. Но для серий шагов еще в этой же структуре держу массив long* step_buffer (каждый элемент - знаковый step_count, из которого при переходе на каждую новую серию задаётся dir). Значит нужно для серий шагов завести еще такой же массив рядом и проследить, чтобы при переходе на новую серию знак брался из него.

Вообще, step_count знаковый - параметр почти во всех методах. Нужно сделать его беззнаковым, везде добавить вместо него (знака) параметр dir и почистить участки, которые со знаком step_count обращались.

Код получится посогласованнее и логичнее местами. К примеру, step_counter (обратный счетчик) беззнаковый, но взводится на изначальное значение через знаковый step_count.

_cstatuses[sm_i].step_counter = _cstatuses[sm_i].step_count;

Плюс в некоторых местах после того, как беру знак из step_count, привожу его к неотрицательному виду

    long step_count = _cstatuses[sm_i].step_buffer[0];
    // сделать step_count положительным
    _cstatuses[sm_i].step_count = step_count > 0 ? step_count : -step_count;

Это всё лишние хаки только из-за того, что когда-то решил направление вращения таскать не отдельным параметром, а знаком (типа так элегантнее). Теперь это всё лишнее можно удалить.

Коменты тоже навести ревизию. Например, здесь:

     * для 32-битного знакового целого:
     * макс расстояние за серию=
     *   (2^31)*1мкм=2147483648мкм=2147483мм=2147м=2км
     * макс время при движении с макс скоростью=
     *   (2^31)*10мкс=2147483648*10мкс=21474836480мкс=21474сек=358мин=6ч
     * 
     * для 16-битного знакового целого:
     * макс расстояние за серию=
     *   (2^15)*1мкм=32768мкм=32мм=3см - ни о чем
     * макс время при движении с макс скоростью=
     *   (2^15)*10мкс=32768*10мкс=327680мкс=328млс=0.3сек - ни о чем

Здесь расчеты для знакового step_count. Нужно пересчитать для беззнакового.

sadr0b0t commented 6 days ago

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

В текущем виде:

В принципе, вроде этого достаточно - вполне исчерпывающе, но в коментах (или даже в названиях переменных) может быть не всегда так. Например, если у мотора для текущего цикла подготовлена единственная серия, могу называть эту серию просто циклом (а про серии говорить только тогда, когда несколько серий в буфере). Или, может, сам массив серий называть серией. Или серию внутри массива серий называть циклом. Серию подсерией, серию - подциклом. И т.п. Может, буду стараться приводить всё к одному виду по мере того, как буду подмечать.

sadr0b0t commented 6 days ago

переименовал: cycle_count -> series_count cycle_counter -> series_counter

и поправил коменты рядом

sadr0b0t commented 4 days ago

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

long steps_x = (150000000 - sm_x.current_pos) / 7500;

сейчас придется городить огород с выделением знака в отдельную переменную

prepare_steps(&sm_x, steps_x > 0 ? steps_x : -steps_x, steps_x > 0 ? 1 : -1, delay_x);
sadr0b0t commented 3 days ago

Вынес направление в отдельный параметр https://github.com/sadr0b0t/stepper_h/commit/a13f802db35dcb09cb1dbbadf0724ac14383b675

тесты ок. апи поломано (совместимость). Пропуск шагов с dir=0 не реализовано, но теперь это можно сделать аккуратно без поломки апи.