نظام البوابة الذكي (Smart Door System)

6 التعليقات
بسم الله الرحمن الرحيم




في هذه التجربة سنقوم بتصميم نظام ذكـي للبوابات يتميز بالمواصفات التالية :

  • يستخدم تقنية الـ RFID للتعرف على الاشخاص المسموح لهم بالدخول . 
  • يحسب عدد ساعات العمل لكل شخص عند الخروج .
  • يمكن فتح البوابة من خلال البلوتوث للأجهزة الموثوقة .
  • يمكن تغير وضع الجهاز ليفتح البوابة تلقائياً عن اقتراب شخص منه .
  • يمكن وصله مع أنظمة الحماية, ليفتح البوابة مباشرة في حالات الطـوارئ .





• نحتاج الى :

  • متحكم اردوينو (يفضل نوع ميجا ).
  • قارئ بطاقات RFID13.56MHz , يمكن شراؤه من هـنـا.
  • حساس حركة (PIR) , يمكن شراؤه من هـنـا .
  • موديول بلوتوث , يمكن شراؤه من هـنـا.
  • H-Bridge , يمكن شراؤه من هـنـا .
  • Door Lock Actuator , يمكن شراؤه من هنا .
  • مفتاح كهربائي (switch & push button  ).
  • شاشة LCD16x2  يمكن شراؤها من هـنـا .
  • مقاومات .
  • ليدات (LEDs).
  • طنان كهربائي (buzzer).
  • لوحة تجارب و اسلاك توصيل .


- يمكنك قراءة هذا المقال عن كيفية شراء القطع الالكترونية بسهولة عبر الانترنت من هـنـا .





• وضـع RFID : 



تقنية (RFID) وتعني ( تحديد الهوية باستخدام موجاتالراديو Radio Frequency Identifcation ). وتعتبر أشهر تقنيات التواصل قريب المدى NFC.

تتكون هذه التقنية ببساطة من ثلاثة أجزاء رئيسية هي:  
  1. البطاقة التي تحتوي على جهاز الإرسال والمعلومات.
  2. جهاز القراءة والإرسال. 
  3. برامج الحاسوب وقواعد البيانات.

تحتوى كل البطاقات (RFID tag) علي كود خاص مكون من خمسة خانات يتم بثها لاسلكيا بمجرد أن تقرب البطاقة من جهاز القراءة (RFID Reader) و تتعدد أشكال البطاقات و ألوانها على حسب الشركة المصنعة و الجهة التي تستخدمها

و جهاز القراءة هو من سيقرأ الكود الخاص بالبطاقة , ويرسله للآردوينو .
استخدمنا في هذه التجربة قارئ من نوع  RFID-RC522 RF IC Card Sensor  
يعتمد هذا الموديول على بروتوكول SPI  للتواصل مع الاردوينو .
لذلك نصل هذا الموديول مع المداخل الخاصة بالـSPI في الاردوينو كالتالي :

 MOSI : Pin 11 
 MISO : Pin 12 
 SCK  : Pin 13 
 SS  : Pin 10
RST : Pin 9

اضغط على الصورة لتكبيرها

- الموديول يعمل على 3.3V  و ليس 5V !
- مخرج IRQ يترك  بدون توصيل !

الموديول اصبح جاهزاً لبرمجتـه .

قم بتحميل المكتبة الخاصة بهذا الموديول من هـنـا .
ستقوم هذه المكتبة بقراءة البطاقة و تخزين الكود الخاص بها في مصفوفة مكونة من خمسة خانات اسمها rfid.serNum .

اذن يمكن قراءة رقم البطاقة و عرضها بسهولة (يمكن الاطلاع على الامثلة المرفقة بالمكتبة ) , لكن كيف سيتم التعرف على البطاقات الموثوقة , و كيف نحفظ وقت الدخول و الخروج ؟!

يجب ان يتم تخزين ارقام البطاقات الموثوقة مسبقاً في كود الاردوينو.
و عند قراءة اي بطاقة يقارنها الاردوينو مع ارقام البطاقات المخزنة , و في حال وجود تطابق تكون هذه البطاقة موثوقة و يُفتح لها الباب ! 
و يجب ايضأ تخزين وقت الدخول لهذه البطاقة , و عند الخروج نطرح وقت الخروج من وقت الدخول لمعرفة عدد ساعات العمل !
لاحظ انه يجب ايضاً تحديد حالة البطاقة (دخول أو خروج ) لتحديد الوظيفة التي سينفذها الاردوينو .

