Алгоритм разгона торможения шагового двигателя

roman2712@mail.ru
Offline
Зарегистрирован: 16.01.2014

Здравствуйте коллеги

Может кто знает что можно почитать по теории разгона торможения шаговых двигателей ? (больше интересует именно разгон по квантам времени)

Или может кто то разбирался как это устроено в grbl или marlin ? 

AccelStep и AVR446 не предлагать. Даже с учетом оптимизации адекватно больше 6 - 8 кГц с них не получить...

Моя цель - 30 кГц (судя по пкид это вполне достижимо).

 

roman2712@mail.ru
Offline
Зарегистрирован: 16.01.2014

Моя цель - 30 кГц (судя по grbl это вполне достижимо).

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

roman2712@mail.ru пишет:

Или может кто то разбирался как это устроено в marlin ? 

Я разбирался - не осилил :( Цель не оправдала средства.

roman2712@mail.ru пишет:

Моя цель - 30 кГц (судя по grbl это вполне достижимо).

Что мешает посадить драйвер STEP/DIR, ногой step на какой нить таймерный пин процессора. И крути хоть до 100 кГц, вопрос только в "полезности" такой фигни. Можность двигателя упадет в никуда, его муха лапой запросто остановит. Естественно нужны ускорения и плавность движений:)

roman2712@mail.ru
Offline
Зарегистрирован: 16.01.2014

Со всем уважение, не стоит тролить вопрос задавался не для этого.

Что такое кривая разгона \ торможения я прекрасно знаю

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

Расчет в grbl не очевиден, так как проект разрабатывается уже длительное время и для меня сложно понять как автор сделал декомпозицию кода. Если кто то смог в этом разобраться, прошу помочь найти это в grbl.

Я понимаю, что в grbl считается по квантам времени, с использование колцевого буфера, для хранения информации о частоте \ делители и т.д. Но я не могу найти именно каким образом он определяет точку начало торможения при своих расчетах.

Может кто то математику на эту тему прорабатывал ?  

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

roman2712@mail.ru пишет:

Со всем уважение, не стоит тролить вопрос задавался не для этого.

Что такое кривая разгона \ торможения я прекрасно знаю

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

Расчет в grbl не очевиден, так как проект разрабатывается уже длительное время и для меня сложно понять как автор сделал декомпозицию кода. Если кто то смог в этом разобраться, прошу помочь найти это в grbl.

Я понимаю, что в grbl считается по квантам времени, с использование колцевого буфера, для хранения информации о частоте \ делители и т.д. Но я не могу найти именно каким образом он определяет точку начало торможения при своих расчетах.

Может кто то математику на эту тему прорабатывал ?  

Где кого и что я тут потролил ? Я конкретно ответил на вопрос. А вот четыре одинаковых поста, это что ?

Что сложного для понимания вы углядели ? Разве только реализацию. О какой "теории" тут вопрос. Эта теория известна их седьмого класса общеобразовательной школы. Cм формулы скорости и ускорения. Для удобства заменитиь меры длинны на импульсы шага. Скорость шаговика измеряем в шагах за единицу времени. Зная скорость вращения мы можем посчитать количество шагов до остановки при определенном ускорении. Какой именно аспект не понятен ? Мне же не понятно как можно использовать кольцевой буфер при расчетах.... Как его можно использовать для буферизации данных понятно, а как с ним что то считать - НЕТ.

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Так в чем конкретно не понимание то ? Опишите конкретнее момент, кторый не понятен, попробуем всместе подумать.

roman2712@mail.ru
Offline
Зарегистрирован: 16.01.2014

Есть разные подходы к реализации кривой разгона торможения (рампы скорости) для шагового двигателя. Для себя выделил 3 варианта (принимаем сразу, что у нас есть драйвер ШД, на который подаем DIR, STEP.)

1) S-кривые - сложная математика, не для 16 битных AVR

2) Расчет периода между импульсами на разгоне торможении. Матиматика попроще, также есть упрощенные формулы расчета. Реализацию видел в AccelStepper, описано в avr446 (да и много где в инете). Из неприятного. Для определения точки начала торможения, необходимо знать сколько шагов при текущей скорости мы проедем, при начале торможения, и сравнивать с установленным количеством шагов (как "скорость" понимается количество импульсов в сек). Скорость - величина обратная от периода => еще немного матиматики на каждом шаге. Как итог, так как для матиматики время у нас есть только между шагами при разгоне торможении, больше 4 - 8 кГц получить не получается на 328

3) Ступенчатое повышение частоты шагового двигателя по квантам времени (как мне кажется grbl). Тат все класно, так как считать мы можем весь квант времени. Из проблем.1) определение приемлемого кванта времени 2) определение точки торможения. Тут засада в том, что точка начала торможения может оказаться в середине кванта времени => что при следующе расчете кванта времени у нас либо надо делать более активное торможение(т.е. отклоняться от указанного значения ускорения\торможения), или останавливать мотор на частоте выше, чем хотелось бы (т.е. мы стартуем с частоты 200 Гц, а заканчиваем на 1 кГц) 

