بناء سيارة روبوتية يُتحكَّم بها عبر البلوتوث باستخدام Arduino وHC-05 وAdafruit Motor Shield

يحتوي هذا المقال على روابط تسويق بالعمولة مُعلَّمة بعلامة *. بصفتي شريكًا في برنامج Amazon Associates، أربح من عمليات الشراء المؤهلة، دون أي تكلفة إضافية عليك. يساعد ذلك على إبقاء الشروحات مجانية.

يُحمَّل الفيديو من YouTube (Google)، وقد يضع ملفات تعريف الارتباط (Cookies). سياسة الخصوصية

شاهد مراحل البناء كاملة: سيارة روبوتية يُتحكَّم بها عبر بلوتوث باستخدام Arduino وHC-05 وAdafruit Motor Shield

تحديث: لهذه السيارة نسخة أحدث مطبوعة بالطباعة ثلاثية الأبعاد (3D)، OmObi. يستخدم OmObi الكود والتطبيق نفسيهما، وملفات STL الخاصة به متوفرة في المتجر. ويبقى هذا المقال مخصصًا للبناء الأصلي على لوح مقطوع من صفيحة أكريليك (Plexiglas).

ملخص سريع

تتلقى هذه السيارة رباعية الدفع الأوامر من تطبيق Android عبر بلوتوث. تعمل بلوحة Arduino Uno مع درع المحركات Adafruit Motor Shield V1.2 ووحدة بلوتوث HC-05. ستقطع لوح الأكريليك، وتوصّل المحركات ووحدة HC-05، وترفع برنامج Arduino (Sketch) إلى اللوحة، ثم تبني تطبيق التحكم في MIT App Inventor.

بنيتُ هذه السيارة كمشروع تالٍ لدرسي عن وحدتي بلوتوث HC-05/HC-06. إذا كنت جديدًا على Arduino، فابدأ بالاطلاع على دليل أساسيات برمجة Arduino.

كيف تعمل السيارة

يتكون النظام من أربعة أجزاء: هاتف Android، ووحدة بلوتوث HC-05، ولوحة Arduino Uno، ودرع المحركات Adafruit Motor Shield مع أربعة محركات تيار مستمر.

يشغّل هاتف Android تطبيق تحكم مبنيًّا باستخدام MIT App Inventor، وهي أداة مجانية تعمل في المتصفح وتبني تطبيقات Android من كتل تُسحب وتُفلت. عندما تضغط زر اتجاه، يرسل التطبيق F أو B أو L أو R عبر بلوتوث. وعندما تحرره، يرسل التطبيق S (توقف).

تستقبل وحدة HC-05 الأمر وتمرره إلى Arduino عبر اتصال تسلسلي: تنتقل البتات واحدًا تلو الآخر على سلكين، RX (الاستقبال، الطرف 0) وTX (الإرسال، الطرف 1). تعمل HC-05 كجسر تسلسلي لاسلكي بين الهاتف وArduino. ويتناول درسي شرح البلوتوث HC-05/HC-06 مع Arduino هذه الوحدة بالتفصيل.

يقرأ Arduino الحرف من المخزن المؤقت التسلسلي (Serial Buffer)، وهو منطقة ذاكرة صغيرة تنتظر فيها البايتات المستقبَلة حتى يقرأها البرنامج. ثم يستدعي دالة الحركة المناسبة: forward أو backward أو turnLeft أو turnRight أو stop.

لوحة Adafruit Motor Shield V1.2 هي درع (Shield)، أي لوحة إضافية تُركَّب فوق أطراف التوصيل في Arduino. لا تستطيع أطراف Arduino توفير التيار الذي يحتاجه المحرك، لذا تقوم شريحتا قيادة المحركات L293D في الدرع بتمرير تيار البطارية إلى المحركات الأربعة، بحد أقصى 0.6 A لكل محرك. يتصل كل محرك بأحد أطراف المحركات من M1 إلى M4، وهي أطراف توصيل لولبية (Screw Terminals) تثبّت أسلاك المحرك بالضغط. يتحكم البرنامج في الدرع باستخدام مكتبة AFMotor، وهي حزمة من الكود الجاهز يمكن تضمينها في البرنامج. تحدد المكتبة الاتجاه (FORWARD وBACKWARD وRELEASE) والسرعة (من 0 إلى 255). وللانعطاف، يدور أحد الجانبين إلى الأمام بينما يدور الجانب الآخر إلى الخلف، وهو انعطاف على طريقة الدبابات. لمعرفة مبادئ وحدات قيادة المحركات، راجع شرح وحدة قيادة المحركات L298N.