يبدو ان لدينا كمية كبيرة من البيانات يجب ان نتعامل معها , و اسهل طريقة لترتيبها هو وضعها في مصفوفة .( كما في الشكل ) .



نعمل مصفوفة مكونة من 7 صفوف , و اي عدد أعمدة تريد ( يجب ان يكون عدد الاعمدة اكبر من عدد البطاقات ) , كل عامود سيمثل ارقام البطاقة و بياناتها .
اول خمسة صفوف ستحتوي على رقم البطاقة .
الصف السادس سيحتوي على حالة البطاقة ( 1=في الداخل , 0 = في الخارج).
الصف السابع يحتوي على زمن الدخول .

هذا مثلاً كود عمل مصفوفة مكونة من 7 صفوف و 50 عامود اسمها Employee .

int Employee[7][50];


و لنخزن في العامود الاول رقم البطاقة الاولى في اول خمسة صفوف .
(العد في لغة C++ يبدأ من الصفر , أي ان العامود الاول رقمه 0 )

 Employee[0][0] =110;
 Employee[1][0] =241;
 Employee[2][0] =127;
 Employee[3][0] =161;
 Employee[4][0] =65;


و لنجعل الاردوينو يقارن رقم بطاقة معينة مع ارقام البطاقات المخزنة ( في rfid.serNum ذكرناها سابقا) .
سنستخدم جملة For للمرور على جميع الأعمدة ...
و جملة IF لمقارنة ارقام البطاقت معاً ..  
كالآتي :

 for ( Employee_Number=0 ; Employee_Number<50 ; Employee_Number++ ) {
        
      if(      Employee[0][Employee_Number] == rfid.serNum[0]&&
               Employee[1][Employee_Number] == rfid.serNum[1]&&
               Employee[2][Employee_Number] == rfid.serNum[2]&&
               Employee[3][Employee_Number] == rfid.serNum[3]&&
               Employee[4][Employee_Number] == rfid.serNum[4])
               {
                //do something  
                break ;}

 }   
 }

اذاً .. عند تقريب بطاقة مـا من الموديول , يقرأ الاردوينو ارقام هذة البطاقة و يخزنها في (rfid.serNum ) , ثم يدخل الى جملة For و يبدأ بمقارنة هذه الارقام مع الارقام المخزنة
في مصفوفة (Employee).
اذا لـم يجد تطابق (يعني البطاقة ليست موثوقة ) لا يقم بعمل شيء .

اما اذا وجد تطابق مع احد البطاقات المخزنة , يقوم اولاً بفتح الباب , ثم و حسب حالة البطاقة ينفذ وظيفة معينة . 
اذا كانت حالة البطاقة دخول : سيخزن زمن الدخول , و يعرض Welcome و رقم الموظف على الشاشة !
اما اذا كانت حالة البطاقة خروج : سيطرح زمن الدخول من الوقت الحالي و يعرض وقت العمل على الشاشة .

يمكن تنفيذ ذلك من خلال الكود التالي :

- قيمة X هي رقم البطاقة التي حصل عندها التطابق.


void a(int x){
  
digitalWrite(buzzer,1);//تنبيه بسيط
delay(100);
digitalWrite(buzzer,0);
delay(100);
digitalWrite(LED_1,0);

  if (Employee[5][x] == 0)  {
      Employee[5][x] = 1;
      Employee[6][x] = (millis()/60000 );
      lcd.clear() ;
      lcd.setCursor(0, 0);
      lcd.print("WELCOME : ");
      lcd.setCursor(10, 0);
      lcd.print(x);
      OPEN();
      delay(3000);
      CLOSE();
               }

      
  else if (Employee[5][x] == 1)   {
      Employee[5][x] = 0;
      start_time = Employee[6][x] ;
      now = millis()/60000;
      work_time = now - start_time  ;
      Employee[6][x] = 0;
      lcd.clear() ;
      lcd.setCursor(0, 0);
      lcd.print("GOODBYE : ");
      lcd.setCursor(0, 1);
      lcd.print(work_time);
      lcd.setCursor(10, 0);
      lcd.print(x);
      lcd.setCursor(8, 1);
      lcd.print("minute");
      OPEN();
      delay(3000);
      CLOSE();
           }

} 