Вот для 3 варианта я и не могу понять мат.обоснование. Из входных параметров ШД - максимальная частота и ускорение. Возможно что то еще. На выходе - рампа скорости.

P.S. дополнительный вопрос - Как определить безопасную частоту остановки мотора...

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Вот вы заморочились, однако... На самом деле S кривые не так страшны как звучит. Теория пугает, а реализация намного проще :) Да и с большинством AVR ституация обстоит намного хуже, они 8 битные :)

По 3, вообще странная теория, грубо говоря апроксимирующая траекторию прямыми отрезками, от длинны тайм слота(кванта) зависит качество апроксимации. Под точку начала торможения можно просто сдвинуть начало кванта, удлиннив предыдущий. Так же поступить и с точкой останова. 

Что вы такое крутите ? Большая инерция ?

roman2712@mail.ru
Offline
Зарегистрирован: 16.01.2014

Да, конечно 8 битный :) на uint16_t смотрел, замотался :)

Да именно так. В случае с grbl это 100 раз в секунду (можно менять).

В целом я прихожу к тому что кванты времени отсчитывать "виртуально". Т.е. считаем параметры кванта, в том числе и количество импульсов, и отдаем на таймер. Соответвенно может быть больше\меньше на конечном кванте. Как вариант в середине рампы вставить короткий квант, что бы скорректировать торможение до полных квантов. 

Если хотите, взгляните на "stepper.с" из grbl. пытаюсь его понять. расчеты именно в нем реализованы.

Хочу свою библу с шахматами и благородными девицами, так как эпизодически возникает потребность крутить ШД на высоких частотах. (ШГ с редуктором, делителем шага на 16 да еще и на винте)

 

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

В марлине тоже самое. Из-за большого числа макросов понимание работы сильно осложнено :( Если честно не хочу тратить время на этот ужас, при том, что код полон пояснений. Но что получается в результате - мне нравится. Очевидно что они используют алгоритм Брешенема и в описании рассказывают об адаптивной точности. Типа делением-умножением пополам поднимают, опускают точность входных - выходных данных.

А циклический буфер у них для хранения потока вхордящих G-кодов, только и всего.

roman2712@mail.ru
Offline
Зарегистрирован: 16.01.2014

там несколько буферов. один действительно для g-кодов. Есть еще буфер для загрузки таймера (хотя может и просто очередь), который и формирует импульсы на шаговики. Он, вроде как на структуру plan_block_t завязан.

В общем хочется также, только упразнив часть с обработкой G-кода.

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

А что будет "путевой картой" для этой системы. Ведь тут большое значение имеет то, что процессор(планировщик) знает куда в будущем поедет мотор. То есть он может "заглядывать вперед". Без этого ничего не получится.

В марлине мне очень нравится, что решен вопрос одновременной плавной работы 6 моторов на разных скоростях, вот это ценно. А если мотор всего один, то и планировщик такой нафик не нужен.

roman2712@mail.ru
Offline
Зарегистрирован: 16.01.2014

ИМХО "заглядывавть вперед" смысла особого нет. У нас есть текущая точка0 (x0,y0,z0). Есть команда (г-кодом) ехать на точку1 (x1,y1,z1).  Имеем вектор, раскладываем его на состовляющие, выбираем состовляющую с самам большим количеством попугаев (тут я пока не совсем понял, какие "попугаи" в grbl, толи шаги толи мм), применяем алгоритм Брешенема, беря за основу самую длинную составляющую и получаем, на сколько "попугаев" самой длинной составляющей приходится 1 "попугай" более короткой. Это пока как я сейчас это вижу, дальше, наверно будет понятней.

А то что я сейчас пытаюсь реализовать, фактически рампа скорости для самой длинной составляющей. В grbl действительно все завязано на вормулы 7 класса. https://kiselevich.ru/edu/fiz/ege-2011/11.html + кванты времени. Но дьявол кроется в деталях.

До сих пор не могу сообразить как коректируется скорость\ускорение или время после прохождение точки торможения и как отрабатывается замедление на сверх малой скорости(когда в квант не попадает ни одного импульса).

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Разгон. Торможение . Шагового двигателя. Это проблема не в самом ШД. Шаговый двигатель двигается шагами и ему остановиться и разогнаться не проблема. Проблема в механической нагрузке. Масса это уже инерция. И блок питания. При шаге ШД растет ток потребления. И если источник питания и Драйвер на ШД паршивый то быстро остановиться и разогнаться не получится. И все формулы оптимизации это как эфективно использовать не очень хороший драйвер.

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

roman2712@mail.ru пишет:

До сих пор не могу сообразить как коректируется скорость\ускорение или время после прохождение точки торможения и как отрабатывается замедление на сверх малой скорости(когда в квант не попадает ни одного импульса).

Ну из кода я увидел, что там есть конкретная завязка на прерывания. После каждого импульса вызывается прерывание, так что все под контролем. Ну вот вам примерный алгоритм: посчитав шаг приращения скорости, вы можете каждый раз увеличивать задержку выдачи шага на некое количество единиц, прямо в прерывании. В результате получите равнозамедленное движение. А то что вы называте квантами, нужно для отработки прямых отрезков. В определенное время зная текущую точку,скорость и конечную точку и скорость, вычисляете шаг приращения скорости за один шаг или за несколько шагов мотора. Ну как то так. Все сводится к очень простой математике, которую легко реализовать.

roman2712@mail.ru
Offline
Зарегистрирован: 16.01.2014

Если кому то интересно, наброски по теме :)

