sadr0b0t / stepper_h

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

Посчитать разные граничные значения для драйверов, моторов и логики #23

Closed sadr0b0t closed 7 years ago

sadr0b0t commented 7 years ago

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

и т.п.

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

Отправные точки: Про подключение драйвера step-dir и выбор режима делителя https://github.com/1i7/stepper_h/issues/16 Замеры некоторых значений на плате ChipKIT для фиолетового драйвера с делителем шага 1/32 https://github.com/1i7/stepper_h/issues/17

фиолетовый драйвер - Pololu-DRV8825 https://ru.aliexpress.com/item/20pcs-lot-StepStick-DRV8825-Stepper-Driver-Pololu-Reprap-4layer-PCB-Sanguinololu-RAMPS/32417447864.html?spm=a2g0v.10010108.1000016.1.38f7f7319jDHWL&isOrigTitle=true

sadr0b0t commented 7 years ago

Тест: задержка между шагами. Фиолетовый драйвер, моторы 17HS4401 (побольше; 1.7А 0.42N.M), 17HS3401 (cредний), 17HS2408 (самый маленький).

По результатам тестов выделяю 4 основные состояния мотора в зависимости от выставленной задержки:

Чем меньше делитель шага, тем более размыта граница между состояниями. Например, пограничное состояние "если остановить его пальцем, сам движение не продолжает" иногда воспроизводится стабильно, а иногда мотор может взять и продолжить. Если "мотор гудит и не крутится", то можно его немного крутануть пальцем и он начинает крутится. Или в режиме без деления при задержке 600 микросекунд мотор вроде как пищит и даже при попытке крутануть пальцем не начинает вращаться, но если плавно провернуть его 3-4 раза, то все равно начинает вращение.

Скорее всего режимы "сам движение не продолжает" можно будет включить в рабочий диапазн в том случае, если стартовать мотор не сразу на максимальной скорости, а применить к нему плавное ускорение. Сопротивление при вращении мотор все равно оказывает, стопор может произойти только при полной остановке.

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

https://github.com/sadr0b0t/stepper_h/blob/master/test-sketches/step_dir_test/step_dir_test.ino

//
// 1/1 (___)

// 1/1: пищит и не крутится (и не раскручивается)
//int step_delay_us = 500;

// 1/1: гудит и не крутится (условно можно раскрутить - с нескольких проворотов)
//int step_delay_us = 600;
//int step_delay_us = 900;

// 1/1: гудит и не крутится (можно раскрутить)
//int step_delay_us = 1000;
//int step_delay_us = 1300;

// 1/1: крутится ок, если притормозить, то может не продолжить
//int step_delay_us = 1400;

// 1/1: крутится ок, если притормозить, то продолжает полюбому
//int step_delay_us = 1500;

//
// 1/2 (|__)

// 1/2: пищит и не крутится (и не раскручивается)
//int step_delay_us = 300;

// 1/2: гудит и не крутится (условно можно раскрутить - с нескольких проворотов)
//int step_delay_us = 400;

// 1/2: гудит и не крутится (можно раскрутить)
//int step_delay_us = 500;
//int step_delay_us = 610;

// 1/2: крутится ок, если притормозить, то может не продолжить
//int step_delay_us = 620;
//int step_delay_us = 640;

// 1/2: крутится ок, если притормозить, то продолжает полюбому
//int step_delay_us = 650;

//
// 1/4 (_|_)

// 1/4: пищит и не крутится (и не раскручивается)
//int step_delay_us = 100;

// 1/4: гудит и не крутится (условно можно раскрутить - с нескольких проворотов)
//int step_delay_us = 200;

// 1/4: гудит и не крутится (можно раскрутить)
//int step_delay_us = 250;
//int step_delay_us = 310;

// 1/4: крутится ок, если притормозить, то может не продолжить
//int step_delay_us = 320;

// 1/4: крутится ок, если притормозить, то продолжает полюбому
//int step_delay_us = 330;

//
// 1/8 (||_)

// 1/8: пищит-гудит и не крутится (и не раскручивается)
//int step_delay_us = 50;

// 1/8: гудит и не крутится (условно можно раскрутить - с нескольких проворотов)
//int step_delay_us = 80;
//int step_delay_us = 110;

// 1/8: гудит и не крутится (можно раскрутить)
//int step_delay_us = 120;
//int step_delay_us = 150;

// 1/8: крутится ок, если притормозить, то может не продолжить
//int step_delay_us = 160;

// 1/8: крутится ок, если притормозить, то продолжает полюбому
// (оптимальный вариант)
//int step_delay_us = 180;

//
// 1/16 (__|)