يجب ان نتذكر ان هذا النظام يمكن تشغيله باكثر من وضع ( وضع الطوارئ  وضع حساس الحركة , البلوتوث ) ,و يتم التنقل بينهم من خلال المفاتيح , لذلك يجب ان نتأكد من حالة المفاتيح قبل ان يعمل كود الـ RFID .. 





• وضع PIR : 




في هذا الوضع ستفتح البوابة تلقائاً عند اقتراب شخص منها .
عن وجود حركة (اقتراب شخص ) سيعطي الحساس اشارة (HIGH) , ثم يقوم الاردوينو بقتح البوابة لمدة زمنية ثم اغلاقها . 

  • اولاً يتأكد من انه لا توجد اشارة طوارئ (button) .
  •  يتأكد ان المفتاح على وضع الـ PIR .
  • يعرض على الشاشة الوضع الحالي . 
  • الحساس موصول على المدخل  A3 .


while( digitalRead(button)== LOW && digitalRead(main_button)==  HIGH ){ 
  lcd.clear() ;
  lcd.print("Smart Door System");
  lcd.setCursor(0, 1);
  lcd.print("      PIR");

  if (digitalRead(A3)){  
    OPEN();
    delay(10000);
    CLOSE();
  }

delay(1000);
}






• وضع البلوتوث :





وضع البلوتوث يعمل مع وضع الـ RFID , و الهدف منه هو تجاوز حماية الـRFID و فتح البوابة دون الحاجة لبطاقة .



توصيل موديول البلوتوث كالتالي :







و يمكن اختيار اي تطبيق لاستخامه . في تطبيق Blue Control مثلاً سوف نستخدم الزر في الوسط لفتح البوابة . ( سيرسل التطبيق حرف C عند الضغط عليه ) 


ليكون الكود كالتالي : 

- لاحظ ان موديول البلوتوث موصول على المداخل 0 و1 الخاصة بالتواصل التسلسلي في الآردوينو , لذلك يجب فصلها عند تحميل الكود على الاردوينو .

if (Serial.available()) {
   int data = Serial.read();
   if ( data == 'C' ){
     OPEN();
     delay(3000);
     CLOSE();
   
   }
 }





• وضع الطوارئ :


ببساطة سيقوم الاردوينو في هذا الوضع بفتح البوابة حال وجود اشارة طوارئ .
في هذه التجربة اشارة الطوارئ قادمة من مفتاح كهربائي (push button) , لكن يمكن ربط الجهاز مباشرة مع انظمة الحماية في المبنى .



 while(digitalRead(button)== HIGH){
  E_OPEN();
  digitalWrite(LED_1,1);
  digitalWrite(buzzer,1);
  delay(50);
  digitalWrite(LED_1,0);
  digitalWrite(buzzer,0);
  delay(50);
  lcd.clear() ;
  lcd.setCursor(0, 0);
  lcd.print("Emergency");
}







• قفل البوابة 

لإغلاق و فتح البوابة سنتحكم بالقفل الخاص بها , باستخدام Door Lock Actuator الخاص بأقفال السيارات  .



 و هو عبارة عن محرك 12V موصول بآلية معينة لتحويل حركته الدائرية لحركة افقية .
سنتحكم به من خلال H-Bridge بالاتجاهين للداخل و الخارج .

و يتم توصيله كالتالي :
اضغط على الصورة لتكبيرها




و الآن سنكتب كود لفتح البوابة و اغلاقها ..


  • بعد اغلاق او فتح القفل سيستمر المحرك بسحب تيار لكن بدون حركة , و بالتالي تبدأ حرارته و حرارة الـ H-Bridge بالارتفاع , لذلك يجب قطع التيار عنهم بعد مدة قصيرة ( هذا سبب استخدام void OFF )!
  • IN1 و IN2 موصولين على A4 و A5  في الاردوينو

void CLOSE (){
  // void this part to close the door .
  digitalWrite(IN1,1);
  digitalWrite(IN2,0);
  delay(100); 
  OFF();
}

void OPEN (){
  // void this part to open the door .
  digitalWrite(IN1,0);
  digitalWrite(IN2,1);
  delay(100); 
  OFF(); 
}

void OFF (){
  digitalWrite(IN1,0);
  digitalWrite(IN2,0);
  
}

void E_OPEN (){  // emergency open
  // void this part to open the door .
  digitalWrite(IN1,0);
  digitalWrite(IN2,1); 
}




