في البداية ، أردت فقط إعادة تحميله ، ولهذا الغرض حصلت على رموز المصدر لمشروع Grbl CNC. لكن الفضول تغلب وانغمست في دراسة هذه المصادر ...
فهي تبني أسلوبًا بسيطًا ومنطقيًا للغاية ، لكن
في الواقع ، فكرة جهاز التحكم في آلة CNC بسيطة للغاية ومثيرة للاهتمام. هناك العديد من خيوط المعالجة - واحد يقرأ البيانات (gcode) ويوزعها ، والثاني يحول الأوامر إلى كتل تنفيذ ، والثالث (السائر) ينفذ هذه الكتل بالفعل. سيتم مناقشة هذا التيار الثالث.
يتعامل السائر مع قائمة من الأوامر الفردية للنموذج - اتخذ خطوات (X ، Y ، Z) لجميع المحركات السائر الثلاثة (على الأقل) ، وفي وقت محدد وفي اتجاه محدد (حسنًا ، هذا بسيط جدًا). يجب أن أقول إن المحرك المتدرج مع سائقه هو شيء بسيط للغاية للتحكم - يمكنك ضبط (0 أو 1) اتجاه الدوران ثم يحاول المحرك أن يخطو خطوة واحدة بفارق إدخال إيجابي (0 -> 1) (وعادة ما تكون هناك 200 خطوة لكل ثورة). تم إعداد البيانات بالفعل ، لذلك تحتاج فقط إلى ربط الأعداد الصحيحة الثلاثة بطريقة أو بأخرى بالوقت المحدد.
في الأصل ، استخدم المؤلف وحدة التحكم atmega328p ، ولكن بدون أي تغييرات عمليًا ، يمكن نقل كل شيء بسهولة إلى الذراع (على سبيل المثال ، stm32). لكن الخوارزمية نفسها لا يمكنها إلا أن تثير الأسئلة.
من ناحية أخرى ، يتم استخدام خوارزمية Bresenham المثالية للغاية ، أو بالأحرى نسختها من Adaptive Multi-Axis Step-Smoothing. ولكن من ناحية أخرى ، كل شيء معقد بطريقة ما والأهم من ذلك أن نعومة محرك السائر ودقة جهاز التوجيه تعتمد بشكل مباشر على دقة إشارات التحكم. في هذه الحالة ، يرجع هذا إلى التردد الذي يعمل فيه المؤقت ووقت معالجة المقاطعة - وهذا لا يعطي أكثر من 40-50 كيلو هرتز في أحسن الأحوال ، وعادة ما يكون أقل - حسنًا ، أي أن دقة إعداد التحكم هي 20-50 ميكروثانية.
ولكن من الواضح تمامًا أنه عندما نعالج أمرًا واحدًا من المخزن المؤقت ، نحتاج فقط إلى حساب لحظات تبديل الإشارة عند منفذ الإخراج وهذه اللحظات وإجراء التبديل.
نظرًا لأنني كنت أفكر في التبديل إلى cortex-m (حسنًا ، بشكل أكثر دقة ، إلى stm32h750 ، والذي أحبه كثيرًا والذي أصبح أرخص جدًا) ، يمكن حل هذه المهمة على الإطلاق دون إشراك وحدة المعالجة المركزية ، فقط باستخدام قناتين DMA وعداد واحد 32 بت.
الفكرة بسيطة جدا. اسمح لقناة واحدة بكتابة بيانات جديدة إلى المنفذ عند تجاوز العداد ، وتكتب القناة الثانية قيمة عداد قصوى جديدة (من المعقول القيام بذلك في أول دورة ساعة للعداد). بعد ذلك ، لمعالجة الأمر من القائمة ، تحتاج إلى التحضير لمجموعة من قيم التغيير للمنفذ والمهلة بينها.
سوف يتحول إلى شيء مثل هذا.
معالجة المقاطعة - التبديل إلى مخزن مؤقت جديد (تخزين مؤقت مزدوج).
#define MAX_PGM 32
typedef struct _pgm_buffer {
uint32_t data[MAX_PGM];
uint32_t delta[MAX_PGM];
} pgm_buffer;
pgm_buffer buf[2];
uint32_t current_buf = 1;
uint32_t flags = 0;
void program_down(DMA_HandleTypeDef *_hdma) {
TIM2->CR1 &= ~TIM_CR1_CEN;
if ((flags & BUF_RUNNING) == 0)
return;
current_buf ^= 1;
DMA1_Channel5->CCR &= ~1;
DMA1_Channel2->CCR &= ~1;
DMA1_Channel5->CNDTR = MAX_PGM;
DMA1_Channel2->CNDTR = MAX_PGM;
DMA1_Channel5->CMAR = (uint32_t) (buf[current_buf].delta);
DMA1_Channel2->CMAR = (uint32_t) (buf[current_buf].data);
DMA1_Channel5->CCR |= 1;
DMA1_Channel2->CCR |= 1;
TIM2->CNT = 0;
TIM2->ARR = 8;
TIM2->EGR |= TIM_EGR_UG;
TIM2->CR1 |= TIM_CR1_CEN;
}
يمكنك البدء بهذه الطريقة:
HAL_DMA_RegisterCallback(&hdma_tim2_up, HAL_DMA_XFER_CPLT_CB_ID,
program_down);
HAL_DMA_Start_IT(&hdma_tim2_up, buf, &GPIOA->BSRR, MAX_PGM);
DMA1_Channel5->CCR &= ~1;
DMA1_Channel5->CPAR = &TIM2->ARR;
DMA1_Channel5->CCR |= 1;
TIM2->CCR1 = 1;
TIM2->DIER |= TIM_DIER_UDE | TIM_DIER_CC1DE;
flags |= BUF_RUNNING;
حسنًا ، البداية هي:
program_down(NULL);
ماذا تعمل، أو ماذا تفعل؟ دعنا نحسب باستخدام مثال نفس stm32h750. يعمل المؤقت (TIM2) هناك بتردد 200 ميجاهرتز ، والحد الأدنى للكمون هو دورتان على مدار الساعة ، لكن DMA لا يمكنه إرسال البيانات أسرع من 50 ميجاهرتز ، أي بين أمرين لتبديل المنفذ ، يمكنك وضع (مع الأخذ في الاعتبار التوظيف المحتمل للناقل) 40 nsec (25 MHz) - هذا هو 1000 مرة أفضل من التنفيذ الأصلي!
من ناحية أخرى ، يبلغ عرض المنفذ 16 بتًا ، بحيث يمكنك التحكم في 8 محركات متدرجة في نفس الوقت بدلاً من 3 ،
في هذه الحالة ، لا يتسبب ملء البيانات نفسها في حدوث مشكلات (مع هذا القرار!) - استيفاء خطي بسيط لكل محرك على حدة باستخدام من خلال الجمع بين (للتحسين) أحداث أقرب من 40 نانوثانية.
الاستنتاجات الفعلية.
يوجد بالورشة آلة CNC نهائية بقياس 1.2 متر × 0.8 متر بمحركات ومحركات ، ولكن بدون جهاز تحكم. يبدو أننا بحاجة إلى إنهاء المهمة وتجربتها لمعرفة مدى ملحمة الأمر. إذا فعلت ذلك ، سأكتب بالتأكيد تكملة. في غضون ذلك ، لا أفهم سبب قيام وحدات التحكم بذلك على atmega وهم يصدرون صريرًا على جميع الطابعات ثلاثية الأبعاد وأجهزة التوجيه باستخدام الحاسب الآلي على هذه المقاطعات الخشنة ...
وبالطبع ، من المحتمل أن يكون لديك قوة Cortex-M7 ، يمكنك تنفيذ تحكم أكثر سلاسة في المسار مع كل القيود ، لكن هذه مقالة مختلفة تمامًا.
ملاحظة: على ما يبدو ، من الضروري إعطاء بعض الأمثلة الافتراضية عن سبب أهمية قضاء مثل هذا الوقت القصير.
لنفترض أن الآلة تحتاج إلى تحريك 100 مم في X و 11 مم في Y ، وقام البرنامج بتقسيمها جميعًا إلى أقسام تسارع وحركة موحدة - هناك العديد من الأقسام المكونة من 100 خطوة بـ 11 خطوة ويتم اجتيازها بأقصى سرعة ، دعها تتوافق مع 10 كيلو هرتز. حسنًا ، 10 خطوات في Y سوف تتناسب تمامًا مع 100 خطوة في X ، ولكن قد تحدث مشكلة للخط الحادي عشر - يمكن تخطيها ، لأنها تسبب مضاعفة التردد. ونتيجة لذلك ، ستكون الحركة 100 مم في X ومن 10 إلى 11 مم في Y. وهذا مع الحركة الخطية ، حيث ، في الواقع ، حتى القيود على التسارع والسرعات المسموح بها بسيطة. وإذا تم ذلك بشكل متعرج؟ حسنًا ، على سبيل المثال ، هناك تجتاح لمساحة 100 × 110 مم في 10 ممرات - ثم نفتقد كثيرًا بشكل عام ...
يتم استخدام الخوارزمية المقترحة لإزالة هذا الخطأ ، وليس على الإطلاق للمطاحن الفائقة ، إلخ.