يحتوي هذا المقال على روابط تسويق بالعمولة مُعلَّمة بعلامة *. بصفتي شريكًا في برنامج Amazon Associates، أربح من عمليات الشراء المؤهلة، دون أي تكلفة إضافية عليك. يساعد ذلك على إبقاء الشروحات مجانية.
ملخص سريع
يتتبع هذا الروبوت خطًا أبيض على خلفية داكنة. ويستخدم مستشعرَين من نوع KY-033 لتتبع الخط بالأشعة تحت الحمراء، ولوحة Arduino Uno، ودرع المحركات Arduino Motor Shield Rev3. تطبع الهيكل بالطباعة ثلاثية الأبعاد، وتوصّل المكونات الإلكترونية، وتكتب منطق توجيه بجمل if/else لإشارتَي المستشعرين الرقميتين. تنفّذ جملة if/else إجراءً عندما يكون الشرط صحيحًا وإجراءً آخر عندما يكون خاطئًا. يُخرج كل مستشعر القيمة HIGH أو LOW، وتحدد أربع حالات في الكود هل يسير الروبوت مستقيمًا، أم ينعطف انعطافًا محوريًا (يستدير تقريبًا في مكانه)، أم يدور حول نفسه في مكانه. هذه النسخة هي المرحلة التي تسبق التحكم PID (التحكم التناسبي التكاملي التفاضلي، الذي يجعل مقدار تصحيح التوجيه متناسبًا مع مقدار ابتعاد الروبوت عن الخط).

