عناوين الدرس

مشروع الرادار الالكتروني

متوسط

سنقوم في هذا المشروع بعمل نظام بسيط لرصد إحداثيات موقع الأجسام عن طريق صناعة رادار رقمي بإستخدام جهاز مستشعر الموجات فوق الصوتية HC-SR04، ولوحة الأردوينو كمتحكم للنظام . ويتم استخدام جهاز الحاسوب لعرض الواجهة الرسومية.

arduino-radar-project

القطع المطلوبة:

الأدوات التي تحتاجها لهذا المشروع :

 مستشعر الموجات فوق الصوتية (Ultrasonic sensor HC- SR04).

tower pro sg90

محرك سيرفو ( Servo Motor).

arduino uno r3

Arduino Uno R3

Half-size Breadboard

 لوح تجارب حجم متوسط (Half size breadboard)

Jumper Wires Male/Male

 اسلاك توصيل ذكر/ذكر (Jumper Wires Male Male)

Female-Male Jumper Wires

 اسلاك توصيل أنثى/ذكر (Jumper Wires Female/male)

تصميم لوح التجارب

يقوم الاردوينو بالتحكم بزاوية دوران محرك السيرفو(Servo motor) ، لذلك يتم تثبيت حساس الموجات فوق الصوتية على المحرك ليتم قياس المسافة عند تلك الزاوية.

قم بتوصيل الدائرة الكهربائية على لوحة التجارب كما هو موضح بالصورة.

arduino-radar-project

يتحتوي مستشعر الموجات فوق الصوتية على اربع منافذ، منفذ الطاقة  Vcc و منفذ GND و منفذ Trig الذي يتم من خلاله ارسال النبضة, و منفذ Echo الذي يتم من خلاله استقبال صدى النبضة المرسلة من قبل Trig.
يتم توصيل مستشعر الموجات فوق الصوتية بالاردوينو كالتالي:

حساس الموجات فوق الصوتية لوحة الاردوينو
Vcc 5v
GND GND
Trig Pin 10
Echo Pin 11

و توصيل محرك السيرفو كالتالي:

لوحة الاردوينو محرك السيرفو
5v السلك الأحمر
GND  السلك الأسود/البني
 Pin 9  السلك الاصفر/البرتقالي

عندما يقوم الاردوينو بتحريك محرك السيرفو بدرجات معينة (و بالتالي يتحرك حساس الموجات الفوق صوتية)  يتم حساب المسافة عند تلك الزاوية. سيتم ارسال هذة البيانات إلى جهاز الحاسوب عبر المنفذ التسلسلي (Serial port)، و بالتالي يقوم الحاسوب باستخدام برنامج لرسم الخريطة البيانية اعتمادا على هذة القيم .

واجهة المستخدم:

Processing IDE، هي بيئة تطوير متكاملة تم بناؤها من أجل الأشخاص المهتمين بالتصميم المرئي والفنون الإلكترونية الأخرى. حيث تمكنك من برمجة الرسوم و الصور المتحركة و تقوم بتحديث الرسومات المعروضه على شاشة الكمبيوتر و الاستجابة لتفاعل المستخدم.

arduino-radar-project

الان نحن بحتاج لعمل برنامج يتم رفعه على الاردوينو الذي من شأنه تمكين التفاعل بين    Arduino IDE  و  IDE Processing.

*يمكنك تنزيل برنامج Processing من هنـا.

الكود البرمجي للأردوينو

قم برفع البرنامج التالي على الاردوينو:

#include <Servo.h>

Servo leftRightServo; // set a variable to map the servo
int leftRightPos = 0; // set a variable to store the servo position
const int numReadings = 10; // set a variable for the number of readings to take
int index = 0; // the index of the current reading
int total = 0; // the total of all readings
int average = 0; // the average
int echoPin = 11; // the SRF05's echo pin
int initPin = 10; // the SRF05's init pin
unsigned long pulseTime = 0; // variable for reading the pulse
unsigned long distance = 0; // variable for storing distance

/* setup the pins, servo and serial port */
void setup() {
  leftRightServo.attach(9); 
// make the init pin an output:
  pinMode(initPin, OUTPUT); 
// make the echo pin an input:
  pinMode(echoPin, INPUT); 
// initialize the serial port:
  Serial.begin(9600);
}

