مشروع الاردوينو الرادار اصنع نظام كشف خاص بك بخطوات بسيطة

مشروع رادار اردوينو: بناء وكود سهل

مشروع اردوينو الرادار اصنع نظام كشف خاص بك بخطوات بسيطة

رادار الأردوينو: اصنع نظام كشفك بخطوات سهلة

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

ما هو الرادار وكيف يعمل ببساطة؟

كلمة رادار هي اختصار لـ "Radio Detection and Ranging" وتعني الكشف وتحديد المدى بواسطة أمواج الراديو، يعتمد مبدأ عمل الرادار التقليدي على إرسال موجات كهرومغناطيسية وعندما تصطدم هذه الموجات بجسم ما فإن جزءاً منها يرتد إلى هوائي الاستقبال، من خلال تحليل الزمن الذي استغرقته الموجة للذهاب والعودة يمكن تحديد المسافة إلى الجسم، كما يمكن تحديد اتجاه الجسم من خلال اتجاه الهوائي لحظة استقبال الإشارة المرتدة، مشروعنا هنا سيستخدم مبدأً مشابهاً ولكنه يعتمد على الموجات فوق الصوتية بدلاً من موجات الراديو، الموجات فوق الصوتية هي موجات صوتية ذات تردد أعلى من مدى السمع البشري.

المكونات والأدوات المطلوبة للمشروع:

قبل أن نبدأ في رحلتنا المثيرة لبناء الرادار الخاص بنا دعنا نتأكد من أن لدينا جميع الأدوات والمكونات اللازمة، هذه القائمة شاملة ولكنها بسيطة ومتوفرة في معظم متاجر الإلكترونيات أو عبر الإنترنت:

  1. لوحة أردوينو أونو (Arduino Uno R3): هي العقل المدبر للمشروع. مسؤولة عن معالجة البيانات والتحكم في المكونات الأخرى، يمكن استخدام أي لوحة أردوينو أخرى متوافقة ولكن الأونو هي الأكثر شيوعاً وسهولة في الاستخدام للمبتدئين.
  2. مستشعر الموجات فوق الصوتية (Ultrasonic Sensor HC-SR04): هذا هو "عين" الرادار، يقوم بإرسال نبضات فوق صوتية واستقبال صداها بعد اصطدامها بالأجسام، يحتوي عادةً على أربعة أطراف: VCC (للتغذية)، Trig (لإرسال النبضة)، Echo (لاستقبال الصدى)، و GND (الأرضي).
  3. محرك مؤازر صغير (Servo Motor SG90): هذا المحرك الصغير سيقوم بتدوير مستشعر الموجات فوق الصوتية بزاوية محددة (عادة من 0 إلى 180 درجة) ليتمكن الرادار من مسح المنطقة أمامه، يأتي بثلاثة أسلاك: سلك إشارة (عادة برتقالي أو أصفر)، سلك تغذية (أحمر)، وسلك أرضي (بني أو أسود).
  4. أسلاك توصيل (Jumper Wires): مجموعة من أسلاك التوصيل (ذكر-ذكر، ذكر-أنثى، أنثى-أنثى) لتوصيل المكونات المختلفة ببعضها البعض وبلوحة الأردوينو، يفضل أن تكون ملونة لتسهيل تتبع التوصيلات.
  5. لوحة تجارب (Breadboard) (اختياري ولكن موصى به): تسهل عملية توصيل المكونات بدون الحاجة إلى لحام خاصة للمبتدئين.
  6. كابل USB (Type A to Type B): لتوصيل لوحة الأردوينو بالحاسوب لبرمجتها وتزويدها بالطاقة وأيضاً لنقل البيانات من الرادار إلى الحاسوب لعرضها.
  7. حاسوب شخصي: مثبت عليه بيئة تطوير الأردوينو (Arduino IDE) وبرنامج المعالجة (Processing IDE) لعرض البيانات بشكل رسومي.

مبدأ عمل رادار الأردوينو بالموجات فوق الصوتية:

يعتمد مشروعنا على مبدأ بسيط ولكنه فعال.
1- المسح بواسطة المحرك المؤازر: يتم تثبيت مستشعر الموجات فوق الصوتية HC-SR04 على ذراع المحرك المؤازر SG90. يقوم الأردوينو بإرسال أوامر للمحرك المؤازر ليتحرك بشكل تدريجي بزاوية معينة (مثلاً من 0 إلى 180 درجة ثم العودة) مما يسمح للمستشعر بمسح المنطقة أمامه.
2- إرسال واستقبال الموجات فوق الصوتية: عند كل زاوية يتوقف عندها المحرك المؤازر يقوم الأردوينو بإرسال أمر إلى مستشعر HC-SR04 لإطلاق نبضة قصيرة من الموجات فوق الصوتية عبر طرف Trig.
3- حساب المسافة: عندما تصطدم هذه الموجات بجسم ما ترتد مرة أخرى إلى المستشعر الذي يستقبلها عبر طرف Echo. يقوم الأردوينو بقياس الزمن الذي استغرقته الموجة للذهاب والإياب. بما أن سرعة الصوت في الهواء معروفة (تقريباً 343 متراً في الثانية أو 0.0343 سنتيمتراً في الميكروثانية) يمكن حساب المسافة إلى الجسم باستخدام المعادلة:
  • المسافة = (الزمن × سرعة الصوت) / 2
  • (نقسم على 2 لأن الزمن المقاس هو لرحلة الذهاب والإياب).
4- إرسال البيانات إلى الحاسوب: بعد حساب المسافة عند زاوية معينة يقوم الأردوينو بإرسال بيانات الزاوية والمسافة المقابلة لها إلى الحاسوب عبر منفذ USB التسلسلي.
5- العرض الرسومي: على الحاسوب يقوم برنامج خاص (عادة ما يتم كتابته باستخدام بيئة Processing) باستقبال هذه البيانات (الزاوية والمسافة) وتحويلها إلى إحداثيات لرسم نقطة تمثل الجسم المكتشف على شاشة تشبه شاشة الرادار التقليدية. مع تحرك المحرك المؤازر وتحديث البيانات يتم رسم صورة ديناميكية للمحيط.

خطوات توصيل الدائرة الإلكترونية:

توصيل المكونات بشكل صحيح هو خطوة حاسمة لنجاح المشروع. اتبع الخطوات التالية بعناية:

توصيل مستشعر الموجات فوق الصوتية HC-SR04 بالأردوينو:
  • صل طرف VCC الخاص بالمستشعر بمنفذ 5V على لوحة الأردوينو.
  • صل طرف GND الخاص بالمستشعر بمنفذ GND على لوحة الأردوينو.
  • صل طرف Trig الخاص بالمستشعر بالمنفذ الرقمي 9 (Pin 9) على الأردوينو. (يمكن اختيار منفذ آخر ولكن يجب تعديل الكود وفقاً لذلك).
  • صل طرف Echo الخاص بالمستشعر بالمنفذ الرقمي 10 (Pin 10) على الأردوينو. (يمكن اختيار منفذ آخر ولكن يجب تعديل الكود وفقاً لذلك).
توصيل المحرك المؤازر SG90 بالأردوينو:
  • صل السلك الأحمر (VCC) الخاص بالمحرك المؤازر بمنفذ 5V على لوحة الأردوينو.
  • صل السلك البني أو الأسود (GND) الخاص بالمحرك المؤازر بمنفذ GND على لوحة الأردوينو.
  • صل السلك البرتقالي أو الأصفر (Signal) الخاص بالمحرك المؤازر بالمنفذ الرقمي 11 (Pin 11) على الأردوينو، يجب أن يكون هذا المنفذ يدعم PWM (تعديل عرض النبضة) وعادة ما يُشار إليه بعلامة (~) بجانب رقم المنفذ.

تنبيه هام: تأكد من فصل لوحة الأردوينو عن مصدر الطاقة (USB أو مصدر خارجي) أثناء عملية التوصيل لتجنب أي تلف محتمل للمكونات، بعد الانتهاء من التوصيل قم بمراجعة التوصيلات مرة أخرى للتأكد من صحتها قبل توصيل الطاقة.

برمجة الأردوينو (كود الأردوينو):

الآن بعد توصيل العتاد سنقوم بكتابة الكود الذي سيتحكم في عمل الرادار، افتح بيئة تطوير الأردوينو (Arduino IDE) وانسخ الكود التالي:
#include <Servo.h> // تضمين مكتبة التحكم في المحرك المؤازر