Без слежения за шагами. Тупо разгон и изменение скорости. (т.е. шаговик работает как DC мотор), зато до 30 кГц :)

Есть проблемы с изменением частототы , ИМХО надо на управление таймером напрямую переходить.

#include <TimerOne.h>

int a = 10000;

int v_set;
int p;
float t = 0.05;

int v;
int s_delta;
int v_delta;

enum
{
  ACCEL,
  CRUISE,
  DECEL,
  DECEL_TO_V,
  STOP
} state = STOP;

void isr_timer1()
{
  digitalWrite(p, HIGH);
  digitalWrite(p, LOW);

  --s_delta;

  if (s_delta == 0)
  {
    switch (state)
    {
      case ACCEL:
        if (v + v_delta >= v_set)
        {
          v = v_set;
          s_delta = v * t;
          state = CRUISE;
        }
        else
        {
          s_delta = (v + v_delta / 2) * t;
          v += v_delta;
        }
        break;
      case CRUISE:
        s_delta = v * t;
        v = v_set;
        break;
      case DECEL:
        if (v - v_delta > 0)
        {
          s_delta = (v - v_delta / 2) * t;
          v -= v_delta;
        }
        else state = STOP;
        break;
      case DECEL_TO_V:
        if (v - v_delta > v_set)
        {
          s_delta = (v - v_delta / 2) * t;
          v -= v_delta;
        }
        else
        {
          v = v_set;
          s_delta = v * t;
          state = CRUISE;
        }
        break;
    }

    if (state != STOP)
    {
      Timer1.setPeriod(1000000 / v);
    }
    else Timer1.stop();
  }
}

void initiation(int _p)
{
  p = _p;
  pinMode(p, OUTPUT);
  Timer1.initialize();
  Timer1.stop();
  Timer1.attachInterrupt(isr_timer1);
}

void start(int _v)
{
  v_set = _v;
  v_delta = a * t;
  if (v > v_set)
  {
    v = v_set;
    s_delta = v * t;
    state = CRUISE;
  }
  else
  {
    v = v_delta;
    s_delta = t * v_delta / 2;
    state = ACCEL;
  }

  Timer1.setPeriod(1000000 / v);
  Timer1.start();
}

void stop()
{
  state = DECEL;
}

void setSpeed(int _v)
{
  if (state != STOP)
    if (_v < v_set) state = DECEL_TO_V;
    else state = ACCEL;
  v_set = _v;
}

void setAccel(int _a)
{
  a = _a;
}

void setup() {
  pinMode(8, OUTPUT);
  pinMode(5, OUTPUT);
  digitalWrite(8, LOW);
  digitalWrite(5, HIGH);
  Serial.begin(9600);
  initiation(2);
  start(100);
}

void loop() {
  delay(3000);
  setSpeed(15000);
  delay(3000);
  setSpeed(5000);
  delay(3000);
  setSpeed(1000);
}

 

Logik
Offline
Зарегистрирован: 05.08.2014

Если Вас интересует быстрый код, то про floatdigitalWrite и прочую нечесть надо забыть один раз и навсегда. Только после этого можна будет рассуждать успевает 328 или нет.

roman2712@mail.ru
Offline
Зарегистрирован: 16.01.2014

В данном случае она и так успеет. С целочисленным вычислением есть нюанс, при использовании long (int в некоторых случаях не хватает) то скорость вычислениия не сильно выше получается. 

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

Ну и digitalWrite - данном коде это фактически задание время импульса и возвожность указать тестовый пин, в перспективе перекину на таймер и регистры. Ну и да   digitalWrite - окло 4 мкС => 200 кГц (по осцилографу), на фоне требуемых 30 кГц не влияете.

Logik
Offline
Зарегистрирован: 05.08.2014

//при использовании long (int в некоторых случаях не хватает) то скорость вычислениия не сильно выше получается. 

