يحتوي هذا المقال على روابط تسويق بالعمولة مُعلَّمة بعلامة *. بصفتي شريكًا في برنامج Amazon Associates، أربح من عمليات الشراء المؤهلة، دون أي تكلفة إضافية عليك. يساعد ذلك على إبقاء الشروحات مجانية.
نسخة Plexiglas: استخدمت نسخة سابقة من هذه السيارة هيكلًا مقصوصًا من Plexiglas، وهي موصوفة في بناء سيارة روبوت يُتحكَّم بها عبر بلوتوث باستخدام Arduino وHC-05 وAdafruit Motor Shield. الكود والتطبيق متطابقان.
ملخص سريع
OmObi سيارة روبوت رباعية الدفع (لكل عجلة من العجلات الأربع محرك خاص بها) مبنية على هيكل مطبوع بطابعة ثلاثية الأبعاد. يرسل تطبيق Android مصمم باستخدام MIT App Inventor أحرفًا مفردة (F وB وL وR وS) عبر بلوتوث إلى وحدة HC-05. تقرأ لوحة Arduino Uno كل حرف وتشغّل أربعة محركات تيار مستمر عبر Adafruit Motor Shield V1.2.
هذا المشروع مناسب لأول روبوت تبنيه: يُركَّب درع المحركات مباشرة فوق لوحة Arduino، والبرنامج (Sketch، وهي التسمية التي تستخدمها Arduino للبرنامج) أقل من 70 سطرًا. في OmObi استبدلت لوح Plexiglas المثقوب الذي استخدمته في نسختي الأولى بهيكل صممته في Autodesk Inventor (برنامج تصميم 3D) ثم طبعته بطابعة ثلاثية الأبعاد. يحتوي الهيكل على فتحات لمستشعر الموجات فوق الصوتية أغلقتها في هذا البناء، وعلى فتحة لكابل USB. إذا كان استخدام بلوتوث مع Arduino جديدًا عليك، فاقرأ شرح البلوتوث HC-05/HC-06 مع Arduino أولًا. وإذا كانت Arduino IDE جديدة عليك، فابدأ بقراءة أساسيات برمجة Arduino.