// 1/16: пищит-гудит и не крутится (и не раскручивается)
//int step_delay_us = 25;

// 1/16: гудит и не крутится (условно можно раскрутить - с нескольких проворотов)
//int step_delay_us = 40;
//int step_delay_us = 50;

// 1/16: гудит и не крутится (можно раскрутить)
//int step_delay_us = 60;

// 1/16: крутится ок, если притормозить, то может не продолжить
//int step_delay_us = 70;

// 1/16: крутится ок, если притормозить, то продолжает полюбому
// (оптимальный вариант)
//int step_delay_us = 80;

//
// 1/32 (|||)

// 1/32: пищит и не крутится (и не раскручивается)
//int step_delay_us = 10;

// 1/32: гудит и не крутится (условно можно раскрутить - с нескольких проворотов)
//int step_delay_us = 20;

// 1/32: гудит и не крутится (можно раскрутить)
//int step_delay_us = 30;

// 1/32: крутится ок, если притормозить, то продолжает полюбому
// (оптимальный вариант)
//int step_delay_us = 40;
sadr0b0t commented 7 years ago

Посчитаем максимальные скорости

1/1: 1500мкс/шаг (оптимальный стабильный вариант) 1500мкс/шаг*200шагов/оборот=300000мкс/об=300млс/об=0.3с/об макс.ск = 1/0.3об/сек = 3.3 об/сек

1/1: 1000мкс/шаг (крутит с толчка) 1000мкс/шаг*200шагов/оборот=200000мкс/об=200млс/об=0.2с/об макс.ск=1/0.2 = 5 об/сек

1/2: 650мкс/шаг (стабильный вариант) 650мкс/шаг*400шагов/оборот=260000мкс/об=260млс/об=0.260с/об макс.ск=1/0.260об/с = 3.8 об/сек

1/4: 330мкс/шаг (стабильный вариант) 330мкс/шаг*800шагов/оборот=264000мкс/об=264млс/об=0.264с/об макс.ск=1/0.264об/с = 3.8 об/сек

1/8: 180мкс/шаг (стабильный вариант) 180мкс/шаг*1600шагов/оборот=288000мкс/об=288млс/об=0.288с/об макс.ск=1/0.288об/с = 3.8 об/сек

1/16: 80мкс/шаг (стабильный вариант) 80мкс/шаг*3200шагов/оборот=256000мкс/об=256млс/об=0.256с/об макс.ск=1/0.256об/с = 3.9 об/сек

1/32: 60мкс/шаг (медленнее, чем лучший стабильный вариант, но держит 3 мотора на ChipKIT с PIC32MX) 60мкс/шаг*6400шагов/оборот=384000мкс/об=384млс/об=0.384с/об макс.ск=1/0.384об/сек = 2.6 об/сек

1/32: 40мкс/шаг (стабильный вариант, 2 мотора на ChipKIT с PIC32MX) 40мкс/шаг*6400шагов/оборот=256000мкс/об=256млс/об=0.256с/об макс.ск=1/0.256об/с = 3.9 об/сек

1/32: 30 мкс/шаг (чуть менее стабильный, чем 40 - самый быстрый из рабочих) 30мкс/шаг*6400шагов/оборот=192000мкс/об=192млс/об=0.192с/об макс.ск=1/0.192об/сек = 5.2 об/сек

В итоге получили, что примерная скорость на стабильных режимах на всех делителях получается в районе ~4об/сек.

sadr0b0t commented 7 years ago

Посчитаем длину шага и скорость для ременной передачи.

Берем шкив GT2:

типа такого https://ru.aliexpress.com/item/2GT-timing-belt-wheel-16-teeth-20-teeth-width-6mm-inner-hole-5-8mm-for-DIY/32728094223.html?spm=a2g0v.10010108.1000016.1.fb88affc9Zvzz&isOrigTitle=true

По логике вещей полная длина окружности шкива будет L=2мм*20зубов=40мм

т.е. за полный оборот мотор переместит 40мм (=40000мкм) длины ремня.

Длина шага будет:

Некоторые варианты скорости (для наглядности габаритов: A4:210×297 мм)

1/1: 1500мкс/шаг (оптимальный стабильный вариант) макс.ск = 3.3 об/сек макс.ск (шкив) = 40000мкм/об * 3.3об/с= 132000мкм/с = 132 мм/с = 13.2 см/с

1/2: 650мкс/шаг (стабильный вариант) макс.ск = 3.8 об/сек макс.ск (шкив) = 40000мкм/об * 3.8об/с = 152000мкм/с = 152 мм/с = 15.2 см/с