Сильно-не сильно. Художественный треп. Выиграш в разы и даже десятки раз , тот факт что лонг и флоат по 4 байта не определяющий, даже сложение и и вычитание с плавающей оч. тяжелое дело, всегда в отдельной подпрограмме с выравниваниями согласно порядкам чисел и т.д. В Вашем случае это весьма критично. К тому же есть float t = 0.05;, ну выбирите её поудобней 1/16 или лучше  1/32. Вам посути всеравно, а код без флоата и с удобной константой станет существенно шустрей.

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

оч. спорная архитектура. Буфера и очереди выглядят лишней сущностью, которые займут  ресурсы. Прервались - вывели сигнал, посчитали данные для следующего прерывания, настроили таймер и завершили прерывание. Так выглядит оптимальней.

//на фоне требуемых 30 кГц не влияете.

Внимательней считайте. 30КГц это 33мксек на все про все. Из них 8мкс на вход/выход из прерывания. Тяжело от них избавится. Остается 25. Из них 2 раза по 4мксек =8мксек на digitalWrite. Т.е. 30% доступной в коде производительности коту под хвост.

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

Кто-нибудь учитывает тот факт что ток в индуктивности не может изменяться мгновенно?
Или  у вас тут чисто математичечкие состязания?
Типа   кто больше цыфру назовёт.

roman2712@mail.ru
Offline
Зарегистрирован: 16.01.2014

Для trembo 

то что вы написали решается фактически накладывает ограничение по приемистости\крут.моменту\максимальной частоте и т.д. ШД. Если упрощать подход, то у нас для системы драйвер->ШД->исполнительный модуль есть фактически 2 основные характеристики - максимальная скорость и максимальное ускорение.

Фактически для используемого мной ШД при шаге 1/16, напряжении питании 15В и токе около 1.5А то что вы написали не дает его разогнать больше 16 кГц (16 000 / (200*16)) = 5 об/сек, правда только на холостом ходу. Опять таки есть и более мощьные моторы. Был в руках сервопривод с энкодером и своим драйвером, его станок споконо крутил до 3000 RPM с позиционированием до сотки на винте.  

Для Logik

В целом да, учитывая что это наброски, не критично. Кроме того, результат приводиться к long, так что значительного выигрыша в скорости не будет. Кроме того, по вычислениям я не уперся, так что на текущем этапе смысла не имеет, сейчас важнее простота восприятия кода. float t = 0.05  сейчас пока на поиграться вообще орентир на 1/100 сек. мотор мягче работает, меньше слышны переходы при разгоне. Упрусь в расчет перейду на целочисленную математику.

Не так. как вы написали сделано в AccelStepper. Посмотрите как там идет расчет. Я в свое время оптимизировал расчет AccelStepper в целочисленые, а также переделывал ее на таймер1, больше 6 - 8 кГц не тянет. И это с учетом что там облегченная формула (без квадратных корней)

Тут идея в ступенчатом увеличении скорости ШД, что позволяет расчеты вынести за пределы прерывания, проводя их для из расчеты изменения генерироемой частоты раз в 1/100 сек. (grbl, marlin. Да и судя по звукам не очень больших ЧПУ станков, то и в пром.контроллерах).

Согласен, но пока даже этого хватает и до 50 кГц, тока это не нужно. Я пока не в работу с digitalWrite уперся, а в часть связанную с расчетом замедления, когда нам надо строго определенное количество шагов ездить.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Что там шаги считать . Разгон или замедление это конкретное количество шагов. А дальше шаги идут по линейной скорости. Если шагов мало для набора скорости то половина идет на разгон и оставшая на торможение. И все. задайте константы и все.

roman2712@mail.ru
Offline
Зарегистрирован: 16.01.2014

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

Напишите как вы будете считат количество шагов \ разгона торможений. При линейном движении вопросов нет, а вот если есть ускорение, то тут становиться намного все интересней...

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Если вы тему курите, то похоже трава не та.  Итак . Каково бы не было ускорение все равно выйдем на линейную скорость в которой шаг будет  x микросекунд. Пусть у нас торможение . Длительность первого шага 2*х. второго 3*х и так до 100*х, потом стоп . больше шагов не будет. 99 шагов - линейное торможение. Долго - может быть. Ускорим . 1 шаг -2х ; 2 шаг 4х ; 8x ;16x; 32x;64x 128x стоп.  7 шагов. Ладно пусть у нас хитрая траектория торможения. Кто нам мешает записать константы на каждый шаг и сколько шагов в.. PROGMЕM. И все потому что нам от Адуины нужна работа. А всякое моделирование можно расчитать на больших компьютерах и залить готовую таблицу в Ардуину. Сомнение что разгон и торможение не симметричны в одном сила торможения в - а в другом в +. Так сделайте таблицы. Для разгона и для торможения.