void loop() {
  for(leftRightPos = 0; leftRightPos < 180; leftRightPos++) { // going left to right.
    leftRightServo.write(leftRightPos);
    average=Avg();
    Serial.print("X"); // print leading X to mark the following value as degrees
    Serial.print(leftRightPos); // current servo position
    Serial.print("V"); // preceeding character to separate values
    Serial.println(average); // average of sensor readings
  }
/*
start going right to left after we got to 180 degrees
*/
  for(leftRightPos = 180; leftRightPos > 0; leftRightPos--) { // going right to left
    leftRightServo.write(leftRightPos);
    average=Avg();
    Serial.print("X");
    Serial.print(leftRightPos);
    Serial.print("V");
    Serial.println(average);
  }
}

long Avg()
{
  for (index = 0; index<=numReadings;index++) {
  digitalWrite(initPin, LOW);
  delayMicroseconds(50);
  digitalWrite(initPin, HIGH);
  delayMicroseconds(50);
  digitalWrite(initPin, LOW);
  pulseTime = pulseIn(echoPin, HIGH);
  distance = pulseTime/58;
  total = total + distance;
  delay(10);
}
average = total/numReadings; // create average reading

if (index >= numReadings) { // reset the counts when at the last item of the array
index = 0;
total = 0;
}
return average;
}

لمحة عن الكود :

يقوم محرك السيرفو بالدوران من 0 إلى 180 درجة  و العكس ، ومن خلاله يقوم مستشعر الموجات فوق الصوتية بالمسح الأرضي و الجوي لما يجري داخل منطقة محدودة وهي ابعد ما يستطيع المستشعر التعامل معه.

دالة for  تقوم بتغير قيمة زاوية الدوران للمحرك :

for(leftRightPos = 0; leftRightPos < 180; leftRightPos++) {
}
for(leftRightPos = 180; leftRightPos > 0; leftRightPos--){
}

تقوم الدالة ()AVG اعتمادا على القيم التي يتلقاها حساس الموجات فوق الصوتية بحساب المسافة التي يبعد عنها الجسم عن الحساس :

long Avg()
{
  for (index = 0; index<=numReadings;index++) {
  digitalWrite(initPin, LOW);
  delayMicroseconds(50);
  digitalWrite(initPin, HIGH);
  delayMicroseconds(50);
  digitalWrite(initPin, LOW);
  pulseTime = pulseIn(echoPin, HIGH);
  distance = pulseTime/58;
  total = total + distance;
  delay(10);
}
average = total/numReadings; // create average reading

if (index >= numReadings) { // reset the counts when at the last item of the array
index = 0;
total = 0;
}
return average;
}

* يمكنك الاطلاع على مشروع نظام الحسّاسات لاصطفاف السيارة لفهم الكود المتعلق بحساس الموجات فوق الصوتية و حساب المسافة , و الدرس الخامس عشر للاطلاع على شرح الكود المتعلق بمحرك السيرفو.

يتم ارسال قيمة المسافة و الزاوية عند هذة القيمة إلى الحاسوب فيقوم البرنامج  (Processing IDE)  برسم خطوط الرادار باستعمال الدوال المثلثة طبقا للمعلومات المستقبله.

Serial.print("X"); 
Serial.print(leftRightPos);
Serial.print("V"); 
Serial.println(average);

برمجة الواجهة الرسومية

 الحاسوب بعد ارسال قيم الزاوية و المسافة من الاردوينو الى (processing IDE) ، يتم استقبالها بإستخدام دالة ()SerialEvent  .
تقوم ()SerialEvent بقراءة البيانات من المنفذ التسلسلي (serial port) ثم نقوم بوضع قيم الزاوية و المسافة في متغيرات (degree, value). هذة المتغيرات سيتم استخدامها لرسم الرادار، و الخطوط، و الكشف عن الأجسام ، وتغير النصوص .

لعرض البيانات على الشاشة يتم انشاء Arrays  لتخزين القيم الحديثة على newValue Array و عمل تحديث للقيم القديمة على oldValue Array . لأن الموقع اتباعا لحركة  محرك السيرفو يتغير بإستمرار ، فسنفقد البيانات القديمة التي سيتم عرضها على الشاشة.

int[] newValue = new int[181];
int[] oldValue = new int[181];
رادار

لرسم الرادار سيتم كتابة الداله ()drawRadar التي تتكون من دوال ()arc و ()line.