المكونات (قائمة المواد)

المكوّنالكميةمطلوب؟الغرضملاحظات
Arduino Uno1مطلوبالمتحكم الدقيق الرئيسيتصلح أي لوحة متوافقة مع Uno
Adafruit Motor Shield V1.21مطلوبيقود أربعة محركات تيار مستمريُركَّب فوق Arduino. استخدم V1.2 أو نسخة مقلَّدة منه تعتمد L293D: الدرع الأحدث V2 يحتاج إلى مكتبة Adafruit_MotorShield وكود مختلف
وحدة البلوتوث HC-051مطلوبوصلة تسلسلية لاسلكية مع الهاتفتعمل HC-06 أيضًا: فهي تقبل الاتصالات الواردة فقط (وضع التابع Slave)، وهذا كل ما يحتاجه هذا المشروع
محركات تيار مستمر بعلب تروس4مطلوبلتحريك العجلات الأربععادةً محركات بتروس تعمل بجهد من 3 إلى 6 V
العجلات4مطلوبتُركَّب على أعمدة المحركاتاخترها بما يناسب مقاس عمود علبة التروس
لوح أكريليك1مطلوبيحمل المحركات والإلكترونيات والبطاريةيُقطع بالمقاس المطلوب؛ وتصلح أيضًا مادة ألواح مشابهة
حوامل محركات بالطباعة ثلاثية الأبعاد (3D)4اختياريتثبّت المحركات على لوح الأكريليكتصلح أيضًا زوايا معدنية على شكل L
حامل Arduino بالطباعة ثلاثية الأبعاد (3D)1اختيارييثبّت Arduino على لوح الأكريليكيصلح أيضًا شريط إسفنجي لاصق على الوجهين أو فواصل تثبيت (Standoffs، وهي مباعدات ملولبة بين اللوحة ولوح الأكريليك)
حزمة بطاريات، 4 × AA أو ما يماثلها1مطلوبتغذّي المحركات بالطاقة (وتغذّي Arduino أيضًا عبر وصلة PWR (Jumper)، انظر الخطوة 4)6 V؛ استخدم بطاريات جديدة
مقاومات، 1 kΩ و2 kΩ1 من كل نوعموصى بهمقسم جهد على الطرف RXD في HC-05انظر الخطوة 3
مفتاح تشغيل/إيقاف1اختيارييطفئ السيارة دون فصل حزمة البطارياتيُركَّب في مسار السلك الأحمر للبطارية
أسلاك التوصيل (Jumper)عدةمطلوبوصّل HC-05 بلوحة Arduinoأنثى-أنثى، تُركَّب على أطراف توصيل ملحومة على الدرع (انظر الخطوة 3)
براغٍ وصواميل وأعمدة تباعدمتنوعةمطلوبالتجميع الميكانيكيالمقاس M3 هو الشائع
هاتف Android1مطلوبيشغّل تطبيق التحكمتستخدم HC-05 تقنية Bluetooth Classic (وليس Bluetooth Low Energy)؛ لا يمكن لهواتف iPhone الاتصال بها، كما أن App Inventor يبني تطبيقات Android فقط
3D rendering of the four-wheel-drive chassis: acrylic plate, four yellow geared DC motors and wheels, before the electronics are mounted

الخطوة 1: بناء الهيكل

الهيكل (Chassis)، أي إطار السيارة، عبارة عن لوح أكريليك مسطح. وهو خفيف وسهل القطع ومتين بما يكفي لحمل أربعة محركات والإلكترونيات وحزمة البطاريات.

اقطع لوح الأكريليك

قِس لوح الأكريليك واقطعه. المقاس المعتاد حوالي 20 cm × 15 cm؛ عدّله بما يناسب محركاتك وحزمة البطاريات. استخدم منشارًا أو قاطع أكريليك (سكين تحزيز معقوفة لألواح البلاستيك) للحصول على حواف نظيفة. بعد القطع، نزعتُ الغشاء الواقي، وحددتُ مواضع ثقوب المكونات ثم ثقبتُها. وثقبتُ ثقبًا إضافيًا لتمرير أسلاك المحركات عبر اللوح.