// تعريف أطراف التوصيل
const int trigPin = 9;    // طرف Trig للمستشعر فوق الصوتي
const int echoPin = 10;   // طرف Echo للمستشعر فوق الصوتي
const int servoPin = 11;  // طرف الإشارة للمحرك المؤازر

Servo myServo;  // إنشاء كائن للتحكم في المحرك المؤازر

long duration; // متغير لتخزين زمن ارتداد الموجة
int distance;  // متغير لتخزين المسافة المحسوبة
int angle;     // متغير لتخزين زاوية المحرك الحالية

void setup() {
  pinMode(trigPin, OUTPUT); // تعريف طرف Trig كمخرج
  pinMode(echoPin, INPUT);  // تعريف طرف Echo كمدخل
  myServo.attach(servoPin); // ربط كائن المحرك المؤازر بالطرف المخصص له
  Serial.begin(9600);       // بدء الاتصال التسلسلي بسرعة 9600 باود
  delay(2000);              // تأخير بسيط للسماح للمكونات بالاستقرار
}

void loop() {
  // المسح من زاوية 0 إلى 180 درجة
  for (angle = 0; angle <= 180; angle += 1) { // زيادة الزاوية بمقدار درجة واحدة في كل مرة
    myServo.write(angle);    // توجيه المحرك المؤازر إلى الزاوية الحالية
    delay(30);               // تأخير بسيط للسماح للمحرك بالوصول إلى الزاوية المطلوبة

    // إرسال نبضة فوق صوتية
    digitalWrite(trigPin, LOW);
    delayMicroseconds(2);
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);

    // قراءة زمن ارتداد الموجة
    duration = pulseIn(echoPin, HIGH);

    // حساب المسافة بالسنتيمتر
    // سرعة الصوت = 0.0343 سم/ميكروثانية
    // المسافة = (الزمن * سرعة الصوت) / 2
    distance = duration * 0.0343 / 2;

    // إرسال بيانات الزاوية والمسافة عبر المنفذ التسلسلي
    // التنسيق: "الزاوية,المسافة\n"
    Serial.print(angle);
    Serial.print(",");
    Serial.print(distance);
    Serial.print("\n");
  }

  // المسح من زاوية 180 إلى 0 درجة (للعودة)
  for (angle = 180; angle >= 0; angle -= 1) { // إنقاص الزاوية بمقدار درجة واحدة
    myServo.write(angle);
    delay(30);

    digitalWrite(trigPin, LOW);
    delayMicroseconds(2);
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);

    duration = pulseIn(echoPin, HIGH);
    distance = duration * 0.0343 / 2;

    Serial.print(angle);
    Serial.print(",");
    Serial.print(distance);
    Serial.print("\n");
  }
}

شرح كود الأردوينو:

  • #include <Servo.h>: يتم تضمين مكتبة Servo للتحكم في المحرك المؤازر.
  • const int trigPin = 9;، const int echoPin = 10;، const int servoPin = 11;: تعريف الثوابت التي تمثل أرقام المنافذ المستخدمة.
  • Servo myServo;: إنشاء كائن من الفئة Servo للتحكم في المحرك.
  • void setup (): هذه الدالة تعمل مرة واحدة عند بدء تشغيل الأردوينو أو إعادة تعيينه.
  1. pinMode(trigPin, OUTPUT); و pinMode(echoPin, INPUT);: تحديد وضعية أطراف المستشعر (Trig كمخرج و Echo كمدخل).
  2. myServo.attach(servoPin);: ربط كائن المحرك بالمنفذ الرقمي 11.
  3. Serial.begin(9600);: بدء الاتصال التسلسلي مع الحاسوب بسرعة 9600 بت في الثانية.
  • void loop (): هذه الدالة تعمل بشكل مستمر بعد انتهاء دالة setup ().
  1. حلقة for الأولى: تقوم بتحريك المحرك المؤازر من زاوية 0 إلى 180 درجة بزيادات قدرها درجة واحدة.
  2. myServo.write(angle);: يرسل أمر للمحرك للتحرك إلى الزاوية angle.
  3. delay(30);: تأخير صغير للسماح للمحرك بالوصول إلى الموضع المطلوب قبل أخذ القراءة.
  4. الكود الخاص بإرسال نبضة فوق صوتية: يتم تفعيل طرف trigPin لمدة 10 ميكروثانية.
  5. duration = pulseIn(echoPin, HIGH);: تقيس هذه الدالة مدة بقاء طرف echoPin في حالة HIGH وهو يمثل زمن رحلة الموجة فوق الصوتية ذهاباً وإياباً.
  6. distance = duration * 0.0343 / 2;: حساب المسافة بالسنتيمتر.
  7. Serial.print(...): إرسال بيانات الزاوية والمسافة مفصولة بفاصلة (,) ومتبوعة بحرف سطر جديد (\n) عبر المنفذ التسلسلي. هذا التنسيق مهم لبرنامج المعالجة (Processing) ليتمكن من قراءة البيانات بشكل صحيح.
  8. حلقة for الثانية: تقوم بنفس العملية ولكن تحرك المحرك من 180 إلى 0 درجة (مسح عكسي).

