Перегляд теми - апаратний помножувач кроків (можливість реалізації)

Колеги, а ось таке питання. Мучить мене неможливість маленького мікрошага з великою швидкістю на програмному рівні - мач на 75кГц поводиться вкрай нестабільно, на 100кГц може повіситися намертво, linuxcnc взагалі більше 50кГц не видає, а latency-test показує затримку системи в

7000ns, що дає мені максимум 44кГц на генерацію імпульсів. Коротше, хочу мікрошаг 1/64 або навіть 1/128 на швидкості 5000мм / хв, але без апаратного генератора імпульсів такого домогтися неможливо. Апаратні варіанти я поки доглядаю і потихеньку душу жабу, але цінник на них боляче злий.

Вообщем, ось така ідея виникає, прошу допомоги - чи можливо реалізувати апаратний помножувач кроків на зовнішньому контролері, в ідеалі на Ардуіно?

Для себе я це приблизно уявляю так - в Мачеєм виставляємо бажаний мікрошаг керуючись тільки лише необхідною точністю. Наприклад, нам необхідний 0.01мм на крок, що при 5мм / об = 500 кроків на оборот. Але при цьому на драйвері двигуна ми виставляємо свій жала мікрошаг, наприклад 1/50. Таким чином при швидкості 4500мм / хв (для рівного рахунку) = 75мм / сек = 15 об / сек нам потреуется всього 7500 імп / сек, тобто від софтового драйвера потрібно генерація імпульсів на швидкості 7,5кГц на одну вісь.

Далі ми з лпт порту захоплюємо крок на умножителе (Ардуіно), тобто тупо читаємо стан пінів в змінну до тих пір поки триває імпульс. Після закінчення імпульсу, ми в проміжок до наступного кроку (якщо встигаємо) відтворюємо необхідну кількість імпульсів, тобто наприклад на 1 крок відтворюємо 20 імпульсів, що дає нам мікрошаг 1/50 на виході.

Як думаєте, таке реально?

Re: Апаратний помножувач кроків (можливість реалізації?)

Re: Апаратний помножувач кроків (можливість реалізації?)

Як думаєте, таке реально?


Реально, але є готові драйвера з множником.

Re: Апаратний помножувач кроків (можливість реалізації?)

Мда, все досить сумно.

Ось такий код видає всього 100kHz:

digitalWrite (outPin, LOW);
digitalWrite (outPin, HIGH);

Трохи краще, із застосуванням бітової магії, видає 1000kHz:

7.5кГц, для імітації імпульсів з лпт-порту:

const int outPin = A2;

void setup () pinMode (A2, OUTPUT);
>

void loop () while (1) digitalWrite (outPin, HIGH);
delayMicroseconds (5);
digitalWrite (outPin, LOW);
delayMicroseconds (115);
>
>

Умножитель для 4х осей 1/20, на виході 1/50 (при вихідних 1 / 2.5):

byte outVal = B00000000;

// Лічильники мікрошагов для крокових виходів
// потрібно для підрахунку виконаних дроблень вхідного кроку
//
byte plnCntX = 0;
byte plnCntY = 0;
byte plnCntZ = 0;
byte plnCntA = 0;

// Ознака стану планувальника для крокових виходів
// потрібно для визначення поведінки планувальника при зміні входу
//
boolean plnRunX = 0;
boolean plnRunY = 0;
boolean plnRunZ = 0;
boolean plnRunA = 0;

// Попереднє і поточний стан входу
// знадобиться для планування такту
//
byte inpValPrv = B00000000;
byte inpValCur = B00000000;

void setup () pinMode (30, OUTPUT);
pinMode (29, INPUT);
Serial.begin (9600);
>

void loop () // У головного циклу величезні наклание витрати:
// для запобігання виходу встановлюємо точку безумовного переходу
// так, це виглядає досить дивно, але по ідеї нормальний компілятор
// сформує тут jmp, таким чином ми повернемося в цикл з мінімальними втратами
//
stp:
//// Плануємо поточний такт крокових виходів:
//// зчитуємо значення на вході, якщо рівень на вході змінився
//// визначаємо чи є це моментом виникнення, продовження або
//// закінчення кроку
////
inpValCur = PINA;

//// Якщо змінився стан входу
////// і лічильник імпульсів порожній
//////// встановлюємо лічильник імпульсів
//////// встановлюємо ознака
////////. на вході з'явився крок
////////. починаємо формувати мікрошагі
////// якщо лічильник імпульсів не порожній
//////// і є ознака стану
////////// знімаємо ознака
//////////. крок на вході закінчився
//////////. продовжуємо формувати мікрошагі
//////// якщо ознаки немає
////////// все зникло
//////////. не встигли сформувати всі мікрошагі
//////////. в період між двома кроками

if ((inpValCur B10000000)! = (InpValPrv B10000000)) if (! PlnCntX) plnCntX = 20;
plnRunX = 1;
> Else if (plnRunX) plnRunX = 0;
> Else goto dbg;
>
>
>

if ((inpValCur B01000000)! = (InpValPrv B01000000)) if (! PlnCntY) plnCntY = 20;
plnRunY = 1;
> Else if (plnRunY) plnRunY = 0;
> Else goto dbg;
>
>
>

if ((inpValCur B00100000)! = (InpValPrv B00100000)) if (! PlnCntZ) plnCntZ = 20;
plnRunZ = 1;
> Else if (plnRunZ) plnRunZ = 0;
> Else goto dbg;
>
>
>

if ((inpValCur B00010000)! = (InpValPrv B00010000)) if (! PlnCntA) plnCntA = 20;
plnRunA = 1;
> Else if (plnRunA) plnRunA = 0;
> Else goto dbg;
>
>
>

//// Формуємо рівень чергового імпульсу для крокових виходів:
//// якщо лічильник імпульсів трохи порожній інвертуємо рівень на
//// відповідному виході і зменшуємо лічильник імпульсів
////
if (plnCntX) PORTC = PORTC ^ B10000000;
plnCntX--;
>

if (plnCntY) PORTC = PORTC ^ B01000000;
plnCntY--;
>

if (plnCntZ) PORTC = PORTC ^ B00100000;
plnCntZ--;
>

if (plnCntA) PORTC = PORTC ^ B00010000;
plnCntA--;
>

//// Формуємо сигнал для виходів не потребують обробки:
//// просто копіюємо поточні значення зі входу
////
outVal = inpValCur B00001111;

//// Записуємо отримані значення виходів в порт
//// в наступний момент на вихід будуть подані якісь сигнали
////
PORTC = outVal;

//// Для рівномірного розмазування мікрошагов всередині кроку, підібрано емпірично
//// по хорошому треба вирахувати
delayMicroseconds (2);

//// При такому плануванні імпульсів ширина низького сигналу буде

=
//// ширині високого, тобто драйвер зможе визначати імпульс до тих пір,
//// поки значення дроблення кроку знаходиться в допустимих межах. кмк
////
goto stp;

//// Тривога, тривога, вовк вкрав зайчат!
dbg:
Serial.print ( "ERR");
Serial.print ( "\ t");
Serial.print (outVal, BIN);
Serial.print ( "\ t");
Serial.print (inpValPrv, BIN);
Serial.print ( "\ t");
Serial.print (inpValCur, BIN);
Serial.print ( "\ t");
Serial.print (plnCntX);
Serial.print ( "\ t");
Serial.print (plnRunX);
Serial.print ( "\ n");
plnCntX = 0;
plnRunX = 0;
>

Якщо хто підкаже, де тут можна викроїти трошки тактів, буду радий.

Схожі статті