آلية العمل
تعمل أربعة أجزاء معًا: هاتف Android، ووحدة بلوتوث HC-05، ولوحة Arduino Uno، ودرع Adafruit Motor Shield مع أربعة محركات تيار مستمر.
هاتف Android يشغّل تطبيقًا مبنيًا باستخدام MIT App Inventor. عند الضغط على زر اتجاه، يرسل التطبيق حرفًا واحدًا عبر بلوتوث: F (للأمام) أو B (للخلف) أو L (لليسار) أو R (لليمين). وعند تحرير الزر يرسل S (توقف).
وحدة البلوتوث HC-05 تستقبل الحرف وتمرّره إلى Arduino عبر اتصال تسلسلي (Serial)، وهو اتصال يرسل البيانات بتًا تلو الآخر. تتصل الوحدة بالطرف 0 في Arduino (RX، الاستقبال) والطرف 1 (TX، الإرسال)، وتعمل ككابل تسلسلي لاسلكي بين الهاتف وArduino.
Arduino Uno تقرأ الحرف من المخزن المؤقت التسلسلي (Serial Buffer، وهو ذاكرة صغيرة تحتفظ بالبايتات المستلمة إلى أن يقرأها البرنامج). ثم تستدعي دالة الحركة المناسبة: forward أو backward أو turnLeft أو turnRight أو stop.
Adafruit Motor Shield V1.2 يُركَّب مباشرة فوق Arduino. تتولى شريحتا جسر H من نوع L293D على الدرع تبديل تيار المحركات، فلا ترسل أطراف Arduino سوى إشارات التحكم. وجسر H (H-bridge) دائرة من أربعة مفاتيح يمكنها تمرير التيار عبر المحرك في أي من الاتجاهين. تقود كل شريحة اثنين من منافذ المحركات الأربعة M1 إلى M4. وفي البرنامج تضبط مكتبة AFMotor اتجاه كل محرك (FORWARD وBACKWARD وRELEASE) وسرعته (من 0 إلى 255). وعند الانعطاف يدور أحد الجانبين للأمام بينما يدور الآخر للخلف، فتستدير السيارة في مكانها (التوجيه الانزلاقي Skid Steering، على طريقة استدارة الدبابة).
قائمة المواد
| المكوّن | الكمية | مطلوب؟ | الغرض | ملاحظات |
|---|---|---|---|---|
| Arduino Uno | 1 | مطلوب | المتحكم الدقيق الرئيسي | تصلح أي لوحة متوافقة مع Uno |
| Adafruit Motor Shield V1.2 | 1 | مطلوب | يقود أربعة محركات تيار مستمر | يُركَّب فوق Arduino |
| وحدة البلوتوث HC-05 | 1 | مطلوب | وصلة تسلسلية لاسلكية مع الهاتف | تعمل أيضًا وحدة HC-06 (راجع الأسئلة الشائعة) |
| محركات تيار مستمر بعلبة تروس | 4 | مطلوب | لتحريك العجلات الأربع | محركات TT صفراء بعلبة تروس (TT هو الاسم الشائع لهذا النوع من المحركات ذات علبة التروس البلاستيكية)، من 3 إلى 6 V |
| العجلات | 4 | مطلوب | تُركَّب على أعمدة المحركات | تناسب أعمدة محركات TT |
| هيكل مطبوع بطابعة ثلاثية الأبعاد | 1 | مطلوب | الإطار الأساسي | يصلح أيضًا لوح Plexiglas أو أكريليك |
| حوامل محركات بالطباعة ثلاثية الأبعاد (3D) | 4 | اختياري | تثبيت المحركات على الهيكل | غير موجودة ضمن ملفات STL الخاصة بـOmObi؛ استخدم ملفات motor_holder من حزمة Advanced Robot Car، أو زوايا معدنية على شكل حرف L |
| حامل Arduino بالطباعة ثلاثية الأبعاد (3D) | 1 | اختياري | تثبيت Arduino على الهيكل | يصلح أيضًا شريط لاصق مزدوج الوجه أو فواصل تثبيت (Standoffs، أعمدة مباعدة) |
| بطارية LiPo 2S بجهد 7.4 V، بسعة 5300 mAh | 1 | مطلوب | يغذّي المحركات وArduino بالطاقة | حزمة بطاريات ليثيوم بوليمر، والتفاصيل والحزم الأخرى في الخطوة 4 |
| شاحن موازنة LiPo (Balance Charger) | 1 | مطلوب | يشحن بطارية LiPo بأمان | راجع الخطوة 4 |
| مفتاح تشغيل/إيقاف | 1 | اختياري | يشغّل السيارة ويطفئها | يوضع في السلك الموجب الممتد من البطارية إلى الدرع (الخطوة 4) |
| أسلاك التوصيل (Jumper) | عدة | مطلوب | وصّل HC-05 بلوحة Arduino | مع أطراف توصيل لوحدة HC-05 |
| براغٍ، صواميل، حشوات ملولبة، فواصل تثبيت | متنوعة | مطلوب | التجميع الميكانيكي | المقاس الشائع M3 (لولب بقطر 3 mm)؛ الحشوات الملولبة: راجع الخطوة 1 |
| هاتف ذكي يعمل بنظام Android | 1 | مطلوب | يشغّل تطبيق التحكم | يجب أن يدعم Bluetooth Classic، وهو نمط بلوتوث القياسي الذي تستخدمه وحدة HC-05؛ أما أجهزة iPhone فتحتاج إلى وحدة بلوتوث مختلفة (راجع الأسئلة الشائعة) |
الخطوة 1: تركيب المحركات والعجلات
في البداية سخّنت حشوات ملولبة (Threaded Inserts، وهي جلب معدنية صغيرة ذات لولب داخلي) وضغطتها داخل القطع المطبوعة. بعد ذلك تُربط البراغي مباشرة في لولب معدني فتثبت بإحكام أكبر. ثبّت كل محرك على حامله المطبوع بالبراغي والصواميل. ركّب المحركات بحيث تتجه أعمدتها إلى الخارج. يُركَّب المحركان الأيسر والأيمن متعاكسين كصورة المرآة، لذلك يُحدَّد اتجاه الدوران لاحقًا بقطبية الأسلاك عند الدرع، لا بطريقة تركيب المحركات. وإذا لم تتوفر حوامل مطبوعة، فيمكن استخدام زوايا معدنية على شكل L، أو الغراء الحراري كحل مؤقت.
ثبّت العجلات على أعمدة المحركات بالضغط عليها. تأكد من أنها مثبتة بإحكام وتدور دون أن تحتك بالهيكل أو ببعضها.
الخطوة 2: تركيب Arduino ودرع المحركات
ثبّت حامل Arduino المطبوع بطابعة ثلاثية الأبعاد في منتصف الهيكل أو في مؤخرته، واترك مساحة في المقدمة أو على الجانبين لحزمة البطاريات. صممت الهيكل ليناسب Arduino Uno أو Arduino Mega. وإذا لم تستخدم الحامل، فاستعمل فواصل تثبيت مع براغٍ M3 عبر فتحات التثبيت في Arduino، أو ألصق اللوحة بشريط إسفنجي مزدوج الوجه.
ضع لوحة Arduino Uno في الحامل وثبّتها بالبراغي. ضع درع المحركات فوق Arduino واضغطه برفق حتى تصطف جميع أطراف التوصيل (صفوف الأطراف الموجودة أسفل الدرع) وتدخل بالكامل في مقابس Arduino.
الخطوة 3: التوصيلات
استخدم مخطط التوصيل أدناه مرجعًا. يُظهر المخطط بطارية 9 V (PP3) مصدرًا للطاقة؛ لا تنقل هذا الجزء كما هو (راجع الخطوة 4). في السيارة تُوصَّل بطارية LiPo 2S بطرف الطاقة نفسه.