roman2712@mail.ru
Offline
Зарегистрирован: 16.01.2014

PROGMЕM. можно, но не универсально, хотя имеет право на жизнь для конкретного мотора. 

А та подборка шагов, что вы написали (насамом деле это первое что приходит в голову, и даже обсчитывал этот вариант) - 1) очень медленно тормозим и разгоняемся 2) не универсально (моторы разные бывают)

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

   

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

roman2712@mail.ru пишет:

PROGMЕM. можно, но не универсально, хотя имеет право на жизнь для конкретного мотора. 

А та подборка шагов, что вы написали (насамом деле это первое что приходит в голову, и даже обсчитывал этот вариант) - 1) очень медленно тормозим и разгоняемся 2) не универсально (моторы разные бывают)

 

Это Вы думаете, что неуниверсально.

В мире, в котором мы живем физика одна и та же. Неуниверсально может быть только для какого-то альтенативного мира с другими законами физики.

roman2712@mail.ru
Offline
Зарегистрирован: 16.01.2014

Слуште, возьмите табличку и посчитайте. 

Исходные данные ускорение 1000 шагов/сек^2, максимальная скорость 15 000 шагов/сек (это в моем случае)

При том что скорость текущая может быть задана любая.

Для тех кто не понял... у нас шаг таблицы должен быть 1 шаг. т.е. итого 15 000 шагов. Если информация о шаге занимает 2 байта (uint16_t) то надо 30 000 байт. На программу места не остается. 

но 15 кГц - это у меня, ШД могут тягать значительно выше. (любой пром ШД с нормальным драйвером).

Можно камень взять с большей памятью, можно внешний EEPROM поставить с шагами, можно просто взять камень аля STM32F4 на 168 МГц и считать в лоб. Не в этом вопрос... 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Похоже мозги умному в помощь, а дураку в наказание.  Ну зачем 15 000 шагов и каждому шагу по 2 байта.  1 % процент погрешности уже нормально. Итого было 15 000 стало 150 отсечек. А 100 шагов или одинаковая величина или линейность. 

ПС: Вот как просто получают синусоиду не пользуясь трудоемкой математикой http://robocraft.ru/blog/2911.html

Но вам нужен геморрой, что бы не решать свою же проблему. Потому что ваша проблема смысл вашей жизни. Нет проблемы и нет смысла в жижни ;)

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

roman2712@mail.ru пишет:

у нас шаг таблицы должен быть 1 шаг.

Откуда это следует?

roman2712@mail.ru
Offline
Зарегистрирован: 16.01.2014

qwone ну вот ну почему, как я тебя прочитаю, мне хочется зарыдать и напица? 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

 

Вот есть еще прием для нахального разгона http://electroprivod.ru/akseleration.htm  Но там надо прикитывать что бы мотор успевал остыть перед разгонами. И разумеется лучше прикрепить датчик температуры к ШД хотя бы на время тестов.

А это в догонку Кенио Т. — Шаговые двигатели и их микропроцессорные системы управления https://yadi.sk/d/vu-aNxpWMnj3f     Так что пользуйтесь PROGMEM, а не ищите спасительные формулы.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

qwone пишет:

ПС: Вот как просто получают синусоиду не пользуясь трудоемкой математикой http://robocraft.ru/blog/2911.html

Типичная "статья из И-нета": на входе банальная идея, на выходе - негодная реализация.

Спрашивается, зачем было делать 8-разрядный выход, если в 3-4 младших все равно будут только шумы?

Кстати, это даже видно по приведенным фото: на экране осциллографа с разрешением экрана по вертикали 240 пикселей синусоида занимает около четверти, т.е пикселей 70. Но даже при этом явно видны искажения.

Ну и автор статьи, похоже, не в курсе, что осциллограф, которым он пользуется, может сам сделать аккуратный скриншот и записать его на флешку. А может - знает, но понял, что если вместо размытого фото позместить аккуратный скриншот, то "кривоватость" синусоиды будет бросаться в глаза.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

andriano, я просто привел пример, как не вычисляя синус получить синусоиду. А что статья из Инета,выглядит так, так жанр "статьи из Инета" такой.  Более серьезную информацию надо брать из жанра "технические книги", который большинство "народа из Инета" не осилит.

roman2712@mail.ru
Offline
Зарегистрирован: 16.01.2014

andriano и qwone http://avrdoc.narod.ru/index/0-7 почитайте (это перевод апноута avr446). Только вдумчиво. Тогда у вас не должно быть вопросов почему на каждый шаг, и не получиться делать это через несколько шагов. Более того, в данном решении нет возможности замедления до новой скорости (критично), такак начало остановки расчитывается до начала движения. 