اطبع حوامل المحركات

اطبع أربعة حوامل للمحركات تمسك جسم المحرك وتسمح لعمود علبة التروس بالبروز إلى الخارج عند حافة لوح الأكريليك. صمّمتُ حواملي في Autodesk Inventor. بعد الطباعة، سخّنتُ حشوات ملولبة (Threaded Inserts، وهي جُلَب معدنية صغيرة ذات سن داخلي) وضغطتُها داخل البلاستيك، كي تُثبَّت البراغي مباشرة في الحوامل. إن لم تكن لديك طابعة ثلاثية الأبعاد (3D)، فاستخدم زوايا معدنية على شكل L؛ أما الغراء الساخن فلا يصمد إلا في الاختبارات الأولى.

جهّز حامل Arduino

ثبّت اللوحة بحامل مطبوع بالطباعة ثلاثية الأبعاد (3D) أو بفواصل تثبيت (Standoffs) وبراغي M3 عبر ثقوب التثبيت في Arduino. يصلح أيضًا شريط إسفنجي لاصق على الوجهين. يُبقي الحامل اللوحة في مكانها أثناء سير السيارة ويمنع الأسلاك من الانفصال بالشد.

الخطوة 2: تركيب المحركات والإلكترونيات

ثبّت المحركات في الحوامل

ثبّت كل محرك في حامله (أو في الزاوية المعدنية L) بالبراغي والصواميل. ركّب المحركات بحيث تتجه جميع الأعمدة إلى الخارج. المحركات اليسرى واليمنى صور معكوسة لبعضها، لذا قد يدور أحد الجانبين إلى الخلف عند توصيلها بالطريقة نفسها؛ ويمكنك إصلاح ذلك بتبديل سلكي تلك المحركات (انظر شرح الكود).

ركّب مجموعات المحركات على لوح الأكريليك

اربط حوامل المحركات بلوح الأكريليك بالبراغي، محركين على كل جانب، بأكبر تباعد ممكن بينها لتحقيق الثبات. تأكد من أن العجلات تدور بحرية دون أن تحتك بلوح الأكريليك أو ببعضها.

ركّب Arduino والدرع

ثبّت حامل Arduino (أو فواصل التثبيت) في منتصف لوح الأكريليك أو في مؤخرته، واترك مساحة في المقدمة أو على الجانبين لحزمة البطاريات. ضع لوحة Uno في الحامل وثبّتها بالبراغي. اضغط درع المحركات على أطراف التوصيل في Arduino حتى يستقر تمامًا، وتأكد من عدم انثناء أي طرف أو خروجه عن مقبسه.

الخطوة 3: التوصيلات

يوضّح مخطط التوصيل أدناه المحركات والبطارية ومفتاح التشغيل/الإيقاف؛ أما توصيلات HC-05 فتأتي في جدول مستقل. قبل توصيل المحركات، وضعتُ على كل سلك محرك ملصقًا باسم محركه، كي أتمكن من مطابقة الأزواج الأربعة مع M1 إلى M4.

Wiring diagram: four 3 to 6 V DC motors on the motor terminals M1 to M4 of the Adafruit Motor Shield V1.2, and two 4 × AAA battery holders in series, with an on/off switch in the red wire, on the EXT_PWR terminal

توصيلات المحركات

المحركطرف المحركالموضع على السيارة
المحرك 1M1الجانب الأيسر (أمامي أو خلفي، الترتيب غير مهم)
المحرك 2M2الجانب الأيسر (أمامي أو خلفي، الترتيب غير مهم)
المحرك 3M3الجانب الأيمن (أمامي أو خلفي، الترتيب غير مهم)
المحرك 4M4الجانب الأيمن (أمامي أو خلفي، الترتيب غير مهم)

أدخِل سلكي كل محرك في طرف المحرك الخاص به وأحكِم شد البراغي.

توصيلات HC-05