توصيلات المحركات
| المحرك | طرف التوصيل على الدرع | الموضع على السيارة |
|---|---|---|
| المحرك 1 | M1 | الجانب الأيسر (الأمامي أو الخلفي) |
| المحرك 2 | M2 | الجانب الأيسر (الأمامي أو الخلفي) |
| المحرك 3 | M3 | الجانب الأيمن (الأمامي أو الخلفي) |
| المحرك 4 | M4 | الجانب الأيمن (الأمامي أو الخلفي) |
أدخل سلكي كل محرك في طرف التوصيل اللولبي الخاص به وأحكم ربط البراغي. القطبية لا تهم الآن؛ ستضبط اتجاه الدوران أثناء الاختبار الأول.
توصيلات HC-05
| طرف HC-05 | طرف Arduino | ملاحظات |
|---|---|---|
| VCC | 5 V | يغذّي الوحدة بالطاقة |
| GND | GND | أرضي مشترك |
| TXD | RX (الطرف 0) | ترسل وحدة HC-05 البيانات إلى Arduino |
| RXD | TX (الطرف 1) | يرسل Arduino البيانات إلى HC-05 |
يغطي الدرع مقابس أطراف Arduino، لذلك لحمت سلكي TXD وRXD على الطرفين 0 و1 في الدرع. يعمل مدخل RXD في وحدة HC-05 بمنطق 3.3 V، بينما يُخرج الطرف TX في Uno جهد 5 V. في بنائي وصّلت RXD مباشرة بالطرف 1 كما في مخطط التوصيل، وعملت السيارة بهذه الطريقة. لكن مقسم الجهد هو الخيار الأكثر أمانًا: مقاومتان، 1 kΩ من TX في Arduino إلى RXD و2 kΩ من RXD إلى GND، تخفضان إشارة 5 V إلى نحو 3.3 V.
المنفذ التسلسلي العتادي (الطرفان 0 و1) وتعارضه مع رفع البرنامج
تحذير: تتصل وحدة HC-05 بالطرفين 0 (RX) و1 (TX)، وهما الواجهة التسلسلية المدمجة في Uno، وتُسمّى المنفذ التسلسلي العتادي (Hardware Serial). ويستخدم اتصال USB الطرفين نفسيهما لرفع البرامج (Sketches) وللشاشة التسلسلية (Serial Monitor، وهي نافذة في Arduino IDE تعرض النصوص التي ترسلها اللوحة عبر USB). افصل وحدة HC-05 (أو على الأقل سلكي TXD وRXD) في كل مرة ترفع فيها الكود. إذا بقيت موصولة يفشل الرفع، لأن الوحدة تتداخل مع البيانات التسلسلية القادمة عبر USB. بعد انتهاء الرفع، أعد توصيل HC-05 ثم أعد تشغيل Arduino (Reset).
كذلك لا يمكنك استخدام الشاشة التسلسلية ما دامت وحدة HC-05 موصولة بالطرفين 0 و1. إذا احتجت إلى الاثنين معًا، فاستخدم مكتبة SoftwareSerial (تنشئ منفذًا تسلسليًا على أطراف أخرى) على طرفين يتركهما الدرع غير مستخدمين، مثل A0 (RX) وA1 (TX). عند تشغيل محركات التيار المستمر يستخدم الدرع الأطراف 3 و4 و5 و6 و7 و8 و11 و12، أما الطرفان 9 و10 فمخصصان لموصلات السيرفو.
الخطوة 4: التغذية بالطاقة
يعمل OmObi ببطارية LiPo 2S بجهد 7.4 V وسعة 5300 mAh، وهي الحزمة نفسها المستخدمة في OmObiArm: خليتان من الليثيوم بوليمر موصولتان على التوالي، والجهد الاسمي لكل منهما 3.7 V. وصّلها بطرف التوصيل اللولبي EXT_PWR على درع المحركات، وهو الطرف المخصص لتغذية المحركات. تحقّق من القطبين الموجب والسالب قبل أن تُحكم ربط البراغي. ولأن الدرع يُركَّب فوق Arduino مباشرة، تشترك اللوحتان تلقائيًا في الأرضي (GND). لا تستخدم بطارية 9 V (PP3): فهي لا تستطيع توفير التيار الذي تسحبه أربعة محركات تيار مستمر تحت الحمل.
اشحن حزمة البطاريات فقط بشاحن موازنة مخصص لبطاريات LiPo (Balance Charger). يشحن هذا الشاحن كل خلية إلى الجهد نفسه عبر قابس الموازنة الصغير في الحزمة. لا تترك الحزمة أبدًا تُشحن دون مراقبة. توقف عن القيادة عندما ينخفض جهد الحزمة إلى نحو 6.6 V (أي 3.3 V لكل خلية)؛ فتحت 3.0 V لكل خلية قد تتلف الخلايا تلفًا دائمًا. يُنبّهك منبّه جهد LiPo موصول بقابس الموازنة في الوقت المناسب. إذا خزّنت الحزمة لأكثر من بضعة أيام، فاشحنها أو فرّغها إلى نحو 7.6 V (أي 3.8 V لكل خلية)، وهو جهد التخزين؛ ومعظم شواحن الموازنة فيها وضع تخزين لهذا الغرض.
يحتوي الدرع على وصلة PWR (Jumper)، وهي قابس صغير يصل بين طرفين. عند تركيب الوصلة تغذي البطارية Arduino أيضًا عبر الطرف VIN، وهو مدخل التغذية الخارجية. يحوّل منظم الجهد المدمج في Arduino جهد VIN إلى 5 V ثابتة، ويحتاج لذلك إلى نحو 7 V على VIN. تعطي بطارية LiPo 2S جهد 8.4 V عند امتلائها و7.4 V جهدًا اسميًا، أي ضمن النطاق الموصى به لـ Uno من 7 إلى 12 V. ركّب الوصلة: فبمجرد فصل كابل USB تصبح البطارية مصدر التغذية الوحيد لـ Arduino. وعندما تقترب الحزمة من النفاد قد ينخفض الجهد إلى ما دون 7 V لحظة بدء المحركات، فيُعاد تشغيل Arduino تلقائيًا: حان وقت إعادة الشحن.
الجهد المقنن لمحركات TT من 3 إلى 6 V. وتسبّب كل شريحة L293D على الدرع هبوطًا في الجهد بنحو 2.6 V، لذلك حتى الحزمة الممتلئة لا توصل إلى المحركات أكثر من نحو 5.8 V عند السرعة القصوى.
حزم أخرى: تعمل حزمة Li-ion من نوع 2S (جهد اسمي 7.4 V، و8.4 V عند الشحن الكامل) مزودة بنظام BMS بالطريقة نفسها. ونظام BMS (نظام إدارة البطارية) لوحة صغيرة تحمي الخلايا من الشحن الزائد والتفريغ العميق. أما حزمة 4 × AA فتعطي 6 V مع بطاريات قلوية جديدة. يكفي ذلك لتشغيل المحركات، لكنه منخفض جدًا بالنسبة لمنظم الجهد على VIN: انزع وصلة PWR وغذِّ Arduino بشكل منفصل عبر USB أو مقبس DC الخاص به. أما أربع خلايا AA قابلة للشحن من نوع NiMH (هيدريد النيكل المعدني) فلا تعطي سوى 4.8 V (4 × 1.2 V): وبعد هبوط الجهد في L293D لا يصل إلى المحركات سوى نحو 2.2 V، أي أقل من حدها الأدنى البالغ 3 V.
يحتوي OmObi على مفتاح تشغيل/إيقاف في السلك الموجب الممتد من البطارية إلى EXT_PWR. وهو مثبت في اللوح العلوي، فيبقى في متناول اليد حتى أثناء سير السيارة.
الخطوة 5: برمجة Arduino
ثبّت المكتبة أولًا. في Arduino IDE افتح Sketch > Include Library > Manage Libraries، وابحث عن “Adafruit Motor Shield library” (مكتبة الإصدار V1 التي تحتوي على AFMotor.h) ثم انقر Install.
يستقبل البرنامج التالي أحرفًا مفردة من وحدة HC-05 عبر المنفذ التسلسلي العتادي ويشغّل المحركات الأربعة. قبل الرفع افصل HC-05 عن الطرفين 0 و1. في Arduino IDE اختر Tools > Board > Arduino Uno، واختر منفذ لوحتك من Tools > Port، ثم انقر Upload. وعندما تعرض IDE الرسالة “Done uploading”، أعد توصيل HC-05 واضغط زر إعادة التشغيل (Reset).
/**
* Author: Omar Draidrya
* Date: 2024/07/03
* Bluetooth-controlled 4WD robot car (OmObi) using Adafruit Motor Shield V1.2 and HC-05.
* Receives single-character commands (F/B/L/R/S) via serial from the HC-05
* Bluetooth module and drives four DC motors on terminals M1-M4 accordingly.
*/
#include <AFMotor.h>
AF_DCMotor motor1(1); // Create motor #1 using M1 connector
AF_DCMotor motor2(2); // Create motor #2 using M2 connector
AF_DCMotor motor3(3); // Create motor #3 using M3 connector
AF_DCMotor motor4(4); // Create motor #4 using M4 connector
char command;
void setup() {
Serial.begin(9600); // Start serial communication at 9600 baud rate
motor1.setSpeed(255); // Set initial motor speeds
motor2.setSpeed(255);
motor3.setSpeed(255);
motor4.setSpeed(255);
}
void loop() {
if (Serial.available() > 0) {
command = Serial.read(); // Read the incoming command
if (command == 'F') { forward(); }
else if (command == 'B') { backward(); }
else if (command == 'L') { turnLeft(); }
else if (command == 'R') { turnRight(); }
else if (command == 'S') { stop(); }
}
}
void forward() {
motor1.run(FORWARD);
motor2.run(FORWARD);
motor3.run(FORWARD);
motor4.run(FORWARD);
}
void backward() {
motor1.run(BACKWARD);
motor2.run(BACKWARD);
motor3.run(BACKWARD);
motor4.run(BACKWARD);
}
void turnLeft() {
motor1.run(BACKWARD);
motor2.run(BACKWARD);
motor3.run(FORWARD);
motor4.run(FORWARD);
}
void turnRight() {
motor1.run(FORWARD);
motor2.run(FORWARD);
motor3.run(BACKWARD);
motor4.run(BACKWARD);
}
void stop() {
motor1.run(RELEASE);
motor2.run(RELEASE);
motor3.run(RELEASE);
motor4.run(RELEASE);
}
مكتبة AFMotor وإعداد المحركات
يبدأ البرنامج بتضمين AFMotor.h، وهي مكتبة Adafruit Motor Shield. ثم يُنشئ أربعة كائنات للمحركات، من motor1(1) إلى motor4(4)، كائنًا لكل منفذ من M1 إلى M4. وفي setup() يبدأ المنفذ التسلسلي بسرعة 9600 baud (أي 9600 بت في الثانية)، وهي السرعة الافتراضية لوحدة HC-05. يجب أن يستخدم الجانبان معدل الباود (Baud Rate) نفسه، وإلا استقبل Arduino أحرفًا خاطئة. وتُضبط المحركات الأربعة كلها على السرعة القصوى (255 من 255).
بروتوكول الأوامر
يرسل التطبيق حرف ASCII واحدًا (حرفًا واحدًا مخزنًا في بايت واحد)، ويقرؤه Arduino من المخزن المؤقت التسلسلي داخل loop(). هناك خمسة أوامر: F (للأمام) وB (للخلف) وL (انعطاف لليسار) وR (انعطاف لليمين) وS (توقف)، لذلك لا تحتاج loop() إلا إلى مقارنة حرف واحد.
دوال الحركة
تشغّل forward() المحركات الأربعة كلها بالأمر FORWARD، وتشغّلها backward() بالأمر BACKWARD. أما turnLeft() فتدير المحركات اليسرى (M1 وM2) للخلف والمحركات اليمنى (M3 وM4) للأمام، فتستدير السيارة يسارًا في مكانها. وتفعل turnRight() العكس: المحركات اليسرى للأمام واليمنى للخلف. وتستدعي stop() الأمر RELEASE لجميع المحركات، فينقطع تيار المحركات؛ وتتدحرج السيارة مسافة قصيرة ثم تتوقف.
تغيير السرعة
تُضبط السرعة في setup() باستخدام setSpeed(255). تتراوح القيمة من 0 إلى 255 وتحدد دورة التشغيل (Duty Cycle) لإشارة PWM. وتقنية PWM (تعديل عرض النبضة) تشغّل جهد المحرك وتقطعه مرات كثيرة في الثانية؛ ودورة التشغيل هي نسبة الزمن الذي يكون فيه الجهد موصولًا. القيمة 150 تعني نحو 59 %. مع بطارية LiPo 2S تحصل المحركات على ما يصل إلى نحو 5.8 V عند القيمة 255 (الخطوة 4)، وعلى نحو 59 % من ذلك عند 150، أي قرابة 3.4 V في المتوسط. لا تتغير السرعة الفعلية بالنسبة نفسها، وعند القيم المنخفضة قد لا تبدأ المحركات بالدوران أصلًا. اخفض القيمة لإبطاء السيارة. ويمكنك أيضًا ضبط سرعات مختلفة للانعطاف وللسير المستقيم باستدعاء setSpeed() داخل دوال الحركة.
الخطوة 6: تطبيق Android
بُني التطبيق باستخدام MIT App Inventor، وهي أداة برمجة مرئية مجانية تعمل في المتصفح: تُركّب التطبيق من كتل بدلًا من كتابة كود Java أو Kotlin. يتصل التطبيق بوحدة HC-05 ويرسل الأحرف المذكورة في الخطوة 5.
إنشاء مشروع
انتقل إلى MIT App Inventor وسجّل الدخول بحساب Google الخاص بك. انقر “Start New Project” وسمِّه “RobotCarControl”.
تصميم واجهة المستخدم
في واجهة Designer، أضف هذه المكونات إلى الشاشة:
- ListPicker: اضبط نصه على “Select Bluetooth Device”. يتيح للمستخدم اختيار جهاز بلوتوث مقترن.
- Label (Label1): يعرض حالة الاتصال، “Connected” أو “Not Connected”.
- BluetoothClient: من لوحة Connectivity. وهو مكوّن غير مرئي يتولى الاتصال عبر بلوتوث.
- أربعة أزرار: ButtonForward وButtonBackward وButtonLeft وButtonRight. اضبط نصوصها وألوانها بحيث تكون الاتجاهات واضحة.
برمجة الكتل
انتقل إلى واجهة Blocks وأضف هذا المنطق:
when ListPicker1.BeforePicking
set ListPicker1.Elements to BluetoothClient1.AddressesAndNames
when ListPicker1.AfterPicking
if call BluetoothClient1.Connect address ListPicker1.Selection
then set Label1.Text to "Connected"
else set Label1.Text to "Not Connected"
when ButtonForward.TouchDown
if BluetoothClient1.IsConnected
call BluetoothClient1.SendText text "F"
when ButtonBackward.TouchDown
if BluetoothClient1.IsConnected
call BluetoothClient1.SendText text "B"
when ButtonLeft.TouchDown
if BluetoothClient1.IsConnected
call BluetoothClient1.SendText text "L"
when ButtonRight.TouchDown
if BluetoothClient1.IsConnected
call BluetoothClient1.SendText text "R"
when ButtonForward.TouchUp
if BluetoothClient1.IsConnected
call BluetoothClient1.SendText text "S"
when ButtonBackward.TouchUp
if BluetoothClient1.IsConnected
call BluetoothClient1.SendText text "S"
when ButtonLeft.TouchUp
if BluetoothClient1.IsConnected
call BluetoothClient1.SendText text "S"
when ButtonRight.TouchUp
if BluetoothClient1.IsConnected
call BluetoothClient1.SendText text "S"