1/4: 330мкс/шаг (стабильный вариант) макс.ск = 3.8 об/сек макс.ск (шкив) = 40000мкм/об * 3.8об/с = 152000мкм/с = 152 мм/с = 15.2 см/с

1/8: 180мкс/шаг (стабильный вариант) макс.ск = 3.8 об/сек макс.ск (шкив) = 40000мкм/об * 3.8об/с = 152000мкм/с = 152 мм/с = 15.2 см/с

1/16: 80мкс/шаг (стабильный вариант) макс.ск = 3.9 об/сек мкс.ск (шкив) = 40000мкм/об * 3.9об/с = 156000мкм/с = 156 мм/с = 15.6 см/с

1/32: 60мкс/шаг (медленнее, чем лучший стабильный вариант, но держит 3 мотора на ChipKIT с PIC32MX) макс.ск = 2.6 об/сек макс.ск (шкив) = 40000мкм/об * 2.6об/с= 104000мкм/с = 104 мм/с = 10.4 см/с

1/32: 40мкс/шаг (стабильный вариант, 2 мотора на ChipKIT с PIC32MX) макс.ск = 3.9 об/сек мкс.ск (шкив) = 40000мкм/об * 3.9об/с = 156000мкм/с = 156 мм/с = 15.6 см/с

1/32: 30мкс/шаг (чуть менее стабильный, чем 40 - самый быстрый из рабочих) макс.ск = 5.2 об/сек макс.ск (шкив) = 40000мкм/об * 5.2об/с= 208000мкм/с = 208 мм/с = 20.8 см/с

// 1/1, 132 mm/s
int _step_delay_us = 1500; // us
int _dist_per_step = 200000; // nm
init_stepper(&sm_x, 'x', STEP_PIN, DIR_PIN, EN_PIN, false, _step_delay_us, _dist_per_step);

// 1/2, 152 mm/s
int _step_delay_us = 650; // us
int _dist_per_step = 100000; // nm
init_stepper(&sm_x, 'x', STEP_PIN, DIR_PIN, EN_PIN, false, _step_delay_us, _dist_per_step);

// 1/4, 152 mm/s
int _step_delay_us = 330; // us
int _dist_per_step = 50000; // nm
init_stepper(&sm_x, 'x', STEP_PIN, DIR_PIN, EN_PIN, false, _step_delay_us, _dist_per_step);

// 1/8, 152 mm/s
int step_delay_us = 180; // us
int dist_per_step = 25000; // nm
init_stepper(&sm_x, 'x', STEP_PIN, DIR_PIN, EN_PIN, false, _step_delay_us, _dist_per_step);

// 1/16, 156 mm/s
int step_delay_us = 80; // us
int dist_per_step = 12500; // nm
init_stepper(&sm_x, 'x', STEP_PIN, DIR_PIN, EN_PIN, false, _step_delay_us, _dist_per_step);

// 1/32, 104 mm/s
int step_delay_us = 60; // us
int dist_per_step = 6250; // nm
init_stepper(&sm_x, 'x', STEP_PIN, DIR_PIN, EN_PIN, false, _step_delay_us, _dist_per_step);

// 1/32, 156 mm/s
int step_delay_us = 40; // us
int dist_per_step = 6250; // nm
init_stepper(&sm_x, 'x', STEP_PIN, DIR_PIN, EN_PIN, false, _step_delay_us, _dist_per_step);
sadr0b0t commented 7 years ago

Короче, я косяк.

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

void loop() {
    digitalWrite(STEP_PIN, HIGH);
    delayMicroseconds(step_delay_us);
    digitalWrite(STEP_PIN, LOW);
    delayMicroseconds(step_delay_us);
}

таким образом на 1 шаг реальная задержка получалась *step_delay_us2**, т.е. все найденные значения минимальной задержки step_delay_us нужно умножить на 2, а лучше еще раз перепроверить.

Правильный код:

void loop() {
    digitalWrite(STEP_PIN, HIGH);
    delayMicroseconds(10);
    digitalWrite(STEP_PIN, LOW);
    delayMicroseconds(step_delay_us-10);
}

Во-вторых, у меня неправильно стояли джамперы для делителя шага.

Правильные позиции:

// количество шагов в полном обороте
// (M0 M1 M2) -> (|||)

// 1/1 (___)
int step_count = 200;
// 1/2 (|__)
//int step_count = 400;
// 1/4 (_|_)
//int step_count = 800;
// 1/8 (||_)
//int step_count = 1600;
// 1/16 (__|)
//int step_count = 3200;
// 1/32 (|||)
//int step_count = 6400;

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

sadr0b0t commented 7 years ago

готово, нах https://github.com/1i7/stepper_h/commit/4f941bd54375d0874068838d008ce8c3148cad7c