شاهـــــــد النتيجـــــــة








كــود الاردوينــو كــامــلاً



توصيلات الشاشة و الأضواء(LEDs) و الـBuzzer واضحة من خلال الكود .

// Smart Door System. 
// Ali Hadabeen 2014.
// http://ali-madness.blogspot.com/

/*
* MOSI: Pin 11 / ICSP-4
* MISO: Pin 12 / ICSP-1
* SCK: Pin 13 / ISCP-3
* SS: Pin 10
* RST: Pin 9
*/

#include <SPI.h>
#include <RFID.h>
#include <LiquidCrystal.h>


// Setup variables:
int Employee[7][50];
int Employee_Number;
int new_Employee =1 ;
float  start_time ; 
float  now ;
float  work_time ;
boolean door_state = false ;

#define SS_PIN 10
#define RST_PIN 9
#define buzzer A1
#define LED_1 A0
#define button 8
#define main_button A2

const int IN1=A4;
const int IN2=A5;

RFID rfid(SS_PIN, RST_PIN); 
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);





void setup()
{ 
  Serial.begin(9600);
  lcd.begin(16, 2);
  lcd.clear() ;
  SPI.begin(); 
  rfid.init();

  
pinMode(LED_1 ,OUTPUT);
pinMode(button ,INPUT);
pinMode(buzzer ,OUTPUT);

//-----CARD_1---------
 Employee[0][0] =110;
 Employee[1][0] =241;
 Employee[2][0] =127;
 Employee[3][0] =161;
 Employee[4][0] =65;

 //-----CARD_2---------
 Employee[0][1] =253;
 Employee[1][1] =109;
 Employee[2][1] =196;
 Employee[3][1] =234;
 Employee[4][1] =190;
 
 //-----CARD_3---------
 Employee[0][2] =77;
 Employee[1][2] =78;
 Employee[2][2] =228;
 Employee[3][2] =198;
 Employee[4][2] =33;
 
 
 lcd.clear() ;
 lcd.print("Smart Door System");
 CLOSE();
 
}

void loop()
{
 
 CLOSE(); 
 lcd.clear() ;
 lcd.print("Smart Door System");
  lcd.setCursor(0, 1);
  lcd.print("      RFID");
 while(digitalRead(button)== LOW && digitalRead(main_button)== LOW){

//---------------------------------- 

if (Serial.available()) {
   int data = Serial.read();
   if ( data == 'C' ){
     OPEN();
     delay(3000);
     CLOSE();
   
   }
 }
 
//---------------------------------- 

 int time =millis();
 if (time > now+10000){
 lcd.clear() ;
 lcd.print("Smart Door System");
   lcd.setCursor(0, 1);
  lcd.print("      RFID");}
 digitalWrite(LED_1,0);   

 if (rfid.isCard()) {
    if (rfid.readCardSerial()) {
        //Serial.println("card read");
     }
 for ( Employee_Number=0 ; Employee_Number<15 ; Employee_Number++ ) {
        
           if( Employee[0][Employee_Number] == rfid.serNum[0]&&
               Employee[1][Employee_Number] == rfid.serNum[1]&&
               Employee[2][Employee_Number] == rfid.serNum[2]&&
               Employee[3][Employee_Number] == rfid.serNum[3]&&
               Employee[4][Employee_Number] == rfid.serNum[4])
               {
                a(Employee_Number);
                delay (1000);
                break ;}

 }   
 }
 rfid.halt();
}





while( digitalRead(button)== LOW && digitalRead(main_button)==  HIGH ){ 
  lcd.clear() ;
  lcd.print("Smart Door System");
  lcd.setCursor(0, 1);
  lcd.print("      PIR");

  if (digitalRead(A3)){  
    OPEN();
    delay(10000);
    CLOSE();
  }

delay(1000);
}

 while(digitalRead(button)== HIGH){
  E_OPEN();
  digitalWrite(LED_1,1);
  digitalWrite(buzzer,1);
  delay(50);
  digitalWrite(LED_1,0);
  digitalWrite(buzzer,0);
  delay(50);
  lcd.clear() ;
  lcd.setCursor(0, 0);
  lcd.print("Emergency");
}
}


//--------------------------------------