كيف يعمل الروبوت
يجمع الروبوت بين اكتشاف الخط بالأشعة تحت الحمراء والتوجيه التفاضلي. فهو لا يملك محور توجيه، بل يغيّر اتجاهه بتدوير عجلته اليسرى وعجلته اليمنى بسرعتين مختلفتين أو في اتجاهين متعاكسين. تقع عجلتا الدفع في الخلف، وتحمل مقدمةَ الهيكل عجلةٌ حرة الدوران (Caster) في الأمام، بين المستشعرين. ويُقصد باليسار واليمين في هذا المقال الجهتان كما تظهران من خلف الروبوت في اتجاه حركته.
Arduino Uno (وحدة التحكم)
Arduino Uno يقرأ إشارتَي المستشعرين، وينفّذ منطق اتخاذ القرار، ويضبط إشارات المحركات. إذا لم تبرمج Arduino من قبل، فابدأ بقراءة درس أساسيات برمجة Arduino.
Arduino Motor Shield Rev3 (وحدة قيادة المحركات)
يُركَّب درع المحركات Motor Shield Rev3 فوق لوحة Uno مباشرة. وتحتوي شريحة L298P فيه على جسرَي H (H-bridge، وهي دارات تبديل يمكنها عكس اتجاه التيار المار في المحرك). تغذّي البطارية المحركات عبر الدرع، ولا يرسل Arduino سوى إشارات التحكم: طرف (Pin) للاتجاه وطرف للسرعة بتقنية PWM (تعديل عرض النبضة) لكل محرك. لمزيد من التفاصيل حول قيادة المحركات، راجع دليل وحدة قيادة المحركات L298N، الذي يشرح التحكم في محركات التيار المستمر بالتفصيل.
مستشعران من نوع KY-033 لتتبع الخط
تحتوي كل وحدة KY-033 على LED يعمل بالأشعة تحت الحمراء، ومستقبِل للأشعة تحت الحمراء، ومقارِن (Comparator)، وهو شريحة صغيرة تقارن بين جهدين. يسلّط الـ LED ضوءه على السطح: فالسطح الأبيض يعكس معظم الضوء، والسطح الداكن يمتصه. يقارن المقارِن إشارة المستقبِل بعتبة تضبطها بالمقاومة المتغيرة (Potentiometer، أي برغي الضبط الصغير على اللوحة)، ثم يحوّل طرف الخرج إلى HIGH أو LOW. تُخرج وحدة KY-033 المعتادة القيمة LOW (0) عندما يعكس السطح الضوء (الشريط الأبيض)، والقيمة HIGH (1) عندما يمتصه (الخلفية الداكنة). أدِر المقاومة المتغيرة حتى يتبدّل الخرج بثبات بين الخط والخلفية عند ارتفاع التركيب الذي اخترته.
مهم: يتتبع هذا المشروع خطًا أبيض على خلفية داكنة. لتتبع خط أسود على خلفية بيضاء، بدّل 1 و0 في شروط if داخل الدالة loop().
منطق التوجيه
يقع المستشعران خارج حافتَي الشريط بقليل، واحد على كل جانب. عندما يكون الروبوت في المنتصف، يرى كلاهما الخلفية الداكنة ويقرأ 1. يوضح الجدول ما يفعله الكود في كل حالة من الحالات الأربع: الاتجاه والسرعة اللذين يرسلهما إلى كل محرك. القيمة HIGH تعني الحركة إلى الأمام، والقيمة LOW تعني الحركة إلى الخلف؛ أما السرعة فهي قيمة PWM من 0 (متوقف) إلى 255 (السرعة القصوى).
| المستشعر الأيسر | المستشعر الأيمن | الإجراء | المحرك الأيسر (الاتجاه، السرعة) | المحرك الأيمن (الاتجاه، السرعة) |
|---|---|---|---|---|
| 1 | 1 | السير مستقيمًا | HIGH, 105 | HIGH, 105 |
| 1 | 0 | الانعطاف المحوري إلى اليمين | HIGH, 105 | LOW, 85 |
| 0 | 1 | الانعطاف المحوري إلى اليسار | LOW, 85 | HIGH, 105 |
| 0 | 0 | الدوران في المكان إلى اليمين | HIGH, 70 | LOW, 70 |
في الانعطاف المحوري، تدور إحدى العجلتين إلى الأمام والأخرى إلى الخلف. إذا انحرف الروبوت إلى اليسار، يصل المستشعر الأيمن إلى الشريط ويقرأ 0، فينعطف الروبوت محوريًا إلى اليمين عائدًا نحو الخط. ويحدث الأمر نفسه مع المستشعر الأيسر عند الانحراف إلى اليمين. لا تكون القراءتان 0 معًا إلا عندما يكون المستشعران فوق الشريط في الوقت نفسه، كأن يعبره الروبوت بزاوية مائلة عند منعطف. عندها يستمر الدوران في المكان حتى تتغير إحدى القراءتين. وإذا خرج الروبوت عن الخط تمامًا، يقرأ المستشعران 1 مجددًا ويواصل الروبوت السير مستقيمًا.
قائمة المواد
معظم القطع مكونات Arduino قياسية؛ أما القطع المطبوعة فمصممة خصيصًا لهذا المشروع. وهي متوفرة كملفات STL، وهي صيغة النماذج ثلاثية الأبعاد التي تقرؤها برامج الطباعة ثلاثية الأبعاد.
| المكوّن | الكمية | مطلوب | الغرض | ملاحظات |
|---|---|---|---|---|
| Arduino Uno | 1 | نعم | يقرأ المستشعرات وينفّذ منطق التوجيه | تصلح أي لوحة متوافقة مع Uno |
| Arduino Motor Shield Rev3 | 1 | نعم | يقود محركَي التيار المستمر | يُركَّب فوق لوحة Uno |
| مستشعر تتبع الخط KY-033 | 2 | نعم | يكتشف الخط من انعكاس الأشعة تحت الحمراء | تُضبط العتبة بالمقاومة المتغيرة المدمجة في اللوحة |
| محرك تيار مستمر بعلبة تروس | 2 | نعم | يدير العجلتين اليسرى واليمنى | محرك TT أصفر بعلبة تروس (النوع الشائع منخفض التكلفة للروبوتات الصغيرة)، من 3 إلى 6 V |
| العجلات | 2 | نعم | عجلات الدفع | يجب أن تناسب عمود المحرك |
| عجلة حرة الدوران (Caster) | 1 | نعم | الدعامة الأمامية | عجلة كروية حرة أو عجلة دوّارة صغيرة |
| هيكل مطبوع بالطباعة ثلاثية الأبعاد | 1 | نعم | لوح قاعدة للمحركات والعجلة الحرة والمستشعرات وArduino والبطارية، مع غطاء في الأعلى | ملفا STL (القاعدة والغطاء)، 170 × 149 mm |
| مباعِدات للمستشعرات مطبوعة بالطباعة ثلاثية الأبعاد | 2 | نعم | تثبّت مستشعرات KY-033 أسفل مقدمة الهيكل | واحد لكل مستشعر، بارتفاع 13.5 mm |
| مباعِدات للوحة Arduino مطبوعة بالطباعة ثلاثية الأبعاد | 4 | نعم | تُبقي لوحة Uno والدرع مرفوعين فوق لوح القاعدة | واحد لكل ثقب تثبيت في لوحة Uno، بارتفاع 14 mm |
| أسلاك توصيل (Jumper) ذكر-أنثى | 6 | نعم | توصل المستشعرين بلوحة Arduino | ثلاثة لكل مستشعر (S، VCC، GND)؛ أما أسلاك المحركات فتدخل مباشرة في مرابط التوصيل اللولبية في الدرع |
| براغي M3 | عدة | نعم | تثبّت المحركات والمباعِدات على الهيكل | |
| حشوات ملولبة M3 | عدة | نعم | توفّر أسنانًا لولبية لبراغي M3 في القطع المطبوعة | تُكبس في مكانها بكاوية اللحام (انظر 3.1) |
| البطارية | 1 | نعم | تغذّي لوحة Arduino والمحركات | بطارية LiPo بجهد 7.4 V من نوع 2S (بطارية ليثيوم بوليمر، خليتان على التوالي) |
| مفتاح الطاقة | 1 | اختياري | يشغّل الروبوت ويطفئه | مفتاح تبديل (Toggle) مركَّب على سلك + للبطارية |
الخطوة 1: تصميم الروبوت في Autodesk Inventor
صممتُ القطع في Autodesk Inventor. يبلغ طول الهيكل 170 mm وعرضه 149 mm. ويضم المشروع ثلاثة أنواع من القطع المطبوعة:
- الهيكل: لوح قاعدة وغطاء. يحمل لوح القاعدة المحركين والعجلة الحرة والمستشعرين ولوحة Arduino والبطارية؛ ويُركَّب الغطاء في الأعلى.
- مباعِدات المستشعرات: مباعِدان مطبوعان بارتفاع 13.5 mm يثبّتان مستشعرَي KY-033 أسفل مقدمة الهيكل.
- مباعِدات Arduino: أربعة مباعِدات مطبوعة بارتفاع 14 mm تُبقي لوحة Uno ودرع المحركات مرفوعين فوق لوح القاعدة، مع بقاء المنافذ في المتناول للبرمجة والتوصيل.
إذا كنت جديدًا على الطباعة ثلاثية الأبعاد، فاقرأ مقدمة في الطباعة ثلاثية الأبعاد والتصميم ثلاثي الأبعاد (3D) باستخدام Inventor أولًا.
الخطوة 2: الطباعة ثلاثية الأبعاد للمكونات
طبعتُ القطع على طابعة Creality Ender 3. ويناسب خيط PLA (حمض البولي لاكتيك، وهو بلاستيك سهل الطباعة) هذا المشروع. يلين PLA عند نحو 60 °C؛ لذا لا تستخدم ABS (أكريلونيتريل بوتادين ستايرين، وهو بلاستيك طباعة آخر) إلا إذا كان الروبوت سيتعرض لحرارة أعلى. بعد الطباعة، أزل مادة الدعامات (الهياكل المؤقتة التي تبنيها الطابعة تحت الأجزاء البارزة) وأي حواف خشنة. وتأكد من أن ثقوب البراغي وعناصر التثبيت بالمقاس الصحيح قبل أن تبدأ التجميع.
الخطوة 3: تجميع الروبوت
جمّع الروبوت بهذا الترتيب.
3.1 تركيب المحركات والعجلات
- ثبّت محركَي التيار المستمر على الهيكل ببراغي M3. تُربط البراغي في حشوات ملولبة حرارية: وهي جُلَب نحاسية صغيرة ذات سن داخلي تكبسها في الثقوب المطبوعة بكاوية لحام ساخنة، حتى لا تُتلف البراغي البلاستيك. كبستُ جميع الحشوات أولًا قبل تركيب أي قطعة أخرى. تأكد من أن كل محرك مثبت بإحكام وأن المحركين على استقامة واحدة.
- ادفع العجلتين بقوة على عمودَي المحركين، وتأكد من أنهما تدوران دون تذبذب.
- ركّب العجلة الحرة في مقدمة الهيكل.
3.2 تركيب المكونات الإلكترونية
- ثبّت مباعِدات Arduino الأربعة على لوح القاعدة، ثم ركّب لوحة Uno فوقها.
- ركّب درع المحركات Motor Shield Rev3 فوق لوحة Uno بحيث تدخل أطرافه بالكامل في مقابس لوحة Uno (الشرائط السوداء ذات المقابس على امتداد حواف اللوحة).
- ركّب كل مستشعر KY-033 على مباعِده في الجهة السفلية من مقدمة الهيكل، بحيث يتجه المستشعر إلى الأسفل.
- ثبّت البطارية على الهيكل بحيث لا يمكنها الانزلاق؛ استخدمتُ أربطة الكابلات.
الخطوة 4: توصيل المكونات الإلكترونية
تسرد الجداول أدناه كل التوصيلات، ويعرض المخطط التوصيلات نفسها. يمثّل رمز البطارية فيه بطارية 9 V، لكن روبوتي يعمل ببطارية LiPo بجهد 7.4 V.

