في هذا الدرس سنتعلّم كيفية استخدام متحكم PID (Proportional-Integral-Derivative) مع الأردوينو. المتحكم PID هو خوارزمية تحكم ذكية تُستخدم للحفاظ على قيمة معينة في النظام بدقة عالية، مثل التحكم في زاوية الميل، السرعة، أو درجة الحرارة.
ما هو متحكم PID؟
متحكم PID هو نظام تحكم يستخدم ثلاثة مكونات رئيسية للوصول إلى القيمة المطلوبة (Setpoint) بأقل خطأ وأسرع استجابة:
- P - Proportional (التناسبي): يتناسب مع الخطأ الحالي
- I - Integral (التكاملي): يتناسب مع مجموع الأخطاء السابقة
- D - Derivative (التفاضلي): يتناسب مع معدل تغير الخطأ
معادلة متحكم PID
المعادلة الأساسية لمتحكم PID هي:
مكونات المتحكم بالتفصيل
1. المكون التناسبي (P)
يحسب الخطأ الحالي ويضربه في معامل Kp. كلما زاد الخطأ، زادت قوة التصحيح.
- Kp كبير: استجابة سريعة لكن قد يسبب تذبذبات
- Kp صغير: استجابة بطيئة لكن أكثر استقراراً
2. المكون التكاملي (I)
يجمع الأخطاء عبر الزمن ويضربها في معامل Ki. يزيل الخطأ المتبقي على المدى الطويل.
- Ki كبير: يزيل الخطأ المتبقي بسرعة لكن قد يسبب تجاوز
- Ki صغير: تصحيح بطيء للخطأ المستمر
3. المكون التفاضلي (D)
يحسب معدل تغير الخطأ ويضربه في معامل Kd. يقاوم التغيرات السريعة ويقلل التذبذبات.
- Kd كبير: يقلل التذبذبات لكن قد يبطئ الاستجابة
- Kd صغير: استجابة أسرع لكن قد يسمح بتذبذبات
المكونات المطلوبة
- لوحة أردوينو أونو
- مستشعر MPU6050 (لقياس الزاوية الحالية)
- ممحرك بدون فرش 1000KV
- أسلاك توصيل (Jumper Wires)
- بطارية LiPo 3S
برمجة الأردوينو
استخدم الكود التالي لتطبيق متحكم PID:
// معاملات PID (يجب ضبطها حسب النظام)
float Kp = 1.0; // معامل التناسبي
float Ki = 0.5; // معامل التكاملي
float Kd = 0.1; // معامل التفاضلي
// متغيرات PID
float integral = 0.0;
float derivative = 0.0;
float controlOutput = 0.0;
float previousError = 0.0;
float setpoint = 0.0; // القيمة المطلوبة (الهدف)
float currentAngle = 5.0; // القراءة الحالية من المستشعر
// متغيرات الوقت
unsigned long currentTime;
unsigned long previousTime;
float deltaT;
void setup() {
// إضافة: معايرة ESC إذا كنت تستخدم محرك Brushless
// إضافة: تهيئة ومعايرة MPU6050
previousTime = millis();
}
void loop() {
// الخطوة 0: حساب الزاوية الحالية من المستشعر
// TODO: استبدل هذا بقراءة فعلية من MPU6050
// currentAngle = readMPU6050Angle();
// الخطوة 1: حساب الفرق
float error = setpoint - currentAngle;
// الخطوة 2: حساب الفارق الزمني
currentTime = millis();
deltaT = (currentTime - previousTime) / 1000.0; // تحويل إلى ثوانٍ
previousTime = currentTime;
// الخطوة 3: حساب المكون التكاملي
integral = integral + (error * deltaT);
// تحديد المكون التكاملي لمنع التراكم الزائد (Anti-windup)
float integralMax = 100.0;
if (integral > integralMax) integral = integralMax;
if (integral < -integralMax) integral = -integralMax;
// الخطوة 4: حساب المكون التفاضلي
derivative = (error - previousError) / deltaT;
previousError = error;
// الخطوة 5: حساب الخرج النهائي
controlOutput = (Kp * error) + (Ki * integral) + (Kd * derivative);
// تحديد الخرج ضمن نطاق معين
float outputMax = 255.0; // للمحركات DC (PWM)
float outputMin = -255.0;
if (controlOutput > outputMax) controlOutput = outputMax;
if (controlOutput < outputMin) controlOutput = outputMin;
// TODO: استخدم controlOutput للتحكم في المحرك
// مثال: analogWrite(motorPin, abs(controlOutput));
// طباعة القيم للمراقبة
delay(10); // تأخير 10 ميلي ثانية (100 Hz)
}
خطوات التطبيق العملي
- قم بتوصيل المستشعر (مثل MPU6050) لقراءة القيمة الحالية
- قم بتوصيل المحرك أو المشغل الذي تريد التحكم فيه
- حمّل الكود على الأردوينو
- ابدأ بضبط معاملات PID (انظر القسم التالي)
ضبط معاملات PID (Tuning)
ضبط معاملات PID هو أهم خطوة للحصول على أداء جيد. اتبع هذه الطريقة البسيطة:
طريقة Ziegler-Nichols المبسطة:
- ابدأ بصفر: اضبط جميع المعاملات على صفر
Kp=0, Ki=0, Kd=0 - زد Kp تدريجياً: زد قيمة Kp حتى يبدأ النظام بالتذبذب بشكل مستمر
- اضبط Ki: زد Ki قليلاً لإزالة الخطأ المتبقي
- أضف Kd: زد Kd لتقليل التذبذبات
Kp = 0.1, Ki = 0.01, Kd = 0.001 ثم اضبطها بناءً على الاستجابة.
جدول تأثير المعاملات
| المعامل | زيادته تؤدي إلى | نقصانه يؤدي إلى |
|---|---|---|
| Kp | استجابة أسرع، تذبذبات أكثر | استجابة أبطأ، استقرار أفضل |
| Ki | إزالة الخطأ المتبقي، قد يسبب تجاوز | خطأ متبقي طويل المدى |
| Kd | تقليل التذبذبات، قد يبطئ الاستجابة | تذبذبات أكثر، حساسية للضوضاء |
تحسينات على الكود
الكود المقدم يتضمن بعض التحسينات المهمة:
- Anti-windup للمكون التكاملي: يمنع تراكم القيم الزائدة في Integral
- تحديد الخرج (Output Limiting): يحصر الخرج ضمن نطاق آمن
- طباعة القيم: لمراقبة وتحليل أداء المتحكم
التطبيقات العملية
يُستخدم متحكم PID في العديد من المشاريع:
- الروبوتات ذاتية التوازن: للحفاظ على التوازن العمودي
- الطائرات المسيّرة: لتثبيت الزوايا والارتفاع
- التحكم في السرعة: للمحركات والعجلات
- التحكم في درجة الحرارة: للفرن أو الحاضنة
- أنظمة الري الذكية: للتحكم في رطوبة التربة
- الأذرع الآلية: للوصول إلى الموضع المطلوب بدقة
Kp = 15-40, Ki = 0.1-1.0, Kd = 0.5-3.0
لكن هذا يعتمد على وزن وحجم روبوتك، لذا الضبط التجريبي ضروري!
نصائح مهمة
- ابدأ دائماً بقيم صغيرة للمعاملات وزدها تدريجياً
- راقب استجابة النظام باستخدام Serial Monitor أو Serial Plotter
- تأكد من أن قراءات المستشعر دقيقة ومعايرة بشكل صحيح
- استخدم تأخير مناسب (10-20ms) لتجنب التشبع الحسابي
- قد تحتاج لمعاملات مختلفة للظروف المختلفة (حمل مختلف، سرعة مختلفة)
- اختبر النظام في بيئة آمنة أولاً قبل الاستخدام الفعلي
الخلاصة
متحكم PID هو أداة قوية جداً للتحكم في الأنظمة الديناميكية. مع الفهم الصحيح والضبط الدقيق للمعاملات، يمكنك تحقيق تحكم دقيق ومستقر في مشاريعك. تذكر أن ضبط المعاملات يحتاج إلى صبر وتجربة، لكن النتيجة تستحق الجهد!