طرف HC-05طرف Arduinoملاحظات
VCC5 Vيغذّي HC-05 بالطاقة
GNDGNDأرضي مشترك (مرجع 0 V المشترك بين اللوحتين)
TXDRX (الطرف 0)ترسل HC-05 البيانات إلى Arduino
RXDTX (الطرف 1)يرسل Arduino البيانات إلى HC-05

يعمل الطرف RXD في HC-05 بمنطق 3.3 V، لكن الطرف TX في Arduino يرسل 5 V. أضِف مقسم جهد، وهو مقاومتان تخفّضان إشارة 5 V إلى حوالي 3.3 V: مقاومة 1 kΩ من TX في Arduino إلى RXD، ومقاومة 2 kΩ من RXD إلى GND. يمكنك الاستغناء عنه إذا كانت لوحة التوصيل (Breakout Board) الخاصة بوحدة HC-05 (اللوحة الحاملة الصغيرة المزودة بأطراف التوصيل) تحتوي على محوّل مستويات (Level Shifter)، وهو دائرة تحوّل إشارات 5 V إلى 3.3 V. يغطي درع المحركات أطراف التوصيل في Arduino. في سيارتي، لحمتُ أطراف توصيل قصيرة على الدرع، اثنين منها للطرفين 0 و1 واثنين لـ 5 V وGND، ثم ركّبتُ عليها أسلاك HC-05. وصّلتُ الوحدة مباشرة دون مقسم جهد؛ نجح ذلك، لكن مقسم الجهد هو الطريقة الأكثر أمانًا. ثبّتُّ HC-05 على لوح الأكريليك بمادة لاصقة.

الطرفان 0/1 ورفع البرامج

تحذير: الطرفان 0 (RX) و1 (TX) هما أيضًا طرفا USB التسلسليان اللذان يستخدمهما Arduino لرفع البرامج وللشاشة التسلسلية (Serial Monitor). الشاشة التسلسلية هي النافذة في Arduino IDE (البرنامج الذي تكتب به برامج Arduino وترفعها) التي تعرض النص التسلسلي. افصل على الأقل سلكي TXD وRXD الخاصين بوحدة HC-05 قبل كل عملية رفع، وإلا فستفشل عملية الرفع. واجهتُ مشكلات في هذه السيارة عند الرفع مع بقاء HC-05 موصولة. أعِد توصيل الأسلاك بعد ذلك واضغط زر إعادة الضبط (Reset). وطالما أن HC-05 موصولة بالطرفين 0/1، لا يمكن استخدام الشاشة التسلسلية.

إذا احتجت إلى بلوتوث والشاشة التسلسلية في الوقت نفسه، فوصّل HC-05 عبر SoftwareSerial، وهي مكتبة تنشئ منفذًا تسلسليًا ثانيًا على أطراف أخرى. استخدم أطرافًا يتركها درع المحركات حرة، مثل A0 وA1. في البرنامج، أنشئ منفذ SoftwareSerial على هذين الطرفين واستخدمه بدلًا من Serial. لا تستخدم الطرف 3: فالدرع يستخدمه للمحرك M2.

الخطوة 4: التغذية بالطاقة

وصّل حزمة 4 × AA (6 V) بطرف EXT_PWR على درع المحركات: السلك الأحمر إلى الطرف +، والسلك الأسود إلى الطرف –. يغذّي الدرع المحركات من هذا الطرف، وأرضيّه موصول بأرضي Arduino عبر أطراف التوصيل. لا تغذِّ المحركات من بطارية 9 V (PP3): فهي لا تستطيع توفير التيار الذي تسحبه أربعة محركات تيار مستمر تحت الحمل.

يحتوي الدرع على وصلة (Jumper) مكتوب عليها PWR، وهي قابس صغير قابل للنزع يصل بين طرفين. عند تركيب هذه الوصلة، تغذّي البطارية الموصولة بـ EXT_PWR أيضًا الطرف VIN في Arduino (مدخل الطاقة الخام). يحتاج منظم الجهد المدمج في Uno (دائرة تحافظ على ثبات جهد الخرج) إلى حوالي 7 V على VIN للحصول على 5 V مستقرة، لذا فإن جهد حزمة 6 V لا يكفي لذلك. إذا حدثت إعادة ضبط (Reset) في Arduino أو HC-05 عند بدء دوران المحركات، فانزع وصلة PWR وغذِّ Uno بشكل منفصل. استخدم بنك طاقة USB أو بطارية 9 V (PP3) على مقبس DC (مقبس الطاقة الدائري في Uno). في هذا الإعداد، تغذّي بطارية 9 V لوحة Uno ووحدة HC-05 فقط؛ وتبقى المحركات تعمل من حزمة 4 × AA.