توصيلات المحركات (عبر درع المحركات)
| المحرك | مربط درع المحركات | طرف Arduino (عبر الدرع) | الوظيفة |
|---|---|---|---|
| محرك التيار المستمر الأيسر | خرج القناة A | DIR_L = الطرف 12، PWM_L = الطرف 3 | اتجاه المحرك الأيسر وسرعته |
| محرك التيار المستمر الأيمن | خرج القناة B | DIR_R = الطرف 13، PWM_R = الطرف 11 | اتجاه المحرك الأيمن وسرعته |
توصيلات مستشعرَي KY-033
VCC هو طرف التغذية، وGND هو الطرف الأرضي (0 V).
| مستشعر KY-033 | طرف المستشعر | طرف Arduino | الوظيفة |
|---|---|---|---|
| المستشعر الأيسر | S (الإشارة) | الطرف الرقمي 2 | قراءة الخط من الجهة اليسرى (HIGH/LOW) |
| المستشعر الأيسر | VCC | 5 V | مزود الطاقة |
| المستشعر الأيسر | GND | GND | الأرضي |
| المستشعر الأيمن | S (الإشارة) | الطرف الرقمي 4 | قراءة الخط من الجهة اليمنى (HIGH/LOW) |
| المستشعر الأيمن | VCC | 5 V | مزود الطاقة |
| المستشعر الأيمن | GND | GND | الأرضي |
توصيلات الطاقة والبطارية
VIN هو مربط دخل الطاقة في درع المحركات. أما مقبس Barrel Jack فهو مقبس الطاقة الدائري في لوحة Arduino Uno.
| التوصيل | من | إلى | ملاحظات |
|---|---|---|---|
| القطب الموجب للبطارية | البطارية + | مربط VIN في درع المحركات (أو مقبس Barrel Jack في Arduino) | يغذّي لوحة Arduino والمحركات |
| القطب السالب للبطارية | البطارية − | مربط GND في درع المحركات | أرضي مشترك |
| مفتاح الطاقة (اختياري) | مركَّب على سلك + للبطارية | لا يوجد مربط منفصل | مفتاح تبديل للتشغيل والإيقاف |
نصيحة حول الطاقة: تعمل بطارية LiPo بجهد 7.4 V على أفضل وجه لأنها توفر جهدًا مستقرًا لكل من لوحة Arduino والمحركات. تصلح بطارية قلوية بجهد 9 V للاختبارات القصيرة، لكنها تنفد بسرعة تحت حمل المحركات وقد تسبب سلوكًا غير منتظم. المحركات مصممة للعمل بجهد من 3 إلى 6 V، بينما تعطي بطارية LiPo جهدًا قدره 7.4 V (و8.4 V عند الشحن الكامل). تُحدث وحدة القيادة L298P في الدرع هبوطًا في الجهد بنحو 2 V، كما أن قيم PWM المستخدمة هنا (من 70 إلى 105 من أصل 255) تخفض متوسط جهد المحرك أكثر. لا تشغّل المحركات على القيمة 255 لفترات طويلة. تحقق من القطبية قبل توصيل البطارية؛ فعكس القطبية قد يُتلف المكونات الإلكترونية. اشحن بطارية LiPo بشاحن موازنة فقط (Balance Charger، وهو شاحن LiPo يحافظ على تساوي جهد الخليتين). وتوقف عن استخدام الحزمة قبل أن ينخفض جهدها إلى أقل من 6.0 V تقريبًا (3.0 V لكل خلية).
الخطوة 5: برمجة روبوت تتبع الخط
إليك برنامج Arduino الكامل (Sketch، وهو مصطلح Arduino للبرنامج). ويضم مستودع GitHub المذكور في قسم التنزيلات الكود الكامل والملفات.