برمجة واجهة العرض الرسومية (كود برنامج المعالجة - Processing):

الآن نحتاج إلى برنامج على الحاسوب لاستقبال البيانات من الأردوينو وعرضها بشكل رسومي. بيئة Processing مثالية لهذا الغرض. قم بتنزيل وتثبيت Processing IDE من موقعه الرسمي. ثم افتح نافذة جديدة وانسخ الكود التالي:
import processing.serial.*; // استيراد مكتبة الاتصال التسلسلي

Serial myPort;  // كائن لتمثيل منفذ الاتصال التسلسلي
String dataFromArduino = ""; // متغير لتخزين البيانات الواردة من الأردوينو
float angle = 0;    // متغير لتخزين الزاوية
float distance = 0; // متغير لتخزين المسافة

// إعدادات شاشة الرادار
int radarWidth = 600;
int radarHeight = 400;
int radarCenterX;
int radarCenterY;
int maxDistance = 50; // أقصى مسافة يمكن عرضها على الرادار (بالسنتيمتر)
                      // يمكن تعديلها حسب مدى المستشعر وقراءاته الفعلية
float sweepAngle = 0; // زاوية خط المسح الحالي

void setup() {
  size(radarWidth, radarHeight); // تحديد أبعاد نافذة العرض
  radarCenterX = width / 2;
  radarCenterY = height - 50; // مركز الرادار في الأسفل قليلاً

  // طباعة قائمة المنافذ التسلسلية المتاحة في وحدة التحكم
  // هذا يساعد في تحديد المنفذ الصحيح للأردوينو
  printArray(Serial.list());

  // استبدل "COM_PORT_NUMBER" بالرقم الصحيح لمنفذ الأردوينو
  // على سبيل المثال في ويندوز قد يكون "COM3" أو "COM4"
  // في نظام ماك أو لينكس قد يكون مثل "/dev/tty.usbmodemXXXX"
  // يجب أن يكون هذا هو المنفذ الأول في القائمة إذا كان الأردوينو هو الجهاز التسلسلي الوحيد المتصل
  // أو يمكن معرفته من Arduino IDE (Tools -> Port)
  String portName = Serial.list()[0]; // محاولة استخدام أول منفذ متاح (قد تحتاج لتعديل هذا)
  try {
      myPort = new Serial(this, portName, 9600); // فتح الاتصال التسلسلي
      myPort.bufferUntil('\n'); // قراءة البيانات حتى يتم استقبال حرف السطر الجديد
  } catch (Exception e) {
      println("خطأ في فتح المنفذ التسلسلي: " + portName);
      e.printStackTrace();
  }
  
  background(0); // خلفية سوداء
  smooth();      // لتنعيم الرسومات
}

void draw() {
  background(0); // مسح الشاشة في كل إطار لرسم جديد
  
  // رسم واجهة الرادار
  drawRadarInterface();
  
  // رسم خط المسح المتحرك
  drawSweepLine(sweepAngle);
  
  // تحديث زاوية خط المسح بناءً على البيانات الواردة (أو بشكل تقديري)
  // إذا كانت البيانات ترد بسرعة كافية، يمكن استخدام الزاوية الواردة مباشرة
  // هنا نقوم بتحديثها بناءً على قيمة الزاوية المستلمة
  sweepAngle = radians(angle); 
  
  // إذا كان هناك جسم مكتشف، ارسمه
  if (distance > 0 && distance < maxDistance) { // فقط إذا كانت المسافة ضمن المدى المعقول
    drawObject(radians(angle), distance);
  }
  
  // عرض قيم الزاوية والمسافة نصياً
  fill(0, 255, 0); // لون أخضر للنص
  textSize(16);
  text("الزاوية: " + nfc(angle, 0) + "°", 20, 30);
  text("المسافة: " + nfc(distance, 1) + " سم", 20, 50);
}