void drawRadar() {

 for (int i = 0; i <=6; i++){
  noFill();
  strokeWeight(1);
  stroke(0, 255-(30*i), 0);
  arc(radius, radius, (100*i), (100*i),PI,TWO_PI); 
  fill(250, 103, 0);
  noStroke();
  text(Integer.toString(radarDist+50), 380, (305-radarDist), 50, 50);
  radarDist+=50;
 }

 radarDist = 0; 
 for (int i = 0; i <= 6; i++) {
   strokeWeight(1);
   stroke(0, 55, 0);
   line(radius, radius, radius + cos(radians(180+(30*i)))*w, radius + sin(radians(180+(30*i)))*w);
   fill(153, 153, 153);
   noStroke();
   if (180+(30*i) >= 300) {
    text(Integer.toString(180+(30*i)), (radius+10) + cos(radians(180+(30*i)))*(w+10), (radius+10) + sin(radians(180+(30*i)))*(w+10), 25,50);
   } 
  else {
   text(Integer.toString(180+(30*i)), radius + cos(radians(180+(30*i)))*w, radius + sin(radians(180+(30*i)))*w, 60,40);
  }
 }
}
رادار

ليتم عمل مسح للرادار يتم رسم الخط الذي يتحرك جنب إلى جنب اتباعا لحركة محرك السيرفو بإستخدام الدالة  ()setupSweep  .

تستخدم الدالة  ()setupSweep الدالة ()line التي تستخدم المتغير degree لإعادة رسم الخط لكل درجة.

void setupSweep(){
 strokeWeight(7); 
 if (motion == 0) { 
 for (int i = 0; i <= 20; i++) { 
 stroke(0, (10*i), 0); 
 line(radius, radius, radius + cos(radians(degree+(180+i)))*w, radius + sin(radians(degree+(180+i)))*w); 
 }
 } else { // if going right to left
 for (int i = 20; i >= 0; i--) { 
 stroke(0,200-(10*i), 0);
 line(radius, radius, radius + cos(radians(degree+(180+i)))*w, radius + sin(radians(degree+(180+i)))*w);
 }
 } 
}

لإعداد تحديث الأشكال يتم عمل الدالة ()SetupShapes . سنقوم بإستخدام الدالة  For loop للتحرك بين القيم التي تم تخزينها بالـ (Arrays  (newValue, oldValue

void SetupShapes(){
  noStroke();                           
  
  fill(0,50,0);                         
  beginShape();                         
  for (int i = 0; i < 180; i++) {     
  x = radius + cos(radians((180+i)))*((oldValue[i])); 
  y = radius + sin(radians((180+i)))*((oldValue[i])); 
  vertex(x, y);                     
  }
  endShape();                           
  
  fill(0,110,0);
  beginShape();
  for (int i = 0; i < 180; i++) {
  x = radius + cos(radians((180+i)))*(newValue[i]);
  y = radius + sin(radians((180+i)))*(newValue[i]);
  vertex(x, y);
  }
  endShape();
  
  fill(0,170,0);
  beginShape();
  for (int i = 0; i < 180; i++) {
  x = radius + cos(radians((180+i)))*((newValue[i]+oldValue[i])/2); 
  y = radius + sin(radians((180+i)))*((newValue[i]+oldValue[i])/2);
  vertex(x, y);
  }
  endShape();
}

لرسم موقع الاجسام التي تم رصدها  ، نقوم بعمل الدالة ()drawObject .التي تستخدم المسافة الملتقطة من مستشعر الموجات فوق الصوتية و بالاشتراك مع الزاوية لرسم الجسم على الرادار.

void drawObject() {
  if (firstRun >= 360) {
  stroke(250,103,0);
  strokeWeight(1);
  noFill();
  for (int i = 0; i < 180; i++) { if (oldValue[i] - newValue[i] > 35 || newValue[i] - oldValue[i] > 35) {
  x = radius + cos(radians((180+i)))*(newValue[i]);
  y = radius + sin(radians((180+i)))*(newValue[i]);
  ellipse(x, y, 10, 10); 
  }
  }
  } 
}

وللإطلاع على القيم التي تم استقبالها و النصوص تم إنشاء الدالة ()drawText  .

رادار

يمكنك تنزيل كود  الـ (Processing) المتعلق بالواجهة الرسومية للرادار من هنـا.

X
تم إضافة المنتج إلى السلة بنجاح