أضفتُ مفتاح تشغيل/إيقاف إلى خط البطارية وثبّتُّه على الإطار، كي أتمكن من إطفاء السيارة دون فصل حزمة البطاريات. يُركَّب المفتاح في مسار السلك الأحمر.

في سيارتي، البطارية حزمة LiPo من نوع 3S (ثلاث خلايا ليثيوم بوليمر موصولة على التوالي، 11.1 V، 5200 mAh)، مثبتة على لوح الأكريليك بأربطة الكابلات. مع تركيب وصلة PWR، توفر جهدًا كافيًا للوحة Uno على VIN. ويُظهر مخطط التوصيل جهدًا مماثلًا: حاملا بطاريات 4 × AAA موصولان على التوالي، أي حوالي 12 V. لكن المحركات مصمَّمة لجهد من 3 إلى 6 V. تُسقط شريحة L293D حوالي 2.6 V، لذا تحصل المحركات عند السرعة القصوى على نحو 8.5 V من بطارية LiPo. أما OmObi، النسخة الأحدث المطبوعة بالطباعة ثلاثية الأبعاد (3D)، فيعمل ببطارية LiPo من نوع 2S (7.4 V). في أول بناء لك، تُعد حزمة 4 × AA الخيار الأكثر أمانًا. ولمدة تشغيل أطول، تصلح أيضًا حزمة Li-ion قابلة لإعادة الشحن من نوع 2S (خليتان على التوالي، 7.4 V جهد اسمي، و8.4 V عند الشحن الكامل). استخدمها مع نظام BMS (نظام إدارة البطارية)، وهو لوحة صغيرة تحمي الخلايا من الشحن الزائد والتفريغ العميق. بعد هبوط الجهد في L293D، يصل إلى المحركات حوالي 5.8 V كحد أقصى.

الخطوة 5: برمجة Arduino

يقرأ البرنامج أدناه أوامر مكونة من حرف واحد من HC-05 ويقود المحركات الأربعة. ويستخدم مكتبة AFMotor، وهي مكتبة Adafruit الخاصة بدرع المحركات V1. ثبّتها في Arduino IDE من Sketch > Include Library > Manage Libraries: ابحث عن “Adafruit Motor Shield library” (وليس مكتبة V2).

لرفع البرنامج، وصّل Uno عبر USB، واختر Tools > Board > Arduino Uno والمنفذ المناسب من Tools > Port، ثم انقر Upload.

مهم: افصل HC-05 عن الطرفين 0 و1 قبل رفع هذا البرنامج. أعِد توصيلها بعد اكتمال الرفع، ثم أعِد ضبط Arduino (Reset).