void serialEvent(Serial p) {
  try {
    dataFromArduino = p.readStringUntil('\n'); // قراءة السلسلة حتى حرف السطر الجديد
    if (dataFromArduino != null) {
      dataFromArduino = trim(dataFromArduino); // إزالة أي مسافات بيضاء زائدة
      String[] values = split(dataFromArduino, ','); // فصل السلسلة عند الفاصلة
      if (values.length == 2) { // التأكد من أن لدينا قيمتين (زاوية ومسافة)
        angle = float(values[0]);    // تحويل القيمة الأولى إلى زاوية (رقم عشري)
        distance = float(values[1]); // تحويل القيمة الثانية إلى مسافة (رقم عشري)
      }
    }
  } catch (Exception e) {
    // تجاهل الأخطاء المحتملة في قراءة البيانات (مثل بيانات غير مكتملة)
    // println("خطأ في قراءة البيانات: " + e.toString());
  }
}

void drawRadarInterface() {
  stroke(0, 255, 0); // لون أخضر للخطوط
  strokeWeight(2);
  noFill();
  
  // رسم أقواس الرادار متحدة المركز
  ellipse(radarCenterX, radarCenterY, maxDistance * 8, maxDistance * 8); // القوس الأكبر
  ellipse(radarCenterX, radarCenterY, maxDistance * 6, maxDistance * 6);
  ellipse(radarCenterX, radarCenterY, maxDistance * 4, maxDistance * 4);
  ellipse(radarCenterX, radarCenterY, maxDistance * 2, maxDistance * 2);
  
  // رسم خطوط الزوايا
  line(radarCenterX, radarCenterY, radarCenterX + cos(radians(30)) * maxDistance * 4, radarCenterY - sin(radians(30)) * maxDistance * 4);
  line(radarCenterX, radarCenterY, radarCenterX + cos(radians(60)) * maxDistance * 4, radarCenterY - sin(radians(60)) * maxDistance * 4);
  line(radarCenterX, radarCenterY, radarCenterX + cos(radians(90)) * maxDistance * 4, radarCenterY - sin(radians(90)) * maxDistance * 4); // 90 درجة
  line(radarCenterX, radarCenterY, radarCenterX + cos(radians(120)) * maxDistance * 4, radarCenterY - sin(radians(120)) * maxDistance * 4);
  line(radarCenterX, radarCenterY, radarCenterX + cos(radians(150)) * maxDistance * 4, radarCenterY - sin(radians(150)) * maxDistance * 4);
  line(radarCenterX, radarCenterY, radarCenterX, radarCenterY - maxDistance * 4); // خط مستقيم للأعلى (0 أو 180 درجة حسب التوجيه)
  line(radarCenterX - maxDistance * 4, radarCenterY, radarCenterX + maxDistance*4, radarCenterY); // خط أفقي
}

void drawSweepLine(float currentAngle) {
  stroke(0, 200, 0, 150); // لون أخضر شبه شفاف لخط المسح
  strokeWeight(3);
  // حساب نهاية خط المسح باستخدام الإحداثيات القطبية
  // نستخدم (PI - currentAngle) لأن الزوايا في Processing تقاس عكس عقارب الساعة من المحور X الموجب
  // بينما محرك السيرفو يتحرك في اتجاه معين (0-180)
  // قد تحتاج لتعديل هذا حسب كيفية تركيب السيرفو واتجاه الدوران
  float x2 = radarCenterX + cos(PI - currentAngle) * maxDistance * 4; 
  float y2 = radarCenterY - sin(PI - currentAngle) * maxDistance * 4;
  line(radarCenterX, radarCenterY, x2, y2);
}

void drawObject(float objAngle, float objDistance) {
  // تحويل الإحداثيات القطبية (زاوية، مسافة) إلى إحداثيات ديكارتية (x, y)
  // نستخدم (PI - objAngle) لنفس سبب خط المسح
  float objX = radarCenterX + cos(PI - objAngle) * objDistance * 4; // *4 لتكبير الرسم
  float objY = radarCenterY - sin(PI - objAngle) * objDistance * 4;
  
  fill(255, 0, 0); // لون أحمر للجسم المكتشف
  noStroke();
  ellipse(objX, objY, 10, 10); // رسم دائرة صغيرة تمثل الجسم
}