void a(int x){
  
digitalWrite(buzzer,1);
delay(100);
digitalWrite(buzzer,0);
delay(100);
digitalWrite(LED_1,0);

  if (Employee[5][x] == 0)  {
      Employee[5][x] = 1;
      Employee[6][x] = (millis()/60000 );
      lcd.clear() ;
      lcd.setCursor(0, 0);
      lcd.print("WELCOME : ");
      lcd.setCursor(10, 0);
      lcd.print(x);
      OPEN();
      delay(3000);
      CLOSE();
               }

      
  else if (Employee[5][x] == 1)   {
      Employee[5][x] = 0;
      start_time = Employee[6][x] ;
      now = millis()/60000;
      work_time = now - start_time  ;
      Employee[6][x] = 0;
      lcd.clear() ;
      lcd.setCursor(0, 0);
      lcd.print("GOODBYE : ");
      lcd.setCursor(0, 1);
      lcd.print(work_time);
      lcd.setCursor(10, 0);
      lcd.print(x);
      lcd.setCursor(8, 1);
      lcd.print("minute");
      OPEN();
      delay(3000);
      CLOSE();
           }

} 


void CLOSE (){
  // void this part to open the door .
  digitalWrite(IN1,1);
  digitalWrite(IN2,0);
  delay(100); 
  OFF();
}

void OPEN (){
  // void this part to open the door .
  digitalWrite(IN1,0);
  digitalWrite(IN2,1);
  delay(100); 
  OFF(); 
}

void OFF (){
  // void this part to open the door .
  digitalWrite(IN1,0);
  digitalWrite(IN2,0);
  
}

void E_OPEN (){
  // void this part to open the door .
  digitalWrite(IN1,0);
  digitalWrite(IN2,1); 
}





• اقـرأ ايضاً :




كتاب [ تقنيات الاختراق المادي  
لـ عبدالله علي عبدالله .
يحتوي هذا الكتاب على فصل كامل يتحدث فيه عن اقفال الـ RFID  و كيفية تجاوزها 
و فيه معلومات اخرى مهمة و ممتعة :) .

يمكن تحميله من هــنــا .








يمكنك ايضاً اضافة حساس بصمة الاصبع للنظام , لتتمكن  من فتح البوابة مباشرة من خلال التعرف على بصمة الاصبع !
هذا مقال  لصديقنا مهنـد الرواشدة , يشرح فيه طريقة عمل الحساس بالتفصيل .


من هــنــا !







اصنع سومو روبوت

11 التعليقات

بسم الله الرحمن الرحيم



من اشهر المسابقات العالمية في مجال الروبوتات بين الهواة هي مصارعة السومو , وتقام سنوياً العديد من الفعاليات المحلية  و الدولية لهذه المسابقة.

السومو ( sumo ) هي بالأصل رياضة يابانية يتبارى فيها شخصان في حلبة، و يحـاول كل منهمـا إخـراج منافسـه من الحلبة . 





و مسابقة السومو للروبوتات لها نفس المبدأ , حيث يوضع روبوتـين على الحلبة و يحاول كل منهم اخراج الآخر .









• قوانين مسابقة السومو للروبوت :


هذه بعض القوانين الخاصة بتصميم الروبوت التي يجب مراعتها عند عمل الروبوت الخاص بك .


-         يجب أن يكون حجم الروبوت محدد بعرض 20 سم، وطول 20 سم , وارتفاع غير محدد .

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

-       يجب أن لا يتعدي الوزن الكلي للروبوت عند بداية المسابقة عن 3 كجم.

-     يجب أن تكون الروبوتات ذاتية التحكم ويمنع التحكم بها من قبل المتسابقين عن بعد بأي طريقة بعد بدء المسابقة.

-    يجب أن ينتظر الروبوت عند بدء تشغيله مدة 5 ثواني قبل أن يبدأ بالتحرك ليسمح للمتسابقين الخروج من الحلبة.

-    لا يسمح باستعمال أجهزة التشويش أو الكبح مثل (IR LEDs) التي قد تسبب في عجز أجهزة الاستشعار للفريق الآخر.

-    لا يسمح بالأجزاء التي يمكن أن تتسبب في كسر أو أضرار للحلبة ولا يسمح باستخدام الأجزاء التي يمكن أن تسبب ضرراً للروبوت أو اللاعب المنافس ولا تعتبر الإصتدامات العادية تعمد للضرر.

-     لا يسمح باستعمال الأجهزة التي تخزن السوائل، البودرة، الغازات أو غيرها من المواد التي قد تستعمل في القذف على الروبوت المنافس.