посмотрите равлизацию AccelStep. Там испульзуется формула еще проще, которая считается за 70 мкС (да и это многовато), но необходимость перерасчета интервалов в скорость для определения точки начало торможения все портит , переводя этот расчет в 200 - 250 мкС. 

 

 

 

roman2712@mail.ru
Offline
Зарегистрирован: 16.01.2014

Ну и да, у чувака не синус кривой, а осцилограф скорее всего шумит. (у самого DSO5102, по сравнению с аналоговым очень шумный).

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

roman2712@mail.ru пишет:

Ну и да, у чувака не синус кривой, а осцилограф скорее всего шумит. (у самого DSO5102, по сравнению с аналоговым очень шумный).

Ну, был бы вменяемый скриншот, можно было бы сказать определеннее. И, кстати, IMHO Rigol в чрезмерной шумности не замечен. В отличие от Hantek'а.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

roman2712@mail.ru пишет:

andriano и qwone http://avrdoc.narod.ru/index/0-7 почитайте (это перевод апноута avr446). Только вдумчиво. Тогда у вас не должно быть вопросов почему на каждый шаг, и не получиться делать это через несколько шагов.

Вопросы остались.

Точнее, остался вопрос к Вам:

- почему "каждый шаг, и не получится..."?

Заодно появились новые вопросы к автору статьи. В частности:

- почему ряд Тейлора оборван на втором члене: в результате сокращения остается единственный член и по сути - линейная аппроксимация.

- почему для аппроксимации выбрано отношение шагов, а не величина шага. В таком варианте погрешность накапливается.

- почему все преобразования свелись к формуле, в которой присутствует деление? Деление - это катастрофа для производительности.

- почему у ТС в прерывании присутвует два деления вместо одного? Нет, вполне может быть, что оптимизатор сам додумается выбросить второе деление, но хотелось бы наверняка. Тем более, что вариант с единственным делением поддерживается библиотекой С.

 

Но вернемся к нашим баранам.

1. Разгон ШД до частот выше 5 кГц - задача нетривиальная. Поэтому возникает законный вопрос: а почему в таком случае привязка осуществляется к 328 чипу? Почему не к Arduino Due или хотя бы к 2560, для которого нет сомнений, поместятся ли таблицы в PROGMEM?

2. Тяжелая операция - деление. Именно от нее надо избавляться. Теоретически - длина таблицы на все случаи жизни 16384 числа. Но далеко не факт, что весь этот диапазон реализуется на практике. Мало этого, погрешность порядка 2% ну совершенно некритична (особенно с учетом того, склько уже потеряли, "линеаризовав" Тейлора). Т.е от 0 до 63 делаем полную таблицу на 64 значения, а потом, по 32 значения на интервалы 64-127, 128-255, 256-511, 512-1023, 1024-2047, 2048-4095, 4096-8191 и 8191-16383. Итого 320 значений при четырех условных переходах. Не тормозит и влезает даже в 168 чип.

3. Воспользовался не относительным изменением шага, а абсолютным: разложить его в ряд Тейлора, а потом преобразовывть так, чтобы не было делений.

4. Если уж совсем по-хорошему, то режим постоянного ускорения хорош при постоянном моменте на валу. А, как мы знаем, у ЩД момент падает на высоких частотах. Притом, весьма существенно. А борьба идет именно за высокие частоты. Откуда непосредственно вытекает, что режим с постоянным ускорением нам категорически не походит. Поэтому не подходит и вся изложенная в статье (по ссылке) математика. И ускорение (а, соответственно, и изменение времени шага) нужно считать в зависимости от достигнутой скорости вращения. Задача математически еще более усложняется (притом, существенно), и единственным подъемным для контроллера вариантом (пока не рассматриваем Arduino Due) остается табличное задание зависимости. Т.е. на ПК по подробной и точной модели насчитываем массив констант, которые затем и используем контроллером при работе.

roman2712@mail.ru
Offline
Зарегистрирован: 16.01.2014

1) принципиально. как инжененрная задача. Кроме того я знаю что это можно (grbl, marlin и т.д., тока там не линейное ускорение а по квантам времени, к чему я тоже пришел).

2) а почему 16384 ? 

3) если говорить об абсолютном значении, то надо считать sqrt(n+1) - sqrt(n). С другой стороны и так есть нормализация по с0 

4) то что вы говорите - это s кривые. в данном случае вообще не рассматриваются. Считаем что линейное ускорение мотор будет поддерживать до тех частот, которые нам нужны.

по 2 и 3 я до экселя доберусь, пересчитаю для хедшего случая.

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

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Разгоняться и тормозить надо до запуска двигателя. Пришла команда :"пройти N шагов"- А шагов разгоняемся B шагов идем на максимуме C шагов тормозим Итого A+B+C=N шагов.Можно запускаться.  А томозить уже когда "сбили пешехода" может только "бухой водитель".

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