شرح كود برنامج المعالجة (Processing):

  • import processing.serial.*;: استيراد مكتبة الاتصال التسلسلي.
  • Serial myPort;: كائن لتمثيل منفذ الاتصال.
  • void setup():
  1. size(radarWidth, radarHeight);: تحديد حجم نافذة العرض.
  2. printArray(Serial.list());: يطبع قائمة بالمنافذ التسلسلية المتاحة. هذا مهم لمعرفة اسم المنفذ الذي يتصل به الأردوينو (مثلاً "COM3" في ويندوز أو "/dev/ttyUSB0" في لينكس). ستحتاج إلى تعديل String portName = Serial.list()[0]; ليطابق المنفذ الصحيح لجهازك.
  3. myPort = new Serial(this, portName, 9600);: فتح الاتصال التسلسلي مع الأردوينو بنفس سرعة الباود المستخدمة في كود الأردوينو (9600).
  4. myPort.bufferUntil('\n');: يخبر البرنامج بقراءة البيانات من المنفذ التسلسلي حتى يتم العثور على حرف السطر الجديد \n الذي أرسلناه من الأردوينو.
  • void draw(): هذه الدالة تعمل بشكل مستمر (مثل loop() في الأردوينو) لإنشاء الرسوم المتحركة.
  1. background(0);: مسح الشاشة باللون الأسود في كل مرة لإعادة الرسم.
  2. drawRadarInterface(): استدعاء دالة لرسم واجهة الرادار الثابتة (الأقواس والخطوط).
  3. drawSweepLine(radians(angle));: استدعاء دالة لرسم خط المسح المتحرك بناءً على الزاوية الحالية.
  4. if (distance > 0 && distance < maxDistance): إذا تم اكتشاف جسم ضمن المدى المحدد (maxDistance).
  5. drawObject(radians(angle), distance);: استدعاء دالة لرسم نقطة تمثل الجسم المكتشف.
  6. text(...): عرض قيم الزاوية والمسافة كنص على الشاشة.
  • void serialEvent(Serial p): هذه الدالة يتم استدعاؤها تلقائياً كلما وصلت بيانات جديدة عبر المنفذ التسلسلي.
  1. dataFromArduino = p.readStringUntil('\n');: قراءة البيانات كسلسلة نصية.
  2. String[] values = split(dataFromArduino, ',');: فصل السلسلة عند الفاصلة للحصول على قيمتي الزاوية والمسافة.
  3. angle = float(values[0]); و distance = float(values[1]);: تحويل القيم النصية إلى أرقام عشرية (float).
  • void drawRadarInterface(): دالة مسؤولة عن رسم الأقواس والخطوط الشعاعية التي تشكل مظهر شاشة الرادار.
  • void drawSweepLine(float currentAngle): ترسم خطاً من مركز الرادار إلى الحافة الخارجية بزاوية المسح الحالية.
  • void drawObject(float objAngle, float objDistance): تحول إحداثيات الجسم المكتشف (الزاوية والمسافة) إلى إحداثيات (x, y) على الشاشة وترسم دائرة صغيرة في ذلك الموقع.

خطوات تشغيل المشروع واختباره:

  1. تأكد من توصيل جميع المكونات بشكل صحيح كما هو موضح في قسم التوصيلات.
  2. قم بتوصيل لوحة الأردوينو بالحاسوب باستخدام كابل USB.
  3. افتح كود الأردوينو في Arduino IDE.
  4. من قائمة "Tools" -> "Board"، اختر "Arduino Uno".
  5. من قائمة "Tools" -> "Port"، اختر المنفذ التسلسلي الصحيح الذي تتصل به لوحة الأردوينو.
  6. اضغط على زر "Upload" (السهم المتجه يميناً) لرفع الكود إلى لوحة الأردوينو.
  7. بعد اكتمال الرفع بنجاح، افتح كود برنامج المعالجة (Processing) في Processing IDE.
  8. هام جداً: في كود Processing، ابحث عن السطر String portName = Serial.list()[0]; وقم بتعديله إذا لزم الأمر ليطابق اسم المنفذ التسلسلي الصحيح للأردوينو (الذي رأيته في Arduino IDE أو من خلال مخرجات printArray(Serial.list()); في وحدة تحكم Processing عند تشغيل الكود لأول مرة بدون تعديل).
  9. اضغط على زر "Run" (المثلث) في Processing IDE.
  10. من المفترض أن ترى نافذة رسومية تظهر شاشة الرادار. يجب أن يبدأ المحرك المؤازر بالدوران وأن ترى خط المسح يتحرك على الشاشة.
  11. حاول وضع يدك أو أي جسم أمام مستشعر الموجات فوق الصوتية. يجب أن ترى نقطة حمراء تظهر على شاشة الرادار تمثل الجسم المكتشف وتتغير موقعها مع تغير المسافة والزاوية.