-         لا يسمح بأي أداة قابلة للاشتعال أو تسبب الوهج الناري.

-         لا يسمح بالأجهزة التي تقذف أشياء ضد الفريق المنافس.


-         لايسمح باستخدام أجهزة تساعد على زيادة قوة تثبيت الروبوت مثل وضع الشفاطة والمغناطيس.

 ( باقي القوانين الخاصة بشكل الحلبة و طريقة اللعب و النقاط و المخالفات .. الخ , يمكن الاطلاع عليها من هــنــا )







ماذا احتاج لبناء الروبوت ؟ 


  •  متحكم اردوينو ( من أي نوع ).
  •  محركات + علبة تروس + مجسم ( حسب التصميم ).( يمكنك شراء محركات ومجسم جاهز من هـنـا ) .
  • بطاريات .
  • حساس ألتراسونك (يمكنك شراؤه من هنا ).
  • حساس  IR TCRT5000 عدد2  (يمكنك شراؤه من هنا ).
  • (H-bridge (L298N  (يمكن شراؤه من هنا )
  • اسلاك توصيل.



لنبدأ بتجهيز اجزاء الروبوت ثم نقوم بتجميعها معاً ...





• حساس الـ IR :

حتى نتأكد من ان الروبوت لن يخرج عن الحلبة نضيف حساس الـ IR  في الامام و من الخلف .
حساس الـIR يمكنه التمييز بين اللونين ( الابيض و الأسود ) و يمكن ان نستفيد منه لأن لون الحبة اسود و محيطها أبيض . 


[ عند اللون الابيض تكون اشارة الحساس HIGH .. و LOW للون الاسود  , أو  العكس حسب تصميم الموديول  ]



و بالتالي اذا كانت قراءة الحساس تشير للون الابيض , يكون الروبوت على وشك الخروج من الحلبة , و يجب ان يقوم الروبوت بتعديل طريقة حركته حتى يتجنب الخروج !
عادة ما يكون الحساس في موديول جاهز-كما في الصورة-  و يوصل مباشرة مع احد المداخل التناظرية ( Analog) .




اذا كان لديك الحساس منفصل ,يمكن عمل دارة بسيطة لتوصيله بالاردوينو ...


اضغط على الصورة لتكبيرها






• حساس الالتراسونك : 

سنستخدم حساس الالتراسونك لتحديد مكان الروبوت الخصم ..
نوصل الحساس كما في الصورة :


[ للتعرف اكثر على حساس الالتراسونك يمكنك قراءة هذا المقال المفصل للزميل مهند الرواشدة ( من هنا ) ]





• توصيل المحركات :
نقوم بتوصيل المحركات مع الـ H-bridge و مع الاردوينو و البطاريات  كما في الشكل :

اضغط على الصورة لتكبيرها
- يجب وصل الـ GND للاردوينو الـH-bridge  معـاً !
- نصل مفتاح (switch) مع تغذية الاردوينو لتشغيل و ايقاف الروبوت !


نضع كل القطع على مجسم الروبوت و نثبتها جيداً . 





• تصميم مجسم الروبوت :

سنقوم بعمل تصميم بسيط للروبوت و هو من اسهل التصاميم , يكون باضافة قطعة بلاستيكية الى مقدمة الروبوت و تميل بزاوية معينة .
[ يمكنك عمل اي تصميم تريد , حاول ان تفكر بتصاميم اكثر ابداعاً ]




وليكون الروبوت اكثر ثباتاً , سنضع البطاريات في مقدمة الروبوت (لأن وزنها اكبر من القطع الاخرى ) و نضع باقي القطع في الخلف .

و يجب ان نتأكد من ابعاد الروبوت و وزنه بما تحدده قوانين اللعبة..
ليكون شكل الروبوت النهائي كالتالي :









 البرمجة :


يمكن برمجة الروبوت بأكثر من طريقة , حسب الطريقة التي تريد ان يلعب فيها الروبوت على الحلبة . 

طــريقــة اللـعب : 
  • سنجعل الروبوت يدور حول نفسه بشكل مستمر . 
  • يقوم الروبوت بقياس المسافة بشكل متواصل اثناء الدوران .
  • في حال قلت المسافة المقاسة عن قيمة معينة (10سم مثلاً ), يعني ذلك وجود الروبوت الخصم امام الروبوت الخاص بنا مباشرة .
  • يتوقف الروبوت مباشرة عن الدوران . ثم يبدأ بالهجوم ( التحرك للأمام باقصى سرعة).
  • يجب ان يأخذ الروبوت القراءات من حساسي الـIR دائمــاً .
  • في حال اشارت قراءة الـIR  لوجود اللون الابيض , يجب ان يتحرك الروبوت مباشرة في عكس اتجاه الحساس ( مثلا : اذا كان الحساس الامامي الذي اعطى اشارة للون الابيض يتحرك الروبوت للخلف ) !


كـود الأردوينــو : 






#include "Ultrasonic.h"
Ultrasonic ultrasonic(4,3);//المداخل الموصولة مع الحساس
const int IN1=5;
const int IN2=6;
const int IN3=9;
const int IN4=10;
#define IR_sensor_front A0 // الحساس الامامي
#define IR_sensor_back A1 // الحساس الخلفي
int distance ;

void setup() 
{
Serial.begin(9600);
delay (5000); // حسب قوانين السومو 
}


void loop()
{
  
 int IR_front = analogRead(IR_sensor_front);
 int IR_back = analogRead(IR_sensor_back);
 distance = ultrasonic.Ranging(CM) ;
 ROTATE(200); // يبدأ الروبوت بالدوران

 if (distance < 20){
    Stop();
    while (distance < 20 ) {
    FORWARD(255); 
    distance = ultrasonic.Ranging(CM);
    IR_front = analogRead(IR_sensor_front);
    IR_back = analogRead(IR_sensor_back);
    if ( IR_front > 650 || IR_back > 650 ) { break;}
    delay(10); }
  }
  
 if (IR_front < 650 )  // اذا كانت القراءة اقل من 650 يعني اللون ابيض
   {
   Stop();
   delay (50);
   BACKWARD(255);
   delay (500);
   } 
   
 if (IR_back < 650 )  //
   {
   Stop();
   delay (50);
   FORWARD(255);
   delay (500);
   }

/* ----------- debugging ----------------
  Serial.print(ultrasonic.Ranging(CM));
  Serial.println("cm");
  Serial.println("IR front :");
  Serial.println(IR_front); 
  Serial.println("IR back :");
  Serial.println(IR_back);  
*/ --------------------------------------  

}



//--------------------------------------------
void FORWARD (int Speed){
  //When we want to let Motor To move forward,
  // just void this part on the loop section .
  analogWrite(IN1,Speed);
  analogWrite(IN2,0);
  analogWrite(IN3,0);
  analogWrite(IN4,Speed);
}


//--------------------------------------------
void BACKWARD (int Speed){
  //When we want to let Motor To move forward,
  // just void this part on the loop section .
  analogWrite(IN1,0);
  analogWrite(IN2,Speed);
  analogWrite(IN3,Speed);
  analogWrite(IN4,0);
}

//--------------------------------------------
void ROTATE (int Speed){
  //When we want to let Motor To Rotate ,
  // just void this part on the loop section .
  analogWrite(IN1,Speed);
  analogWrite(IN2,0);
  analogWrite(IN3,Speed);
  analogWrite(IN4,0);
}


//--------------------------------------------
void Stop(){
  //When we want to  Motor To stop ,
  // just void this part on the loop section .
  analogWrite(IN1,0);
  analogWrite(IN2,0);
  analogWrite(IN3,0);
  analogWrite(IN4,0);
}





تكون النتيجة النهائية كما في الفيديو التالي : 









حاول ان تطبق هذا الروبوت و تجربه لتتعرف على نقاط الضعف فيه , ثم حاول ان تفكر بطريقة لعب اخرى , او ان تعدل تصميم الروبوت , يمكنك مثلاً الاستفادة من القانون الذي يسمح بزيادة ابعاد الروبوت بعد بدء المباراة , بعض التصاميم يزيد عرضها الـى 60سم بعد بدء المباراة !

هذه بعض التصاميم :

------------------------


------------------------



------------------------


------------------------







صور من مسابقة السومو في الجامعــة الهاشميـــة (الأردن) :














جميع الحقوق محفوظة - علي الهضابين ©2012-2013 | ، يرجى ذكر المصدر عند النقل . Privacy-Policy | أنضم ألى فريق التدوين


تصميم alwan-blogger | تطوير Reda Yagoub