يوضح المخطط الانسيابي الترتيب الذي يفحص به الكود الحالات الأربع. لكن تسمياته وسرعاته في حالتَي الانعطاف المحوري لا تطابق البرنامج؛ ويبيّن الجدول في قسم «كيف يعمل الروبوت» ما يفعله الكود فعلًا.
برنامج Arduino الكامل (Sketch)
/**
* Author: Omar Draidrya
* Date: 2024/12/06
* Line-Following Robot with KY-033.
*/
// Motor control pins
#define DIR_L 12 // Left motor direction
#define DIR_R 13 // Right motor direction
#define PWM_L 3 // Left motor speed (PWM)
#define PWM_R 11 // Right motor speed (PWM)
// Sensor pins
int sensorLeft = 2; // Left sensor
int sensorRight = 4; // Right sensor
void setup() {
// Configure motor pins as outputs
pinMode(DIR_L, OUTPUT);
pinMode(DIR_R, OUTPUT);
pinMode(PWM_L, OUTPUT);
pinMode(PWM_R, OUTPUT);
// Configure sensor pins as inputs
pinMode(sensorLeft, INPUT);
pinMode(sensorRight, INPUT);
// Serial communication for debugging
Serial.begin(9600);
}
void loop() {
// Read sensor values
int left = digitalRead(sensorLeft);
int right = digitalRead(sensorRight);
// Output sensor data (debugging)
Serial.print("Sensor Left: ");
Serial.print(left);
Serial.print(" | Sensor Right: ");
Serial.println(right);
// Control logic
if (left == 1 && right == 1) {
// Drive straight
controlMotors(HIGH, HIGH, 105, 105);
} else if (left == 1 && right == 0) {
// Turn right
controlMotors(HIGH, LOW, 105, 85);
} else if (left == 0 && right == 1) {
// Turn left
controlMotors(LOW, HIGH, 85, 105);
} else {
// Both readings 0
// Rotate in place to find the line
controlMotors(HIGH, LOW, 70, 70); // Left motor forward, right motor backward
// delay(500); // Brief rotation
// controlMotors(LOW, LOW, 0, 0);
}
}
// Function to control motors
void controlMotors(int directionL, int directionR, int speedL, int speedR) {
digitalWrite(DIR_L, directionL);
digitalWrite(DIR_R, directionR);
analogWrite(PWM_L, speedL);
analogWrite(PWM_R, speedR);
}
5.1 إعداد أطراف المحركات
#define DIR_L 12 // Left motor direction #define DIR_R 13 // Right motor direction #define PWM_L 3 // Left motor speed (PWM) #define PWM_R 11 // Right motor speed (PWM)
تتحكم هذه الأطراف الأربعة في المحركين عبر درع المحركات. يعطي سطر #define رقمَ الطرف اسمًا. ويستبدل المترجم (Compiler، وهو الجزء من برمجيات Arduino الذي يحوّل الـ Sketch إلى تعليمات للوحة) الاسمَ بالرقم قبل أن يبني البرنامج. أما أطراف المستشعرات في 5.2 فتستخدم متغيرات int بدلًا من ذلك؛ ومع أرقام الأطراف الثابتة تعمل الطريقتان بالشكل نفسه. يحدد DIR_L اتجاه المحرك الأيسر، ويحدد DIR_R اتجاه المحرك الأيمن (HIGH = إلى الأمام، LOW = إلى الخلف في هذا الدرع). ويضبط PWM_L وPWM_R سرعة كل محرك بتعديل عرض النبضة، من 0 (متوقف) إلى 255 (السرعة القصوى).
5.2 إعداد أطراف المستشعرات
int sensorLeft = 2; // Left sensor int sensorRight = 4; // Right sensor
تتصل أطراف الإشارة في مستشعرَي KY-033 بالطرفين الرقميين 2 و4.
5.3 الدالة setup()
void setup() {
pinMode(DIR_L, OUTPUT);
pinMode(DIR_R, OUTPUT);
pinMode(PWM_L, OUTPUT);
pinMode(PWM_R, OUTPUT);
pinMode(sensorLeft, INPUT);
pinMode(sensorRight, INPUT);
Serial.begin(9600);
}
تعمل الدالة setup مرة واحدة عند تشغيل Arduino. وهي تضبط أطراف المحركات الأربعة كمخارج وطرفَي المستشعرين كمداخل. يبدأ Serial.begin(9600) الاتصال التسلسلي بسرعة 9600 baud (بت في الثانية)، لتتمكن من متابعة قراءات المستشعرات في الشاشة التسلسلية (Serial Monitor). والشاشة التسلسلية هي النافذة في برنامج Arduino التي تعرض النص الذي ترسله اللوحة.
5.4 قراءة المستشعرات في الحلقة الرئيسية
int left = digitalRead(sensorLeft); int right = digitalRead(sensorRight);
تعمل الدالة loop() مرارًا وتكرارًا ما دامت اللوحة موصولة بالطاقة. وفي بداية كل دورة، تقرأ المستشعرين باستخدام digitalRead(). يحمل المتغير left قراءة المستشعر الأيسر (الطرف 2)، ويحمل المتغير right قراءة المستشعر الأيمن (الطرف 4).
5.5 إخراج التصحيح عبر المنفذ التسلسلي
Serial.print("Sensor Left: ");
Serial.print(left);
Serial.print(" | Sensor Right: ");
Serial.println(right);
تطبع كل دورة من loop() القراءتين. افتح الشاشة التسلسلية (Tools > Serial Monitor، بسرعة 9600 baud) لترى القيمتين مباشرة.
5.6 منطق اتخاذ القرار
if (left == 1 && right == 1) {
controlMotors(HIGH, HIGH, 105, 105);
} else if (left == 1 && right == 0) {
controlMotors(HIGH, LOW, 105, 85);
} else if (left == 0 && right == 1) {
controlMotors(LOW, HIGH, 85, 105);
} else {
controlMotors(HIGH, LOW, 70, 70);
}
تطابق الحالات الأربع الجدول في قسم «كيف يعمل الروبوت». عندما تكون القراءتان 1، يدور المحركان إلى الأمام بالسرعة 105. وعندما تكون قراءة left هي 1 وقراءة right هي 0، يضبط الكود المحرك الأيسر على الدوران إلى الأمام بالسرعة 105 والمحرك الأيمن إلى الخلف بالسرعة 85، فينعطف الروبوت محوريًا إلى اليمين حتى تتغير قراءات المستشعرين. وعندما تكون قراءة left هي 0 وقراءة right هي 1، يدور المحرك الأيسر إلى الخلف بالسرعة 85 والمحرك الأيمن إلى الأمام بالسرعة 105، فينعطف الروبوت محوريًا إلى اليسار. وفي فرع else (القراءتان 0) يدور الروبوت في مكانه إلى اليمين بالسرعة 70، المحرك الأيسر إلى الأمام والأيمن إلى الخلف، حتى تتغير إحدى القراءتين.
5.7 الدالة controlMotors()
void controlMotors(int directionL, int directionR, int speedL, int speedR) {
digitalWrite(DIR_L, directionL);
digitalWrite(DIR_R, directionR);
analogWrite(PWM_L, speedL);
analogWrite(PWM_R, speedR);
}
تجمع الدالة controlMotors() عمليات الكتابة الأربع على الأطراف في استدعاء واحد: اتجاه (HIGH أو LOW) وسرعة (من 0 إلى 255) لكل محرك. فهي تكتب الاتجاه على الطرفين DIR_L وDIR_R باستخدام digitalWrite()، والسرعة على الطرفين PWM_L وPWM_R باستخدام analogWrite(). ورغم اسمها، لا تُخرج analogWrite() جهدًا تناظريًا، بل تشغّل الطرف وتطفئه بسرعة كبيرة جدًا (PWM)، وتحدد القيمة من 0 إلى 255 مدة بقاء الطرف في حالة التشغيل في كل دورة. لتغيير حركة ما، عدّل الأرقام في الاستدعاء.
الخطوة 6: اختبار الروبوت وضبطه
يصلح شريط لاصق أبيض بعرض 50 mm على خلفية داكنة (سطح طاولة داكن أو لوح كرتون داكن) مسارًا للاختبار.
6.1 جهّز مسار الاختبار
ابدأ بخط مستقيم من الشريط بطول من 1 إلى 2 m. وعندما يتتبعه الروبوت بثبات، أضف منحنيات واسعة. وتجنب المنعطفات بزاوية 90 درجة في البداية. المسار الذي استخدمته في الفيديو شريط أبيض على سجادة رمادية داكنة: حلقة مغلقة من شرائط مستقيمة، قُسم فيها كل تغيير في الاتجاه إلى انحناءات بزاوية 45 درجة.
6.2 موضع المستشعرات وارتفاعها
ركّب مستشعرَي KY-033 على ارتفاع من 5 إلى 15 mm فوق الأرض. واجعل المسافة بينهما أعرض من الشريط ببضعة مليمترات، بحيث يقع كل مستشعر خارج إحدى حافتَي الشريط عندما يكون الروبوت في المنتصف. إذا كان المستشعران مرتفعين أكثر من اللازم، فلن يستطيعا التمييز بين الخط والخلفية. وإذا كانا منخفضين أكثر من اللازم، فقد يحتكان بالسطح أو يعطيان قراءات غير منتظمة. وإذا كانت المسافة بينهما أقل من عرض الشريط، فسيقع كلاهما على الشريط عندما يكون الروبوت في المنتصف، وسيدور الروبوت في مكانه بدلًا من السير مستقيمًا.
6.3 الاختبار الأول: الفحص عبر الشاشة التسلسلية
وصّل الروبوت بحاسوبك بكابل USB، وافتح الشاشة التسلسلية، وحرّك الروبوت فوق الخط بيدك. يجب أن يعرض كل مستشعر 0 فوق الشريط الأبيض و1 فوق الخلفية الداكنة. إذا لم تتغير قراءة ما أو كانت تتذبذب، فاضبط المقاومة المتغيرة في KY-033 أو افحص التوصيلات. وإذا عرضت وحدتك 1 فوق الشريط الأبيض، فهي تعمل بالمنطق المعاكس: بدّل 1 و0 في شروط if داخل الدالة loop()، كما في حالة الخط الأسود.
6.4 أول تشغيل على المسار
ضع الروبوت على المسار في منتصف الخط، ثم شغّله. عندما يعمل كل شيء، يسير الروبوت على طول الخط ويصحّح مساره يمينًا ويسارًا مع تغيّر القراءات. تتبّع روبوتي الخط، لكنه لم يسر بسلاسة قط؛ فقد ظل يتمايل من جانب إلى آخر طوال الوقت.
6.5 ضبط سرعات المحركات
إذا تجاوز الروبوت المنعطفات، فاخفض قيم السرعة في استدعاءات controlMotors() (105 و85)؛ وإذا توقف عن الحركة، فارفعها. غيّرها بخطوات من 5 إلى 10. ويمكن ضبط سرعة السير المستقيم وسرعة الانعطاف كلٍّ على حدة.
6.6 ضبط الدوران في المكان
عندما يقرأ المستشعران 0، يدور الروبوت في مكانه بالسرعة 70. إذا دار بسرعة كبيرة وتجاوز الخط، فاخفض هذه القيمة؛ وإذا دار ببطء شديد أو توقف، فارفعها. يحتوي فرع else على سطرين معطّلين (الرمز // في بداية السطر يحوّله إلى تعليق). إذا حذفت //، يدور الروبوت لمدة 500 ms (delay(500)) دون قراءة المستشعرات. ثم تتوقف المحركات، ولكن فقط حتى تقرأ الدورة التالية من loop() المستشعرات وتضبط قيمًا جديدة للمحركات.
6.7 تحسين سلاسة الانعطاف
في حالتَي التصحيح يدور المحركان في اتجاهين متعاكسين (105 إلى الأمام، 85 إلى الخلف)، فينعطف الروبوت محوريًا في مكانه تقريبًا. وتقريب القيمتين من بعضهما (مثلًا 100 و90) يُبقي مجموعهما وسرعة الانعطاف كما هما، لكنه يخفض الحركة إلى الأمام إلى النصف، فيصبح الانعطاف المحوري أضيق. وللحصول على تصحيحات أكثر سلاسة، أبقِ المحركين يدوران إلى الأمام وأبطئ المحرك الموجود في الجهة التي ينعطف الروبوت نحوها.
استكشاف الأخطاء وإصلاحها
مشكلات المستشعرات والاكتشاف
| المشكلة | السبب المحتمل | الحل |
|---|---|---|
| يدور الروبوت في مكانه باستمرار | يقرأ المستشعران 0 دائمًا (كلاهما يرى الأبيض) | أدِر المقاومة المتغيرة في KY-033 حتى تصبح قراءة الخلفية الداكنة 1. وتأكد من أن الخلفية داكنة وأن المسافة بين المستشعرين أعرض من الشريط (انظر 6.2). |
| لا يكتشف الروبوت الخط على الإطلاق | توصيلات المستشعرين خاطئة أو أحد المستشعرين معطل | تأكد من أن أسلاك الإشارة موصولة بالطرفين 2 و4، وأن VCC وGND موصولان. واختبر كل مستشعر على حدة في الشاشة التسلسلية. |
| يعطي المستشعران القراءة نفسها دائمًا | المستشعران متقاربان جدًا أو مرتفعان كثيرًا عن الأرض | افحص المسافة بين المستشعرين (انظر 6.2). وركّب المستشعرين أقرب إلى الأرض. |
| سلوك غير مستقر أو حركات غير منتظمة | ارتفاع المستشعرين غير ثابت أو السطح غير مستوٍ | ركّب المستشعرين بشكل مستوٍ وعلى ارتفاع ثابت. واختبر على سطح مستوٍ. وابحث عن أسلاك مرتخية. |
| يتتبع الروبوت الخط بشكل ضعيف في المنحنيات | فرق السرعة أثناء الانعطاف المحوري صغير جدًا أو كبير جدًا | اضبط قيم السرعة في حالتَي الانعطاف المحوري. وجرّب تركيبات أخرى من سرعات الدوران إلى الأمام وإلى الخلف. |
| المحركات سريعة جدًا أو بطيئة جدًا | قيم PWM لا تناسب محركاتك وجهد بطاريتك | غيّر قيم السرعة (105، 85، 70) بخطوات من 5 إلى 10. |
مشكلات المحركات والطاقة
| المشكلة | السبب المحتمل | الحل |
|---|---|---|
| الروبوت لا يتحرك إطلاقًا | البطارية فارغة، أو توصيلات الطاقة خاطئة، أو درع المحركات غير مركَّب بالكامل | افحص جهد البطارية. واضغط درع المحركات بالكامل على مقابس لوحة Arduino. وافحص توصيلات مرابط المحركات. |
| أحد المحركين يعمل والآخر لا يعمل | خطأ في التوصيل على إحدى قناتَي المحركين | افحص توصيلات مرابط المحركات في درع المحركات. وبدّل المحركين لتعرف هل الخلل في المحرك أم في قناة الدرع. |
| يتحرك الروبوت إلى الخلف بدلًا من الأمام | أسلاك المحرك معكوسة | بدّل السلكين في مربط المحرك المعني، أو غيّر قيمة الاتجاه (HIGH/LOW) في الكود. |
الأسئلة الشائعة
نعم. بدّل 1 و0 في شروط if داخل الدالة loop().
نعم، مثل وحدة L298N أو Adafruit Motor Shield. حدّث تعريفات الأطراف في الكود، ومنطق التحكم في المحركات عند الحاجة، بما يتوافق مع وحدة القيادة الجديدة.
يناسب عرضٌ من 30 إلى 50 mm هذا الإعداد ذا المستشعرين؛ ويُعد الشريط اللاصق الأبيض بعرض 50 mm نقطة بداية جيدة. يجب أن يكون الشريط أضيق قليلًا من المسافة بين المستشعرين (انظر 6.2)، حتى يرى المستشعران الخلفية الداكنة عندما يكون الروبوت في المنتصف.
التنزيلات
- برنامج Arduino (Sketch): مستودع GitHub.
- ملفات STL للهيكل والمباعِدات: متجر OmArTronics.
المشاريع التالية المقترحة
- روبوت تتبع الخط باستخدام مستشعر TCS34725 RGB والتحكم PID: الترقية المباشرة لهذا الروبوت، مع تتبع أكثر سلاسة ودقة.
- سيارة الروبوت OmObi المتحكَّم فيها عبر بلوتوث باستخدام Arduino وHC-05: روبوت متنقل يُتحكَّم فيه بالهاتف.
- سيارة روبوت لتجنب العوائق باستخدام Arduino ومستشعر الموجات فوق الصوتية: تجنب العوائق بشكل ذاتي.
- OmObiArm: روبوت متنقل بذراع روبوتية مدمجة: روبوت متنقل مزود بذراع روبوتية.
- دليل التحكم بالسيرفو مع Arduino: أساسيات محركات السيرفو في الروبوتات.
الخاتمة
تتعامل هذه النسخة ذات المستشعرين مع الخطوط المستقيمة والمنحنيات الواسعة. لا يُخرج كل مستشعر KY-033 إلا 0 أو 1، لذا إما أن يسير الروبوت مستقيمًا أو ينعطف محوريًا، وهذا ما يسبب تمايله من جانب إلى آخر. وللحصول على تتبع أكثر سلاسة ومنحنيات أضيق، تابع مع درس مستشعر TCS34725 RGB والتحكم PID، الذي يبني على هذا الروبوت.

رأي واحد حول “Building a Line Following Robot with KY-033 Sensors for Beginners”