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

الموضوع في 'برمجة الاشياء arduino' بواسطة ابوفارس, بتاريخ ‏1 ابريل 2019.

  1. ابوفارس

    ابوفارس ادارة المنتدى إداري

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

    [​IMG]



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

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

    [​IMG]
    محرك سيرفو ( Servo Motor).

    [​IMG]
    Arduino Uno R3

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

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

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


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

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

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

    حساس الموجات فوق الصوتيةلوحة الاردوينو
    Vcc5v
    GNDGND
    TrigPin 10
    EchoPin 11
    و توصيل محرك السيرفو كالتالي:

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


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

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

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

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


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

    كود:
    
    #include <Servo.h>
    
    Servo leftRightServo;// set a variable to map the servo
    intleftRightPos=0;// set a variable to store the servo position
    constintnumReadings=10;// set a variable for the number of readings to take
    intindex=0;// the index of the current reading
    inttotal=0;// the total of all readings
    intaverage=0;// the average
    intechoPin=11;// the SRF05's echo pin
    intinitPin=10;// the SRF05's init pin
    unsignedlongpulseTime=0;// variable for reading the pulse
    unsignedlongdistance=0;// variable for storing distance
    
    /* setup the pins, servo and serial port */
    voidsetup(){
    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);
    }
    
    voidloop(){
    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);
    }
    }
    
    longAvg()
    {
    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;
    }
    returnaverage;
    }
    

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

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

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

    كود:
    for(leftRightPos=0;leftRightPos<180;leftRightPos++){
    }
    
    
    
    for(leftRightPos=180;leftRightPos>0;leftRightPos--){
    }
    
    
    تقوم الدالة ()AVG اعتمادا على القيم التي يتلقاها حساس الموجات فوق الصوتية بحساب المسافة التي يبعد عنها الجسم عن الحساس :
    
    
    
    
    longAvg()
    {
    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;
    }
    returnaverage;
    }


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

    يتم ارسال قيمة المسافة و الزاوية عند هذة القيمة إلى الحاسوب فيقوم البرنامج (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=newint[181];
    int[]oldValue=newint[181];


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



    كود:
    voiddrawRadar(){
    
    for(inti=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(inti=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);
    }
    }
    }

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

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


    كود:
    voidsetupSweep(){
    strokeWeight(7);
    if(motion==0){
    for(inti=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(inti=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



    كود:
    voidSetupShapes(){
    noStroke();
    fill(0,50,0);
    beginShape();
    for(inti=0;i<180;i++){
    x=radius+cos(radians((180+i)))*((oldValue));
    y=radius+sin(radians((180+i)))*((oldValue));
    vertex(x,y);
    }
    endShape();
    fill(0,110,0);
    beginShape();
    for(inti=0;i<180;i++){
    x=radius+cos(radians((180+i)))*(newValue);
    y=radius+sin(radians((180+i)))*(newValue);
    vertex(x,y);
    }
    endShape();
    fill(0,170,0);
    beginShape();
    for(inti=0;i<180;i++){
    x=radius+cos(radians((180+i)))*((newValue+oldValue)/2);
    y=radius+sin(radians((180+i)))*((newValue+oldValue)/2);
    vertex(x,y);
    }
    endShape();
    }


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

    كود:
    
    
    voiddrawObject(){
    if(firstRun>=360){
    stroke(250,103,0);
    strokeWeight(1);
    noFill();
    for(inti=0;i<180;i++){if(oldValue-newValue>35||newValue-oldValue>35){
    x=radius+cos(radians((180+i)))*(newValue);
    y=radius+sin(radians((180+i)))*(newValue);
    ellipse(x,y,10,10);
    }
    }
    }
    }
    

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

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




    http://geeksvalley.com/tutorial/arduino-radar-project/



    كود:
    #include <Servo.h>
    
    const int trigPin = 10;
    const int echoPin = 11;
    int maximumRange = 50; // Maximum range needed
    int minimumRange = 0; // Minimum range needed
    long duration;
    int distance;
    Servo myServo;
    Servo myServol;
    int numTones = 10;
    int ss=4000;
    int BUTTON = 4;
    int ylo = 3;
    int gren = 13;
    int red = 12;
    int sond = 2;
    int BUTTON2 ;
    int d = 0;
    int tones[] = {261, 277, 294, 311, 330, 349, 370, 392, 415, 440};
    void setup()
    {
    
    
    Serial.begin(9600);
    pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
      pinMode(sond, OUTPUT); // Sets the trigPin as an Output
      pinMode(ylo, OUTPUT); // Sets the trigPin as an Output
      pinMode(gren, OUTPUT); // Sets the trigPin as an Output
      pinMode(echoPin, INPUT); // Sets the echoPin as an Input
    
    pinMode(sond, OUTPUT);
      myServo.attach(9); // Defines on which pin is the servo motor attached
      myServol.attach(12); // Defines on which pin is the servo motor attached
    
    
    
    }
    void loop() {
    
      // 15 derece ile 165 derece arasında dön
      for(int i=15;i<=165;i++){ 
      myServo.write(i);
      delay(30);
    distance = calculateDistance();
      if (distance >= maximumRange || distance <= minimumRange) {
          /// Serial.println("Nothing Happens");
            digitalWrite(gren, LOW);
        } else {
          myServol.write(i);
            //Serial.println("Trigger");
          digitalWrite(gren, HIGH);
          
       tone(sond,ss- (50*distance),50);
        delay(100);
     
    noTone(sond);
    }
      Serial.print(i);
      Serial.print(",");
      Serial.print(distance);
      Serial.print(".");
     
      }
      for(int i=165;i>15;i--){ 
    myServo.write(i);
      delay(30);
      distance = calculateDistance();
    ////Serial.println(distance);
    
      if (distance >= maximumRange || distance <= minimumRange) {
          /// Serial.println("Nothing Happens");
            digitalWrite(gren, LOW);
        } else {
           myServol.write(i);
           Serial.println("Trigger");
           digitalWrite(gren, HIGH);
          
       tone(sond,ss- (50*distance),50);
        delay(100);
     
    noTone(sond);
           /// digitalWrite(sond, HIGH);
        }
      Serial.print(i);
    Serial.print(",");
      Serial.print(distance);
      Serial.print(".");
    }
    }
    
    int calculateDistance(){
        digitalWrite(trigPin, LOW);
      delayMicroseconds(2);
      // Sets the trigPin on HIGH state for 10 micro seconds
      digitalWrite(trigPin, HIGH);
      delayMicroseconds(10);
      digitalWrite(trigPin, LOW);
      duration = pulseIn(echoPin, HIGH); // Reads the echoPin, returns the sound wave travel time in microseconds
      distance= duration*0.034/2;
      return distance;
    }
     
    آخر تعديل: ‏4 فبراير 2020

مشاركة هذه الصفحة