/**
 * Author: Omar Draidrya
 * Date: 2024/07/03
 * Bluetooth-controlled 4WD robot car 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);
}

شرح الكود

ينشئ البرنامج أربعة كائنات للمحركات، من motor1(1) إلى motor4(4)، كائنًا لكل طرف محرك من M1 إلى M4. في setup()، يبدأ الاتصال التسلسلي بسرعة 9600 baud (بت في الثانية). يجب أن يستخدم الجانبان السرعة نفسها؛ و9600 هي السرعة الافتراضية لوحدة HC-05 في وضع البيانات (وضعها العادي الذي تمرر فيه البيانات). تُضبط المحركات الأربعة كلها على السرعة القصوى (255 من 255).

كل أمر عبارة عن حرف ASCII واحد (حرف يُخزَّن في بايت واحد)، لذا لا يحتاج البرنامج إلى تحليل نصوص. تُتجاهَل الأحرف الأخرى غير F وB وL وR وS.

تُشغّل الدالة forward() المحركات الأربعة كلها بالاتجاه FORWARD، فتسير السيارة إلى الأمام مباشرة. وتُشغّلها backward() بالاتجاه BACKWARD. تُشغّل turnLeft() المحركات اليسرى إلى الخلف والمحركات اليمنى إلى الأمام، وهو انعطاف إلى اليسار على طريقة الدبابات. وتفعل turnRight() العكس. تستدعي stop() الأمر RELEASE لجميع المحركات، مما يقطع الطاقة عنها؛ فتتدحرج السيارة قليلًا ثم تتوقف.

تعتمد دوال الانعطاف على تقسيم المحركات إلى يسار ويمين الوارد في جدول المحركات في الخطوة 3. إذا دارت إحدى العجلات في الاتجاه الخطأ، فبدّل سلكي ذلك المحرك عند طرف المحرك الخاص به. وإذا سارت السيارة كلها إلى الخلف عند الأمر F، فبدّل أسلاك المحركات الأربعة كلها، أو بدّل FORWARD وBACKWARD في الكود.

كيفية تغيير السرعة

تُضبط السرعة في setup() باستخدام motor1.setSpeed(255). تتراوح القيمة من 0 (متوقف) إلى 255 (السرعة القصوى). لإبطاء السيارة، خفّض هذه القيمة. القيمة 150 تشغّل المحرك لنحو 59 % من كل دورة PWM. تعني PWM (تعديل عرض النبضة) أن الدرع يشغّل المحرك ويطفئه بسرعة كبيرة جدًا، وتحدد نسبة زمن التشغيل السرعة. تعتمد السرعة الفعلية للعجلات أيضًا على جهد البطارية والحمل، وقد لا تكفي القيم المنخفضة جدًا لبدء دوران المحركات أصلًا. يمكنك ضبط سرعات مختلفة للانعطاف وللسير المستقيم باستدعاء setSpeed() داخل دوال الحركة.

كيفية اختبار الكود بأمان

في الاختبار الأول، ضع السيارة على صندوق أو كومة كتب بحيث لا تلامس العجلات الأرض. بهذه الطريقة يمكنك التحقق من كل اتجاه دون أن تنطلق السيارة وتسقط عن الطاولة. اتصل عبر بلوتوث، وأرسل كل أمر من التطبيق، وتحقق من أن العجلات الأربع كلها تدور في الاتجاه المتوقع. عندما يتحقق ذلك، ضع السيارة على الأرض واختبرها بسرعة منخفضة مع ضبط setSpeed() على حوالي 120.

الخطوة 6: بناء تطبيق Android

يُبنى تطبيق الهاتف في MIT App Inventor. يتصل بوحدة HC-05 عبر بلوتوث ويرسل أوامر الاتجاه. تبني التطبيق من الكتل، لذا لا تحتاج إلى كتابة أي كود بلغة Java أو Kotlin، وهما لغتا البرمجة المعتادتان لتطبيقات Android.

سجّل وأنشئ مشروعًا

  • انتقل إلى MIT App Inventor (ai2.appinventor.mit.edu) وسجّل الدخول بحساب Google الخاص بك.
  • انقر على “Start New Project” (بدء مشروع جديد) وسمِّه “RobotCarControl”.

صمّم واجهة المستخدم

في عرض Designer (شاشة App Inventor التي تضع فيها مكونات التطبيق)، أضِف المكونات التالية:

  • ListPicker: اضبط نصه على “Select Bluetooth Device”. يختار المستخدم من هذه القائمة جهاز البلوتوث المقترن.
  • Label: يعرض حالة الاتصال. تضبطه الكتل على “Connected” أو “Not Connected”.
  • BluetoothClient: من قسم Connectivity في لوحة Palette. وهو مكوّن غير مرئي يتولى إدارة اتصال بلوتوث.
  • أربعة أزرار: زر لكل اتجاه. اضبط نصوصها وألوانها بحيث تكون الاتجاهات واضحة.

يسمّي App Inventor المكونات الجديدة تلقائيًا (ListPicker1، Label1، BluetoothClient1). احتفظ بهذه الأسماء الافتراضية، لأن الكتل أدناه تستخدمها. أعِد تسمية الأزرار الأربعة فقط (ButtonForward، ButtonBackward، ButtonLeft، ButtonRight) باستخدام زر Rename في لوحة Components.

برمج الكتل

انتقل إلى عرض Blocks، وهو الشاشة التي تبرمج فيها المكونات بالكتل. القائمة أدناه نسخة نصية من الكتل، وليست كودًا يمكنك كتابته. انقر على مكوّن في لوحة Blocks (مثل ListPicker1) واسحب الكتلة المناسبة، مثل “when ListPicker1.BeforePicking”، إلى مساحة العمل. تُظهر لقطة الشاشة أدناه الكتل المكتملة. وفيها سُمّيت الأزرار Forward_Button وBackward_Button وLeft_Button وRight_Button؛ وتصلح أي أسماء ما دامت الكتل مطابقة لها. كما تضبط كتل الاتصال هناك خلفية Label1 على الأخضر أو الأحمر.

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"
MIT App Inventor blocks: ListPicker connection logic and TouchDown/TouchUp handlers for the four direction buttons

فهم منطق الكتل

ListPicker1.BeforePicking: عندما ينقر المستخدم على ListPicker، يملأ القائمة بجميع أجهزة البلوتوث المقترنة (العناوين والأسماء) من BluetoothClient1.AddressesAndNames.

ListPicker1.AfterPicking: بمجرد أن يختار المستخدم جهازًا، يتصل التطبيق باستخدام BluetoothClient1.Connect والعنوان المحدد. عند النجاح، يعرض Label1.Text النص “Connected”، وإلا فيعرض “Not Connected”.

أحداث TouchDown: عندما يضغط المستخدم على زر اتجاه (يلمسه)، يرسل التطبيق حرف الأمر المناسب (F أو B أو L أو R) باستخدام BluetoothClient1.SendText، ولكن فقط ما دام اتصال بلوتوث نشطًا.

أحداث TouchUp: عندما يحرر المستخدم أي زر اتجاه (يرفع إصبعه عنه)، يرسل التطبيق “S”. لذلك لا تتحرك السيارة إلا ما دمت تضغط على زر. عند استقبال S تنتقل المحركات إلى RELEASE، وتتدحرج السيارة مسافة قصيرة قبل أن تتوقف.

الخطوة 7: الاتصال والقيادة

أقرِن وحدة HC-05

شغّل بلوتوث على الهاتف، وافتح إعدادات بلوتوث وابحث عن أجهزة جديدة. اقترن بوحدة HC-05 باستخدام رمز PIN 1234 (0000 في بعض الوحدات). يتذكر الهاتف الاقتران، لذا تفعل ذلك مرة واحدة فقط.

ثبّت التطبيق واتصل

ثبّت التطبيق على الهاتف أولًا. في App Inventor، اختر Build > Android App (.apk). نزّل ملف .apk (ملف تثبيت Android) إلى الهاتف وثبّته؛ سيطلب منك Android السماح بالتثبيت من هذا المصدر. وللاختبارات السريعة، يمكنك بدلًا من ذلك تشغيل المشروع مباشرة باستخدام تطبيق MIT AI2 Companion. إذا طلب Android إذن “Nearby devices” (الأجهزة المجاورة)، فاسمح به، وإلا فلن يتمكن التطبيق من عرض HC-05 أو الاتصال بها. استخدمتُ التطبيق على جهاز لوحي يعمل بنظام Android وثبّتُّه من ملف .apk الذي نزّلته.

افتح RobotCarControl، وانقر على “Select Bluetooth Device” واختر HC-05. يجب أن يعرض Label1 النص “Connected”. اضغط أزرار الاتجاه: تسير السيارة إلى الأمام وإلى الخلف، وتنعطف يسارًا ويمينًا، وتتوقف عندما تحرر الزر.

الاختبار واستكشاف الأخطاء وإصلاحها والأسئلة الشائعة

تستخدم هذه السيارة الكود والتطبيق والتوصيلات نفسها التي تستخدمها النسخة الأحدث المطبوعة بالطباعة ثلاثية الأبعاد (3D)، OmObi. يُحدَّث الاختبار الأول واستكشاف الأخطاء وإصلاحها والأسئلة الشائعة في مقال OmObi: الاختبار الأول, استكشاف الأخطاء وإصلاحها و الأسئلة الشائعة.

شروحات ذات صلة

ترقيات ممكنة: مستشعر موجات فوق صوتية لتجنب العوائق، أو كاميرا للقيادة بمنظور FPV (منظور الشخص الأول)، أو ESP32 للتحكم عبر واي فاي (Wi-Fi).

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

أضف تعليق