В прошлой статье: ПРОБЛЕМА НЧ И ВЧ ЗВОНА В 3D ПЕЧАТИ. ОКОНЧАТЕЛЬНЫЙ АНАЛИЗ я упоминал, что установка на экструдер драйвера, дающего микрошаг 1/32 - вполне себе полезная вещь (хоть польза и выявляется прибором, который не имеет отметки о поверке в отделе метрологии, иными словами ногтём!). Однако, после этого может возникнуть желание заменить все драйверы на аналогичные. На многих форумах я читал, что это делает звук двигателей более музыкальным. Хочется сказать: Всё хорошо в меру. Не то, чтобы это было совсем плохо, но давайте я опишу аргументы, которые появились после копания в недрах прошивки Marlin, ведь именно она используется в качестве базовой во многих 3D-принтерах.

С чего начать? Сначала я расскажу про ускорения. Они нам пригодятся, а в текст их никуда не вставить, везде повествование будет разорвано. Так что пусть это будет как введение. Если головку рвануть резко, то будет масса проблем. Начиная от уже набивших оскомину в прошлых статьях НЧ-шумов печати, и заканчивая тем, что двигатель может при резком старте пропустить несколько шагов. Во избежание всего этого, головку разгоняют плавно. Ну, и тормозят - тоже, там это уже нужно именно для уменьшения шумов. Прошивка Marlin работает в режиме трапециевидного графика скорости.

marlin.png