استكشاف الأخطاء وإصلاحها (Troubleshooting):

1- المحرك المؤازر لا يتحرك أو يتحرك بشكل غريب:

  • تأكد من توصيل أسلاك المحرك بشكل صحيح (الإشارة، الطاقة، الأرضي).
  • تأكد من أن منفذ الإشارة متصل بمنفذ PWM على الأردوينو (مثل Pin 11).
  • قد تحتاج لمصدر طاقة خارجي للمحرك إذا كان يسحب تياراً كبيراً لا يستطيع منفذ USB توفيره.

2- لا توجد بيانات تصل إلى برنامج Processing أو الشاشة فارغة:

  • تأكد من اختيار المنفذ التسلسلي الصحيح في كل من Arduino IDE (عند الرفع) وفي كود Processing.
  • تأكد من أن سرعة الباود (Baud rate) متطابقة في كود الأردوينو (9600) وفي كود Processing (9600).
  • افتح "Serial Monitor" في Arduino IDE (بعد رفع الكود) وتحقق مما إذا كانت البيانات (الزاوية والمسافة) تُطبع بشكل صحيح.
3- قراءات المسافة غير دقيقة أو ثابتة:
  • تأكد من توصيلات مستشعر الموجات فوق الصوتية (Trig و Echo).
  • تأكد من عدم وجود عوائق مباشرة أمام المستشعر.
  • بعض الأسطح (مثل الأقمشة الناعمة أو الأسطح المائلة بزاوية حادة) قد لا تعكس الموجات فوق الصوتية بشكل جيد.
  • المدى الفعال لمستشعر HC-SR04 هو عادة بين 2 سم و 400 سم.

تطويرات مستقبلية للمشروع:

هذا المشروع هو نقطة انطلاق رائعة، هناك العديد من الطرق لتطويره وتحسينه:
  1. استخدام مستشعر أكثر دقة أو بمدى أطول: مثل مستشعرات الليزر (LiDAR) المصغرة.
  2. إضافة شاشة LCD: لعرض البيانات مباشرة على الجهاز بدون الحاجة لحاسوب.
  3. تخزين البيانات: تسجيل البيانات المكتشفة في بطاقة SD لمزيد من التحليل.
  4. إضافة تنبيهات صوتية أو ضوئية: عند اكتشاف جسم ضمن نطاق معين.
  5. واجهة ويب: عرض بيانات الرادار على صفحة ويب يمكن الوصول إليها من أي جهاز على الشبكة.
  6. التعرف على الأجسام: باستخدام تقنيات معالجة الصور أو الذكاء الاصطناعي لمحاولة التعرف على نوع الجسم المكتشف (يتطلب قوة معالجة أكبر).
  7. رادار ثلاثي الأبعاد: بإضافة محرك مؤازر آخر للحركة الرأسية.

لقد نجحنا في بناء نظام رادار بسيط ولكنه فعال باستخدام الأردوينو ومكونات إلكترونية متاحة بسهولة، هذا المشروع لا يقتصر على كونه تجربة ممتعة بل هو مدخل ممتاز لفهم مبادئ الاستشعار والتحكم الآلي والتفاعل بين العتاد والبرمجيات. نأمل أن يكون هذا الدليل قد ألهمك لاستكشاف المزيد في عالم الإلكترونيات والمشاريع التفاعلية، لا تتردد في التجربة والتعديل على الكود والتصميم فالسماء هي الحدود لإبداعك، نتمنى لك كل التوفيق في مشاريعك المستقبلية.

تعليقات