roman2712@mail.ru пишет:

1) принципиально. как инжененрная задача. Кроме того я знаю что это можно (grbl, marlin и т.д., тока там не линейное ускорение а по квантам времени, к чему я тоже пришел).

Ну так решения есть и их существенно больше одного. 

Наброски некоторых я привел.

Цитата:

2) а почему 16384 ? 

Точнее 16383.

Вычисления проводятся в unsigned int. Максимальная величина 65535. Т.е. для числа 16383 по формуле (4х+1) наступит переполнение. Т.е. полная таблица соответствует диапазону значений от 0 до 16382.

Цитата:

3) если говорить об абсолютном значении, то надо считать sqrt(n+1) - sqrt(n). С другой стороны и так есть нормализация по с0 

Вот он нее и надо плясать.

Цитата:

4) то что вы говорите - это s кривые. в данном случае вообще не рассматриваются. Считаем что линейное ускорение мотор будет поддерживать до тех частот, которые нам нужны.

Тогда забудьте о 30 кГц.

И, думаю, даже об 1 кГц.

Цитата:

по 2 и 3 я до экселя доберусь, пересчитаю для хедшего случая.

У-у, как всче запущено...

Проще написать консольную программу для ПК на любом доступном ЯП, хотя бы на том же С++.

Цитата:

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

Ну да, qwone прав - вычислять начало торможения надо до того, как физически начат разгон, а не пытаться сделать это в прерывании.

inspiritus
Offline
Зарегистрирован: 17.12.2012

... я конечно извиняюсь, встревая в Ваш высоконаучный спор... 

Roman , а для чего это Вам это нужно , опишите пожалуйста систему, которой Вы пытаетесь управлять и результат, который получаете, а также чем он Вас не устраивает, и что Вы пытаетесь получить.

зы. Больше  условных 10 кгц получалось только на сервоприводах с частотным управлением, и это были НЕ  шаговики.  И драйвер каждого привода координаты был целой платой со своим , достаточно производительным процессором.

roman2712@mail.ru
Offline
Зарегистрирован: 16.01.2014

qwone этот вариант работает и без таблицы. А вообще данная ситуация вполе вероятна. Т.е. начали разгон, попали на выключатель, начинаем тормозить. Понятно что мимо перелетим. в предложенном Вами случае, мы вынуждены указать просто минимальную скорость с которой будем идти до выключателя. А растояние может буть очень длинным и идти будем долго.

К примеру возвращение каретки на 0, выключатель ставиться с запасом, с учетом, что даже на максимальной скорости, мы при его перелети не улетим в ограничитель. Тогда на >0< мы едем с максимальной скоростью. Даже если перелетим, то знаем на сколько.

В вашем же случае, мы либо ограничены по скорости либо вынуждены будем дождаться окончания разгона а потом тормозить, либо сразу тормозить и терять шаги после выключателя.

С вспомнил почему таблица в свое время меня не устроила. Надо 2 величины держать. время между импульсами и кол-во шагов до торможения. 

А расчет показывает, что при ускорении 5000 и скорости до 15 кГц надо грязно (каждый шаг хранить) - 10180 значений. без повторов - 610

При плохом случае ускорении 100 и скорости до 30 кГц 1976540 и 2456 соответвенно.

т.е. если принять что можно взять не все значения а только уникальные, то надо 2500 значений. время между импульсами и шаги до остановки укладываются в uint. итого 4 * 2500 = 6000. Т.е. около 10 кБ. Реально меньше так как на практике скорее ускорение будет выше.

16384 - верно только для int, а тут надо long. Это при разработке надо учитывать, что бы не влететь на переполнение переменной

из проблем

Если у нас 2 мотора...

Для каждого мотора надо таблицу считать заново...

А если мотор поменяют и поставять с другой характеристикой...

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

   

roman2712@mail.ru
Offline
Зарегистрирован: 16.01.2014

qwone чувствуется Вы с ЧПУ вы не сталкивались...

Замена ШД, это не только замена двигателя, это еще и установка редуктора на станок и замена драйверов и просто изменение числа шагов на оборот. Обычно для этого в программе предусматривают перенастройку некоторых велечин без перекомпиляции (в данном случае ускорение и максимальную скорость).

А по поводу позиционирование - если вы с этим не сталкивались, не значит что этого не существует... поверьте, бывает и хуже... Ну и да, шаговики не только в ЧПУ исользуют, но и в различных приводах...

 

 

 

 

 

roman2712@mail.ru
Offline
Зарегистрирован: 16.01.2014

inspiritus банальный шаговик. ну больше 10 кГц на управлении запросто, если учеть деление шага до 256.

Сейчас то что у меня на столе лежит крутиться на 5 об/сек, при частоте 16 кГц и делении шага 1/16 с достаточным крутящим моментом.