То есть, скорость нарастает и спадает линейно на определённом участке. Угол, под которым наклонён график скорости при разгоне и торможении, как раз и задаётся параметром "Ускорение".  Вот так спад частоты шагов выглядит на осциллографе (красные всплески - шаги двигателя по оси X, жёлтые - двигателя экструдера, эту осциллограмму я сохранил, когда при борьбе с ВЧ-звоном убеждался, что экструдер и правда шагает вдвое чаще, чем раньше:

Снимок_экрана_2016-02-18_в_18.44.43.png

Теперь поговорим о том, с какой скоростью шагает наш двигатель. Давайте спросим у самого принтера через панель связи. Я работаю в Simplify3D, но такая панель есть и в других программах:

Снимок_экрана_2016-02-18_в_18.46.08.png

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

Снимок_экрана_2016-02-18_в_18.47.35.png

Возвращаемся на вкладку Communication, теперь надписи не мельтешат (старые, правда, остались на месте, но это не беда). Говорим принтеру M503 и нажимаем SEND

Снимок_экрана_2016-02-18_в_18.51.53.png

Принтер вывел много чего, причём на человеческом языке. Нас интересует вот эта строчка:

RECEIVED: echo:Steps per unit:

Steps per unit:

RECEIVED: echo: M92 X100.00 Y100.00 Z1600.00 E100.00

M92 X100.00 Y100.00 Z1600.00 E100.00

Получается, что у моего 3D принтера MZ3D-256 по осям X и Y на один миллиметр приходится 100 шагов. Ну, если точнее, то микрошагов.

Чудненько. Что это значит? А значит это, что для перемещения головки на 1 миллиметр, двигатели X и Y должны сделать по 100 шагов. Вообще, там выдалось намного больше информации, почитайте, это очень забавная вещь. Параметры вполне можно поменять и сохранить в EEPROM, но об этом как-нибудь в другой раз.

Пусть головка идёт со скоростью 100 мм/с. Тогда она должна за секунду делать 100*100 =10.000 шагов. То есть, двигатель работает с частотой 10 килогерц. 150 мм/c - 15 килогерц и т.п. Цифры могут быть чуть иными, они зависят от того, какие зубчатые колёса стоят на двигателях.

Из текста прошивки я узнал, что в теории бывают принтеры MZ3D-256A и MZ3D-256B, у них число шагов другое. Но давайте рассмотрим в качестве другого примера не гипотетические A и B, а реальный принтер MakerGear M2, у него прописано 88.8 шагов на миллиметр, тогда 100 мм/с будет 8.88 килогерц, 150 мм/c - примерно 13 килогерц. В общем, спросите у своего принтера, он Вам ответит, какие лично у него параметры.

Собственно, если я увеличу микрошаг двигателя с 16 до 32 шагов, то у моего принтера частоты возрастут до 20 и 30 килогерц, а у M2 (с его 88.8) - до 17 и 26 килогерц соответственно. Много это или мало? Обратимся к прошивке.

Что мы видим в прошивке Marlin? А видим мы, что двигатели обслуживаются таймером 1. Один тик таймера - один шаг. После чего процессор бросает работу с двигателями до следующего тика. Но Marlin - очень хитрая прошивка! Она настраивает таймер так, чтобы следующий тик произошёл строго вовремя! Для этого вызывается функция

unsigned short calc_timer(unsigned short step_rate) {

Как видим, в неё как раз передаётся частота работы двигателя. И что мы наблюдаем на входе? Уууу! Сначала нам встречается безобидное

 if(step_rate > MAX_STEP_FREQUENCY) step_rate = MAX_STEP_FREQUENCY;

 

Ну, тут проверяется, что частота не выше 40 КГц (для моего принтера в родном варианте это 400 мм/с, но если я сделаю микрошаг 1/32, то всего 200 мм/с). Дальше - больше

 if(step_rate > 20000) { // If steprate > 20kHz >> step 4 times

   step_rate = (step_rate >> 2)&0x3fff;

   step_loops = 4;

 }

 else if(step_rate > 10000) { // If steprate > 10kHz >> step 2 times

   step_rate = (step_rate >> 1)&0x7fff;

   step_loops = 2;

 }

 else {

   step_loops = 1;

 }

Перевожу на русский: Производительности процессора AtMega не хватит для того, чтобы обслуживать прерывание таймера на частоте выше 10 КГц. Поэтому если двигатель работает на скорости до 10 КГц - на одно прерывание будет один шаг. От 10 до 20 ГКц - на одно прерывание будет два шага. И от 20 до 40 КГц - четыре шага.

Собственно, вывод статьи как раз заключается в том, что всё, что ниже  10 КГц (100 мм/с для моего принтера), в прошивке Marlin, работающей на контроллере AtMega (стоящем в Arduino) будет обрабатываться равномерно. Выше - шаги будут неравномерными. Два шага, пауза, снова два шага, снова пауза. Или даже четыре шага, пауза, снова четыре шага, снова пауза.

   for(int8_t i=0; i < step_loops; i++) { // Take multiple steps per interrupt (For high speed moves)

...

       if (counter_x > 0) {

       #ifdef DUAL_X_CARRIAGE

         if (extruder_duplication_enabled){

           WRITE(X_STEP_PIN, !INVERT_X_STEP_PIN);

           WRITE(X2_STEP_PIN, !INVERT_X_STEP_PIN);

         }

         else {

           if (current_block->active_extruder != 0)

             WRITE(X2_STEP_PIN, !INVERT_X_STEP_PIN);

           else

             WRITE(X_STEP_PIN, !INVERT_X_STEP_PIN);

         }

       #else

         WRITE(X_STEP_PIN, !INVERT_X_STEP_PIN);

       #endif        

         counter_x -= current_block->step_event_count;

         count_position[X_AXIS]+=count_direction[X_AXIS];   

delayMicroseconds (2);

// Аналогично для Y, Z и экструдера

...

   }

 

В общем, на микрошаге 1/32 двигатели становятся более музыкальными, но работают явно рывками.

Можно ли сделать равномерность? На Arduino - не уверен. Можно перетянуть это всё на ARM, там и сам процессор быстрее, и умножение/деление аппаратно выполняются, поэтому работает быстрее (а попутно можно выкинуть ассемблерные вставки и часть табличных вычислений - это в AVR без них никак, у ARMа уже компилятор преобразует сишный код к приемлемым ассемблерным командам без нашей помощи). А часть Cortexов ещё и плавающую арифметику аппаратно поддерживает (прошивка такими вычислениями просто изобилует). Лично у меня получилось это сделать начерно ровно за неделю, так что всё реально (начисто - ещё пилить и пилить, разумеется). Только не надо думать, что вот сейчас мы переделаем эти сравнения, и всё заработает! Ха! Там проверка на проверке и проверкой погоняет. Скажем, вот концовка той функции calc_timer:

 if(timer < 100) { timer = 100; MYSERIAL.print(MSG_STEPPER_TOO_HIGH); MYSERIAL.println(step_rate); }//(20kHz this should never happen)

 return timer;

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

void calculate_trapezoid_for_block(block_t *block, float entry_factor, float exit_factor) {

 unsigned long initial_rate = ceil(block->nominal_rate*entry_factor); // (step/min)

 unsigned long final_rate = ceil(block->nominal_rate*exit_factor); // (step/min)

 

 // Limit minimal step rate (Otherwise the timer will overflow.)

 if(initial_rate <120) {

   initial_rate=120;

 }

 if(final_rate < 120) {

   final_rate=120;  

 }

Правда, здесь идёт минимальная скорость, чтобы 16 битный таймер не переполнился. Тем не менее, это показывает, что проверки могут быть спрятаны где угодно в коде. Не так-то просто обеспечить музыкальность двигателей! Однако, в принципе, всё реально. Но не так, что купили новые драйверы, поправили пару констант и всё. Та музыкальность - красивая, но обманчивая.

Заключение

В статье показано, что не факт, что имеет смысл заменять драйверы ходовых двигателей X и Y на прддерживающие микрошаг 1/32. При использовании Arduino (с контроллером на базе AVR), частота шагов может оказаться не совсем честной, если она превышает 10 килогерц. Проверка честности шагов для процессора ARM пока находится в активной фазе, но уже точно известно, что как минимум, снимать или изменять ограничения в прошивке - точно придётся.

 

С уважением В.Ш.