وظيفة كل كتلة:
- ListPicker1.BeforePicking: تملأ القائمة بجميع الأجهزة المقترنة (BluetoothClient1.AddressesAndNames).
- ListPicker1.AfterPicking: تتصل بالجهاز المختار وتضبط Label1 على “Connected” أو “Not Connected”.
- TouchDown: ترسل F أو B أو L أو R أثناء الضغط على الزر، إذا كان الاتصال نشطًا.
- TouchUp: ترسل S عندما يرتفع الإصبع عن الزر.
يتحرك الروبوت فقط ما دمت تضغط على الزر. وعند تحريره يرسل التطبيق S، فتُطفأ المحركات (RELEASE) وتتدحرج السيارة مسافة قصيرة قبل أن تتوقف.
تثبيت التطبيق
في App Inventor اختر Build > Android App (.apk). وملف .apk هو حزمة التثبيت الخاصة بتطبيقات Android. امسح رمز QR بهاتفك، أو نزّل ملف .apk وانسخه إلى الهاتف. أنا نسخت ملف .apk إلى جهازي اللوحي الذي يعمل بنظام Android وثبّته عليه. سيطلب منك Android السماح بالتثبيت من هذا المصدر؛ وافق مرة واحدة. وإذا طلب Android إذن “Nearby devices” (الأجهزة المجاورة)، فاسمح به؛ فمن دونه لا يستطيع التطبيق عرض وحدة HC-05 أو الاتصال بها. ولاختبار التطبيق دون تثبيته، شغّل المشروع مباشرة باستخدام تطبيق MIT AI2 Companion.
الخطوة 7: الاتصال والاختبار
أقرِن وحدة HC-05
شغّل بلوتوث في هاتفك وابحث عن أجهزة جديدة. ستظهر الوحدة باسم “HC-05”. أقرن الهاتف بها باستخدام رمز PIN 1234 (أو 0000 في بعض الوحدات). يكفي الإقران مرة واحدة؛ فالهاتف يتذكر الجهاز.
الاختبار الأول
ضع السيارة على صندوق أو كومة كتب حتى تدور العجلات بحرية. اضبط قيم setSpeed() الأربع كلها في setup() على 120، ثم ارفع البرنامج بعد فصل وحدة HC-05. أعد توصيل HC-05 وافتح تطبيق RobotCarControl. اضغط “Select Bluetooth Device” واختر HC-05 من القائمة؛ فتتغير تسمية الحالة (Label1) إلى “Connected”. اضغط أزرار الأمام والخلف واليسار واليمين مرة واحدة لكل منها، وتحقق من أن العجلات الأربع كلها تدور في الاتجاه المتوقع. وإن لم يحدث ذلك، فراجع «اتجاه دوران خاطئ» في قسم استكشاف الأخطاء وإصلاحها. بعد ذلك ضع السيارة على الأرض. اضغط مع الاستمرار على زر لتسير السيارة، وحرّره لتتوقف.
استكشاف الأخطاء وإصلاحها
فشل الرفع
إذا أظهرت Arduino IDE الرسالة “avrdude: stk500_getsync(): not in sync”، فالأرجح أن وحدة HC-05 ما زالت موصولة بالطرفين 0 و1. افصل سلكي TXD وRXD، وارفع البرنامج، ثم أعد توصيلهما. سبّب لي هذا مشكلات في النسخة الأولى من هذه السيارة، نسخة Plexiglas.
الاتصال قائم لكن السيارة لا تتحرك
تحقق من أن TXD في HC-05 موصول بـ RX في Arduino (الطرف 0)، وأن RXD موصول بـ TX (الطرف 1). يجب أن يستخدم البرنامج سرعة 9600 baud، وهي السرعة الافتراضية لـ HC-05. ومعدل الباود الخاطئ لا يسبب تأخيرًا، بل يستقبل Arduino أحرفًا خاطئة فلا تستجيب السيارة إطلاقًا. وتحقق أيضًا من أن الدرع مثبت جيدًا فوق Arduino، وأن بطارية LiPo مشحونة وموصولة وفي وضع التشغيل.
اتجاه دوران خاطئ
إذا دارت إحدى العجلات للخلف عند إرسال F، فبدّل سلكي ذلك المحرك في طرف التوصيل اللولبي الخاص به. وإذا جعل F السيارة كلها تسير للخلف، فبدّل أسلاك المحركات الأربعة كلها، أو بدّل FORWARD وBACKWARD في الكود. وإذا جعل L السيارة تنعطف يمينًا، فبدّل زوجي المحركات الأيسر والأيمن (M1/M2 مع M3/M4)، أو بدّل محتوى turnLeft() وturnRight() في الكود.
أحد جانبي السيارة لا يتحرك
افحص التوصيلات في ذلك الجانب: يجب أن تكون أسلاك المحركات مثبتة بإحكام في أطراف التوصيل اللولبية وأن تكون البراغي مشدودة. ولتحديد المحرك المعطل، ضع // أمام أسطر motor2 وmotor3 وmotor4 في forward()، ثم ارفع البرنامج وأرسل F: يجب أن يدور محرك M1 وحده. كرر ذلك لكل محرك. إذا دار المحرك عند توصيله بمنفذ آخر، فالمنفذ الأول هو المعطل؛ وإذا لم يدر على أي منفذ، فافحص المحرك وأسلاكه.
يتصل التطبيق ولكن الأزرار لا تفعل شيئًا
في واجهة Blocks تحقق من أن كل كتلة SendText تستخدم BluetoothClient1 وترسل حرفًا كبيرًا (Uppercase)؛ فالبرنامج يتجاهل الأحرف الصغيرة f وb وl وr وs. ويجب أن تعرض Label1 الحالة “Connected” بعد اختيار HC-05 في التطبيق.
ضعف المحركات أو إعادة تشغيل Arduino
إذا كانت المحركات ضعيفة، أو كانت السيارة تتصرف بشكل غير منتظم، أو كان Arduino يعيد التشغيل عند بدء المحركات، فافحص البطارية أولًا. عندما تبدأ المحركات الأربعة بالدوران معًا، تتسبب ذروة التيار في انخفاض الجهد؛ وعندما ينخفض الجهد على VIN إلى أقل من نحو 7 V قد يعيد Arduino التشغيل، كما يُبطئ الجهد المنخفض المحركات. قِس جهد بطارية LiPo بجهاز القياس المتعدد (Multimeter): عند نحو 6.6 V (أي 3.3 V لكل خلية) توقف وأعد شحنها. ومع حزمة 4 × AA استخدم بطاريات جديدة. افحص جميع أسلاك الطاقة بحثًا عن تلامس غير محكم. وإذا استمرت إعادة التشغيل مع حزمة مشحونة، فانزع وصلة PWR وغذِّ Arduino بشكل منفصل عبر USB.
يستمر الروبوت في التحرك بعد تحرير الزر
أمر التوقف S لا يُرسَل أو لا يُستقبَل عند رفع إصبعك. في التطبيق يحتاج كل زر إلى كتلة TouchDown (حرف الحركة) وكتلة TouchUp (الحرف S) معًا. ومن دون كتل TouchUp لا يستقبل Arduino أمر التوقف أبدًا.
الأسئلة الشائعة
نعم. لا تستطيع وحدة HC-06 إلا قبول الاتصال (وضع التابع Slave)؛ ولا يمكنها بدء اتصال. وهذا كافٍ هنا، لأن الهاتف هو الذي يبدأ الاتصال دائمًا. والتوصيلات ومعدل الباود متطابقة.
ليس مباشرة. تستخدم وحدة HC-05 ملف التعريف SPP (Serial Port Profile، وهو نمط Bluetooth Classic الذي يعمل ككابل تسلسلي)، ولا يتيحه نظام iOS لتطبيقات الجهات الخارجية. لاستخدام iPhone استبدل HC-05 بوحدة BLE (Bluetooth Low Energy، بلوتوث منخفض الطاقة) مثل HM-10، أو استخدم ESP32 مع BLE، وعدّل التطبيق. وESP32 لوحة تطوير بمتحكم دقيق مزودة ببلوتوث مدمج.
نعم، لكن مع مكتبة مختلفة. يستخدم درع V2 مكتبة Adafruit_MotorShield بدلًا من AFMotor.h، ويتواصل مع Arduino عبر I2C (ناقل لا يحتاج إلا إلى سلكين). التوصيلات وترتيب منافذ المحركات متشابهة، لكن عليك إعادة كتابة أجزاء الكود الخاصة بتهيئة المحركات والتحكم بها لتناسب مكتبة V2.
المشاريع التالية
الخطوة التالية هي OmObiArm: تُركَّب فيه ذراع روبوتية بست درجات حرية (6-DOF: خمسة مفاصل إضافة إلى القابض) على القاعدة نفسها. مشاريع ذات صلة:
- بناء سيارة روبوتية تتفادى العوائق باستخدام Arduino: يستخدم مستشعر الموجات فوق الصوتية مثبتًا على محرك سيرفو مع ملاحة ذاتية، على سيارة بعجلتين مزودة بدرع Arduino Motor Shield Rev3.
- سيارة روبوتية متقدمة ذاتية القيادة ومتحكَّم بها عبر البلوتوث مع Arduino Mega: لوحة Arduino Mega مع أربعة مستشعرات للموجات فوق الصوتية، ووضع ذاتي ووضع تحكم عبر بلوتوث.
- بناء روبوت تتبع الخط بمستشعرات KY-033: سيارة تتبع خطًا باستخدام مستشعرات الأشعة تحت الحمراء.
إذا كانت لديك أسئلة حول مشروعك، فاترك تعليقًا أدناه.
ملفات طباعة ثلاثية الأبعاد (STL)
متجر OmArTronics: ملفات طباعة ثلاثية الأبعاد (STL) لـ OmObi. الكود ومخطط التوصيل وقائمة القطع موجودة في هذا الدرس.

رأي واحد حول “Building the Bluetooth-Controlled Robot Car OmObi with Arduino, HC-05, and Adafruit Motor Shield”