Учитывая что он был снят с принтера с питанием 42В, а я его кормлю пока 15В, он явно не выдает все на что способен )

inspiritus
Offline
Зарегистрирован: 17.12.2012

Почему я и спросил для чего оно все. На 1/16 какой момент достаточен ?

а на 1/1 на какой частоте он шевелится ? 

Каждый гадает на своем шаре и предлагает варианты исходя из гадания, а что имел ввиду тс ? Какая скорость ему нужна? Какой момент ?

 

roman2712@mail.ru
Offline
Зарегистрирован: 16.01.2014

Цель - максимальная скорость 30 кГц на AVR 16 Мгц, при правильной (линейной) характиристике разгона торможения. 

Из входных данных - ускорение движка и максимальная скорость (то что пользователь может изменить в программе)

Из доп.требований

1) нормальная отработка сигнала стоп (начала торможения)

2) правильная обработака начала торможения, если стоп пришел на этап разгона

3) возможность изменения скорость в процессе работы

Это реально, так как в GRBL, Марлин и подобных вещах это работает, причем для 3 моторов одновременно. (позиционирование по X, Y, Z). мне бы пока с 1 решить.

Разбор GRBL продвигается медленно в виду сильной декомпозиции кода и на С его сложно разбирать.

Ну и да, есть прототип кода, которы доказывает реализуемость разгона движка по квантам времени (1/50 сек). К сожалению никак не могу придумать достаточно простой способ линейно тормозить при работе на строго определенное количество шагов. 

 

inspiritus
Offline
Зарегистрирован: 17.12.2012

Наверно я чего то не понимаю?

ОДНАКО

Цель - максимальная скорость 30 кГц на AVR 16 Мгц, при правильной (линейной) характиристике разгона торможения. 

КАКОЙ МОМЕНТ?

Из входных данных - ускорение движка и максимальная скорость (то что пользователь может изменить в программе)

Из доп.требований

1) нормальная отработка сигнала стоп (начала торможения) ЧТО ЕСТЬ НОРМАЛЬНАЯ?

2) правильная обработака начала торможения, если стоп пришел на этап разгона ЧТО ЕСТЬ ПРАВИЛЬНАЯ?

3) возможность изменения скорость в процессе работы  В КАКИХ ПРЕДЕЛАХ 

Это реально, так как в GRBL, Марлин и подобных вещах это работает, причем для 3 моторов одновременно. (позиционирование по X, Y, Z). мне бы пока с 1 решить. 

Я СЕЙЧАС ДЕЛАЮ НЕЧТО ПОДОБНОЕ, ввиду ограниченности требований походу получится на одном мк, однако при незначительных потребных моментах и некритичной точности  требуется максимально достижимая скорость ( 3 координатный манипулятор) Пришлось поставить трехзаходный винт и применять скорость 1/1. В другом проекте также требуется максимально достижимая скорость (5,8,10 об/сек, чем больше тем лучше) и максимально достижимый момент ( 20-30 кг.см) одновременно- пришлось покупать относительно мощный шаговик с током  порядка 5 А ( реверсивная нарезка резьбы). В обоих случаях более 3- 3.5 кГц шаговики тупят, во втором случае после 2 кГц значительно падает момент, что критично.

воти вопрос ? А что делаете Вы? или это как всегда тайна?

Разбор GRBL продвигается медленно в виду сильной декомпозиции кода и на С его сложно разбирать.

roman2712@mail.ru
Offline
Зарегистрирован: 16.01.2014

Момент... момент решается повышением напряжение, более мощьным драйвером и мотором. Ну или систему с Close Loop. Ну я бы еще попробывал BLDC мотор + редуктор + энкодер... но это лирика... (но тут наверно уже AVR не отделаться, надо что то с встроенной системой управления такими моторами, у STM вроде что то было)

Библиотеку хочу написать, аля accelstepper универсальную :) 

Из того что сейчас есть 16 кГц на 1/16 и винт на 4 мм оборот - итого 0,00125 на 1 шаг. Если просто это крутить на максималке то 20 мм/c. Это грустно учитывая что ехать надо около 1 метра (в теории)... но это только позиционирование. Если разговор о какойто серьезой нагрузки то надо будет еще ШД подбирать. 

Мне высокая частота нужна не для скорости, а для точности. Высокая скорость необходимо только на холостых перемещениях. Рабочая скорость будет значительно меньше, если она понадобиться.

inspiritus
Offline
Зарегистрирован: 17.12.2012

И опять рассказали много , но для чего это в конце не нказали ни слова :)

зачем все эти экзарсисы с ускорениями? Если уж совсем не хочется дёргать, делайте стандартное ускорение до достижения целевой скорости для плавного пуска. А если за время перемещения при заданном ускорении целевая скорость не может быть достигнута, то так тому и быть : из ускорения сразу в замедление.