منتديات الهندسة الكهربية والإلكترونية والميكاترونكس والكومبيوتر
هل تريد التفاعل مع هذه المساهمة؟ كل ما عليك هو إنشاء حساب جديد ببضع خطوات أو تسجيل الدخول للمتابعة.

تدريبات ومشاريع الأردوينو Arduino Tutorials and Projects

صفحة 4 من اصل 4 الصفحة السابقة  1, 2, 3, 4

اذهب الى الأسفل

تدريبات ومشاريع الأردوينو Arduino Tutorials and Projects  - صفحة 4 Empty ساعة Clock باستخدام الاردوينو وشاشة مكونة من أربعة وحدات سفن سيجمنت بنظام الانتخاب Multiplexing وساعة التوقيت الحقيقى

مُساهمة من طرف Admin الخميس فبراير 13, 2020 6:24 pm

ساعة Clock باستخدام الاردوينو وشاشة مكونة من أربعة وحدات سفن سيجمنت بنظام الانتخاب Multiplexing وساعة التوقيت الحقيقى DS3231

يدور هذا التدريب حول إنشاء ساعة رقمية عن طريق "انتخاب" multiplexing ما بين أربعة وحدات سقن سيجمنت باستخدام Arduino UNO وعرض الوقت بتنسيق
HH: MM .

الدائرة الكهربية :

تدريبات ومشاريع الأردوينو Arduino Tutorials and Projects  - صفحة 4 7397843A84204E31989DFC0E3D888049

البرمجة :

سيتم شرح كيفية أخذ الوقت (بالساعة hour والدقيقة minute) من وحدة ساعة الوقت الحقيقى RTC بتنسيق 24 ساعة 24hr ، ثم يتم تحويله إلى التنسيق المناسب لعرضه في شاشة العرض السفن سيجمنت المكونة من 4 أرقام .
لربط الموديول DS3231 RTC مع Arduino UNO ، يتم استخدام ناقل I2C من Arduino UNO. يتم تضمين مكتبة تسمى <DS3231.h> في البرنامج للوصول إلى دوال الإعداد setting وقراءة الوقت والتاريخ وبيانات درجة الحرارة وما إلى ذلك. قم بتنزيل المكتبة وتثبيتها فى بيئة تطوير الاردوينو . نظرًا لأن وحدة RTC تستخدم واجهة I2C ، يتم استخدام المكتبة <wire.h> أيضًا في البرنامج.
يتم أخذ الساعة hour والدقيقة minute أولاً من RTC ويتم دمجهما معًا مثل 0930 (09:30 pm) ومن ثم يتم فصل الأرقام بشكل فردى مثل الآلاف thousands والمئات hundreds والعشرات tens والآحاد units ، والأرقام الفردية يتم تحويلها إلى تنسيق ثنائي مثل الصفر 0 يحول إلى 63 (0111111) . يتم إرسال هذا الكود الثنائي إلى سجل الإزاحة ومن ثم من سجل الإزاحة إلى السفن سيجمنت من نوع الكاثود المشترك ، ليتم عرض الرقم 0 على شاشة السفن سيجمنت . وبهذه الطريقة ، يتم انتخاب multiplexed الأرقام الأربعة ويتم عرض الساعة والدقيقة.


خطوات البرنامج :
1- في البداية ، يتم تضمين المكتبات الضرورية مثل مكتبة DS3231 والمكتبة Wire (مكتبة I2C).

الكود:
 #include <Wire.h> 
#include<DS3231.h>

2- يتم تعريف أطراف التحكم فى السفن سيجمنت . ستلعب عناصر التحكم هذه دورًا مهمًا في انتخاب multiplexing الشاشة.

الكود:
#define latchPin 5                     
#define clockPin 6
#define dataPin 4

3- يتم الإعلان عن المتغيرات لتخزين النتيجة المحولة أو الأولية raw المأخوذة من RTC.


الكود:
 int h;              //Variable declared for hour
int m;              //Variable declared for minute
int thousands;   
int hundreds;
int tens;
int unit;
bool h24;
bool PM;

4- يتم الإعلان عن كائن الفئة DS3231 مثل RTC لتبسيط الاستخدام في الأسطر .

الكود:
DS3231 RTC;

5- فى الدالة setup ، نظرا لأنه يتم ربط وحدة RTC مع الاردوينو باستخدام الاتصال I2C. لذلك ، تستخدم الدالة wire.begin() لبدء الاتصال I2C في العنوان الافتراضي للوحدة RTC حيث لا توجد وحدات I2C أخرى.

الكود:
 Wire.begin();

6- كما يتم تعريف وضع الطرف ، ما إذا كان سيتصرق كدخل أم كخرج .

الكود:
  pinMode(9,OUTPUT);
    pinMode(10,OUTPUT);
    pinMode(11,OUTPUT);
    pinMode(12,OUTPUT);
    pinMode(latchPin, OUTPUT);
    pinMode(clockPin, OUTPUT);
    pinMode(dataPin, OUTPUT);
 


7- تعمل الدالة loop بشكل لا نهائي وتأخذ الوقت بالساعة والدقيقة من الوحدة RTC DS3231 . يشير البارامتر ‘h24’ إلى تنسيق المتغير فى شكل 24hr .

الكود:
[code]int h= RTC.getHour(h24, PM);
int m = RTC.getMinute();
 [/code]

8- بعد ذلك يتم الجمع بين الساعة hour والدقيقة minute كعدد واحد (مثال إذا كانت الساعة 10 والدقيقة 60 عندئذ يكون العدد 10*100=1000+60 =1060 ).

الكود:
int number = h*100+m;

9- يتم الحصول على الأرقام الفردية من العدد (على سبيل المثال ، العدد 1060- الواحد 1 هو الآلاف thousands ، و الصفر 0 هو المئات hundreds ، والواحد التالى 1 هو العشرات tens والصفر الذى يليه 0 هو الآحاد unit ، آخر رقم). لفصل الأرقام ، يتم استخدام معامل باقى القسمة % . على سبيل المثال ، في 1060 للحصول على 1 عندئذ 1060/1000=1.06%10=1. ومن ثم يتم تخزين الأرقام المنفصلة في متغيرات منفصلة.

الكود:
  int thousands = number/1000%10;
    int hundreds = number/100%10;
    int tens = number/10%10;     
    int unit = number%10;
 

10- بعد ذلك يتم استخدام عبارة switch case لكل رقم فردي لتحويلها إلى التنسيق المناسب (تنسيق ثنائي) وإرسالها عبر مسجل الإزاحة لعرضها على السفن سيجمنت . على سبيل المثال (بالنسبة للرقم واحد “1” يتم تغييره إلى 06 (0000 0110)) . بحيث يتم إرساله عبر الإزاحة ، ويتم عرض الرقم واحد “1” على السفن سيجمنت (الصفر 0 يعنى LOW ، والواحد 1 يعنى HIGH).

الكود:
 switch (t)
{
  case 0:
  unit = 63;
  break;
  case 1:
  unit = 06;
  break;
  case 2:
  unit =91;
  break;
  case 3:
  unit=79;
  break;
  case 4:
  unit=102;
  break;
  case 5:
  unit = 109;
  break;
  case 6:
  unit =125;
  case 7:
  unit = 07;
  break;
  case 8:
  unit = 127;
  break;
  case 9:
  unit =103;
  break;
  }

11- بعد ذلك ، يتم إرسال الرقم الفردي بالتنسيق الثنائي عبر الدالة "shiftout" مع MSB أولاً ويكون الطرف المشترك للرقم digit الخاص به منخفضا LOW (كاثود مشترك) ويكون طرف latch مرتفعا HIGH .

الكود:
digitalWrite(9, LOW);//digit thousands on , common cathode

digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST,thousands);
digitalWrite(latchPin, HIGH);

delay(5);

digitalWrite(9, HIGH); //  digit thousands off



البرنامج :

الكود:
//Four-Digit 7 Segments Multiplexing using Arduino: Display time in HH:MM
#include <Wire.h>    //Library for SPI communication
#include <DS3231.h>  //Library for RTC module
 
#define latchPin 5                     
#define clockPin 6
#define dataPin 4

DS3231 RTC;        //Declare object RTC for class DS3231

int h;              //Variable declared for hour
int m;              //Variable declared for minute
int thousands;   
int hundreds;
int tens;
int unit;
bool h24;
bool PM;

void setup ()
{
    Wire.begin();
   
    pinMode(9,OUTPUT);
    pinMode(10,OUTPUT);
    pinMode(11,OUTPUT);
    pinMode(12,OUTPUT);

    pinMode(latchPin, OUTPUT);
    pinMode(clockPin, OUTPUT);
    pinMode(dataPin, OUTPUT);
    }
 
void loop ()
{
    int h= RTC.getHour(h24, PM);  //To get the Hour
    int m = RTC.getMinute();      //TO get the minute

    int number = h*100+m;        //Converts hour and minute in 4-digit
    int thousands = number/1000%10; //Getting thousands digit from the 4 digit
    int hundreds = number/100%10;  //Getting hundreds digit from 4 digit
    int tens = number/10%10;        //Getting tens digit from 4-digit
    int unit = number%10;          //Getting last digit from 4-digit
    int t= unit;
    int u= tens;
    int v= hundreds;
    int w= thousands;

//Converting the individual digits into corresponding number for passing it through the shift register so LEDs are turned ON or OFF in seven segment
switch (t)
{
  case 0:
  unit = 63;//common cathod
  break;
  case 1:
  unit = 06;
  break;
  case 2:
  unit =91;
  break;
  case 3:
  unit=79;
  break;
  case 4:
  unit=102;
  break;
  case 5:
  unit = 109;
  break;
  case 6:
  unit =125;
  case 7:
  unit = 07;
  break;
  case 8:
  unit = 127;
  break;
  case 9:
  unit =103;
  break; 
  }
switch (u)
{
  case 0:
  tens = 63;
  break;
  case 1:
  tens = 06;
  break;
  case 2:
  tens =91;
  break;
  case 3:
  tens=79;
  break;
  case 4:
  tens=102;
  break;
  case 5:
  tens= 109;
  break;
  case 6:
  tens =125;
  case 7:
  tens = 07;
  break;
  case 8:
  tens = 127;
  break;
  case 9:
  tens =103;
  break; 
  }
 
  switch (v)
  {
  case 0:
  hundreds = 63;
  break;
  case 1:
  hundreds = 06;
  break;
  case 2:
  hundreds =91;
  break;
  case 3:
  hundreds=79;
  break;
  case 4:
  hundreds=102;
  break;
  case 5:
  hundreds = 109;
  break;
  case 6:
  hundreds =125;
  case 7:
  hundreds = 07;
  break;
  case 8:
  hundreds = 127;
  break;
  case 9:
  hundreds =103;
  break; 
  }
 
  switch (w)
  {
  case 0:
  thousands = 63;
  break;
  case 1:
  thousands = 06;
  break;
  case 2:
  thousands =91;
  break;
  case 3:
  thousands=79;
  break;
  case 4:
  thousands=102;
  break;
  case 5:
  thousands = 109;
  break;
  case 6:
  thousands =125;
  case 7:
  thousands = 07;
  break;
  case 8:
  thousands= 127;
  break;
  case 9:
  thousands =103;
  break; 
  }

    digitalWrite(9, LOW);// Turinig on thousands digit

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST,thousands);  // The thousand digit is sent
    digitalWrite(latchPin, HIGH);  // Set latch pin HIGH to store the inputs

  delay(5);                      // delay for multiplexing
  digitalWrite(9, HIGH);        // Turinig off thousands digit

    digitalWrite(10, LOW);

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST,hundreds );    // The hundered digit is sent
    digitalWrite(latchPin, HIGH);

 
    delay(5);
  digitalWrite(10, HIGH);                             
 
    digitalWrite(11, LOW);

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST,tens);  // The tens digit is sent
    digitalWrite(latchPin, HIGH);

 
    delay(5);
    digitalWrite(11, HIGH);
   
    digitalWrite(12, LOW);

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST,unit);  // The last digit is sent
    digitalWrite(latchPin, HIGH);

    delay(5);
    digitalWrite(12, HIGH);
   
}
 






Admin
Admin

عدد المساهمات : 1194
تاريخ التسجيل : 28/01/2014

https://fathallaabdelaziz.forumarabia.com

الرجوع الى أعلى الصفحة اذهب الى الأسفل

تدريبات ومشاريع الأردوينو Arduino Tutorials and Projects  - صفحة 4 Empty قياس الرطوبة Humidity ودرجة الحرارة Temperature باستخدام الاردوينو Arduinoوالحساس DHT

مُساهمة من طرف Admin الثلاثاء فبراير 18, 2020 12:12 pm

قياس الرطوبة Humidity ودرجة الحرارة Temperature باستخدام الاردوينو Arduinoوالحساس DHT11

الرطوبة ودرجة الحرارة هى بارامترات شائعة لقياس الظروف البيئية. في هذا المشروع القائم على Arduino ، سنقوم بقياس درجة الحرارة والرطوبة المحيطة وعرضها على شاشة LCD مقاس 16 × 2. يتم استخدام مستشعر درجة الحرارة والرطوبة الشائع DHT11 مع Arduino uno لتطوير مقياس حرارة thermometer مئوى Celsius ومقياس رطوبة كنسبة مئوية .
يتكون هذا المشروع من ثلاثة أقسام – القسم الأول يستشعر الرطوبة ودرجة الحرارة باستخدام حساس الرطوبة ودرجة الحرارة DHT11. القسم الثاني يقرأ خرج وحدة الحساس DHT ويستخرج قيم درجة الحرارة والرطوبة إلى رقم مناسب من حيث النسبة المئوية والدرجة المئوية. والجزء الثالث من النظام يعرض الرطوبة ودرجة الحرارة على شاشة LCD .

تدريبات ومشاريع الأردوينو Arduino Tutorials and Projects  - صفحة 4 2C9EFF2123DB4289BD6A7711B91D3A12

يعتمد عمل هذا المشروع على الاتصال التسلسلى لسلك مفرد . فى البداية يرسل الاردوينو إشارة بدء إلى الوحدة DHT ثم يعطي DHT إشارة استجابة تحتوي على بيانات درجة الحرارة والرطوبة. يقوم الاردوينو بالتجميع والاستخراج في شكل جزأين ، الأول هو الرطوبة والثاني هو درجة الحرارة ومن ثم إرسالها إلى شاشة LCD 16X2 .
في هذا المشروع ، استخدمنا وحدة module استشعار تسمى DHT11. تتميز هذه الوحدة بتركيبة للرطوبة والحرارة مع خرج إشارة رقمية معايرة ، يعني أن وحدة الاستشعار DHT11 هي وحدة مشتركة لاستشعار الرطوبة ودرجة الحرارة والتي تعطي إشارة خرج رقمية معايرة. المستشعر DHT11 يعطينا قيمة دقيقة للغاية للرطوبة ودرجة الحرارة ويضمن موثوقية عالية والاستقرار على المدى الطويل. يحتوي هذا المستشعر على مكون لقياس الرطوبة من نوع المقاومة ومكون لقياس درجة الحرارة من النوع NTC مع متحكم 8 بت مدمج له استجابة سريعة وفعال من حيث التكلفة ومتوفر في حزمة بأربعة أطراف فى صف واحد .

تدريبات ومشاريع الأردوينو Arduino Tutorials and Projects  - صفحة 4 79AFFD45C7EE49A3BEAB890266977769

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


تدريبات ومشاريع الأردوينو Arduino Tutorials and Projects  - صفحة 4 16C3A399984744079895557410004633

شيء مهم هو التأكد من قيمة مقاومة السحب لأعلى لأننا إذا وضعنا مستشعر DHT على مسافة أقل من 20 متر ، فمن المستحسن أن تكون قيمة مقاومة السحب لأعلى هى 5k . إذا وضع DHT على مسافة أطول من 20 متر عندئذ استخدم القيمة المناسبة لمقاومة السحب لأعلى .

الدائرة الكهربية :


تدريبات ومشاريع الأردوينو Arduino Tutorials and Projects  - صفحة 4 4047673EF2D54B0AB6E440AEE6A2EC53

يتم استخدام شاشة LCD لعرض درجة الحرارة والرطوبة والتي ترتبط مباشرة مع اردوينو في وضع 4 بت. يتم توصيل أطراف الشاشة المسماة RS, EN, D4, D5, D6 , D7 لأطراف الاردوينو الرقمية رقم 2, 3, 4, 5, 6 , 7 . ويتم توصيل وحدة الاستشعار DHT11 بالطرف الرقمي 12 من الاردوينو ومع مقاومة السحب لأعلى 5k .

وصف البرمجة :

1- في البرمجة ، سوف نستخدم مكتبات مسبقة الصنع للمستشعر DHT11 ووحدة العرض LCD.

الكود:
 #include<dht.h>      // Including library for dht
#include<LiquidCrystal.h>

2- ثم نقوم بتعريف أطراف الشاشة LCD وتعريف طرف المستشعر DHT ، وإنشاء كائن من الفئة dht ، وإعلان حرف درجة الحرارة :

الكود:
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
#define dht_dpin 12
dht DHT;
byte degree[8] =
              {
                0b00011,
                0b00011,
                0b00000,
                0b00000,
                0b00000,
                0b00000,
                0b00000,
                0b00000
              };

3- ويتم تهيئة كل الأشياء فى دالة الإعداد setup .

الكود:
 void setup()
{
 lcd.begin(16, 2);
 lcd.createChar(1, degree);
 lcd.clear();
 lcd.print("  Humidity  ");
 lcd.setCursor(0,1);
 lcd.print("  Measurement ");
 delay(2000);
 lcd.clear();
}

4- بعد ذلك في الدالة loop وباستخدام الدالة dht ، يقرأ المستشعر DHT بالدالة DHT.read11، ثم باستخدام بعض دوال dht (DHT.humidity , DHT.temperature ) ، نستخلص الرطوبة ودرجة الحرارة ونعرضها على شاشة LCD.

الكود:
 void loop()
{
  DHT.read11(dht_dpin);

  lcd.setCursor(0,0);
  lcd.print("Humidity: ");
  lcd.print((int)DHT.humidity);  // printing Humidity on LCD
  lcd.print("%");

  lcd.setCursor(0,1);
  lcd.print("Temperature:");
  lcd.print((int)DHT.temperature);  // Printing temperature on LCD
  lcd.write(1); // lcd.print((char)223);
  lcd.print("C");
  delay(500);
}



البرنامج :

الكود:

#include<dht.h>      // Including library for dht
#include<LiquidCrystal.h>

LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
#define dht_dpin 12
dht DHT;
byte degree[8] =
              {
                0b00011,
                0b00011,
                0b00000,
                0b00000,
                0b00000,
                0b00000,
                0b00000,
                0b00000
              };

void setup()
{
 lcd.begin(16, 2);
 lcd.createChar(1, degree);
 lcd.clear();
 lcd.print("  Humidity  ");
 lcd.setCursor(0,1);
 lcd.print("  Measurement ");
 delay(2000);
 lcd.clear();
}

void loop()
{
  DHT.read11(dht_dpin);
  lcd.setCursor(0,0);
  lcd.print("Humidity: ");
  lcd.print((int)DHT.humidity);  // printing Humidity on LCD , DHT.humidity returns humidity in percent
  lcd.print(" %");
  lcd.setCursor(0,1);
  lcd.print("Temperature:");
  lcd.print((int)DHT.temperature); // Printing temperature on LCD,DHT.temperature returns the temperature in Celsius
  lcd.write(1);
  lcd.print("C");
  delay(500);
}



مثال مع العرض على المنفذ التسلسلى :

تدريبات ومشاريع الأردوينو Arduino Tutorials and Projects  - صفحة 4 10C4D798CFA741DCBCD6DDB7E9DC9240

الكود:
 
#include "dht.h"
#define dht_dpin 12 // sensor Pin
 
dht DHT;
 
void setup(){
 
  Serial.begin(9600);
  delay(500);//Delay to let system boot
  Serial.println("DHT11 Humidity & temperature Sensor\n\n");
  delay(1000);//Wait before accessing Sensor
 
}//end "setup()"
 
void loop(){
  //Start of Program
 
    DHT.read11(dht_dpin);
   
    Serial.print("Current humidity = ");
    Serial.print(DHT.humidity); //  DHT.humidity returns humidity in percent
    Serial.print("%  ");
    Serial.print("temperature = ");
    Serial.print(DHT.temperature); // DHT.temperature returns the temperature in Celsius
    Serial.println("C  ");
   
    delay(5000);//Wait 5 seconds before accessing sensor again.
 
  //Fastest should be once every two seconds.
 
}// end loop()

Admin
Admin

عدد المساهمات : 1194
تاريخ التسجيل : 28/01/2014

https://fathallaabdelaziz.forumarabia.com

الرجوع الى أعلى الصفحة اذهب الى الأسفل

تدريبات ومشاريع الأردوينو Arduino Tutorials and Projects  - صفحة 4 Empty مقاطعات الاردوينو Arduino Interrupts

مُساهمة من طرف Admin السبت فبراير 22, 2020 6:42 pm

مقاطعات الاردوينو Arduino Interrupts

مفهوم المقاطعة :
إعتبر سيارة سريعة الحركة ، إذا صدمت سيارة أخرى فجأة في الاتجاه المعاكس ، فإن أول شيء يحدث هو أن مستشعر التسارع accelerometer الموجود في السيارة يستشعر حدوث عدم تسارع de-acceleration (تباطؤ) مفاجئ ويؤدي إلى مقاطعة خارجية للميكروكونترولر (المتحكم الدقيق) الموجود في السيارة ، ثم ينتج المتحكم إشارة كهربائية لنشر الأكياس الهوائية على الفور. يقوم المتحكم الموجود في السيارة بمراقبة العديد من الأشياء في وقت واحد مثل استشعار سرعة السيارة ، والتحقق من أجهزة الاستشعار الأخرى ، والتحكم في درجة حرارة مكيف الهواء وما إلى ذلك. فما الذي يجعل الفتح المفاجىء لكيس الهواء في ثوانٍ؟ يتم استخدام إشارة المقاطعة Interrupt هنا والتي لها الأولوية القصوى للجميع.
مثال بسيط آخر على المقاطات Interrupts هو الهواتف المحمولة التي تعمل باللمس والتي لها الأولوية القصوى للإحساس باللمس "Touch". لدى كل جهاز إلكتروني تقريبًا نوع من المقاطعات لإيقاف (مقاطعة) العملية المعتادة والقيام ببعض الأشياء ذات الأولوية العليا عند حدث معين. يتم استئناف العملية العادية بعد قضاء المقاطعة.
من الناحية الفنية ، تعد المقاطعات Interrupts آلية يمكن بواسطتها تعليق (إيقاف) الإدخال / الإخراج أو التعليمة من التنفيذ العادي للمعالج والحصول على خدماته كما لوأن لها أولوية مرتفعة . على سبيل المثال ، يمكن مقاطعة المعالج الذي يقوم بتنفيذ عادي من قبل بعض أجهزة الاستشعار لتنفيذ عملية معينة موجودة في ISR (روتين خدمة المقاطعة). بعد تنفيذ المعالج ISR يمكن مرة أخرى استئناف التنفيذ العادي.

أنواع المقاطعات :
هناك نوعان من المقاطعات:
مقاطعة الأجهزة (الهاردوير) Hardware Interrupt : يحدث ذلك عندما يحدث حدث خارجي مثل تغيير حالة طرف المقاطعة الخارجي حالته من LOW إلى HIGH أو LIGH إلى LOW .
مقاطعة البرمجيات Software Interrupt : يحدث وفقا للتعليمات من البرمجيات . على سبيل المثال مقاطعات المؤقت Timer هي مقاطعة برمجية .

المقاطعات في الاردوينو :
الآن سوف نرى كيفية استخدام المقاطعات في لوحة الاردوينو ، والتى لها نوعان من المقاطعات:
• مقاطعة خارجية External Interrupt .
• مقاطعة تغيير الطرف Pin Change Interrupt.

المقاطعة الخارجية External Interrupt :
يتم تفسير هذه المقاطعة بواسطة الأجهزة hardware وتكون سريعة جداً. يمكن تعيين هذه المقاطعات ليتم تشغيلها في حالة حدوث مستويات "صاعدة " RISING أو "هابطة " FALLING أو الحالة LOW.
فى الاردوينو أونو UNO والنانو NANO تخصص الأطراف الرقمية 2 و 3 للمقاطعة الخارجية .

مقاطعات تغيير الطرف Pin Change Interrupts :
يمكن أن يكون للاردوينو أطراف مقاطعة أكثر تمكن enabled باستخدام المقاطعات Pin Change . في لوحات الاردوينو القائمة على المتحكمات ATmega168 / 328 ، يمكن استخدام أي الأطراف أو جميع أطراف الإشارة العشرين كأطراف مقاطعة. يمكن أيضًا تشغيلها باستخدام الحواف الصاعدة RISING أو الهابطة FALLING .

استخدام المقاطعات الخارجية في الاردوينو :
من أجل استخدام المقاطعات في الاردوينو ، يجب فهم المفاهيم التالية.

روتين خدمة المقاطعة Interrupt Service Routine (ISR) :
روتين خدمة المقاطعة ISR أو معالج المقاطعة Interrupt handler هو حدث يحتوي على مجموعة صغيرة من التعليمات . عند حدوث مقاطعة خارجية ، يقوم المعالج أولاً بتنفيذ هذه التعليمات البرمجية الموجودة في ISR ويعود مرة أخرى إلى الحالة التي ترك فيها التنفيذ العادي.

بناء جملة ISR فى الاردوينو كما يلى :

الكود:
 attachInterrupt(digitalPinToInterrupt(pin), ISR, mode);

الوسيط الأول :

الكود:
digitalPinToInterrupt(pin)

في الاردوينو أونو Uno ، ونانو NANO الأطراف المستخدمة للمقاطعة هي 2,3 وفى الميجا mega هى 2,3,18,19,20,21 . يتم تحديد طرف الدخل المستخدم للمقاطعة الخارجية هنا.

الوسيط الثانى :
ISR: هي دالة تستدعى عند إجراء مقاطعة خارجية.

الوسيط الثالث :
Mode : نوع الانتقال إلى التشغيل trigger ، على سبيل المثال falling ، rising ، إلخ.
• RISING : لتشغيل مقاطعة عندما ينتقل طرف من LOW إلى HIGH.
• FALLING : لتشغيل مقاطعة عندما ينتقل طرف من HIGH إلى LOW .
• CHANGE : لتشغيل المقاطعة عندما ينتقل طرف من LOW إلى HIGH أو من HIGH إلى LOW (أي عندما تتغير حالة الطرف ).

بعض الشروط أثناء استخدام المقاطعة :
• روتين خدمة مقاطعة المقاطعة (ISR) يجب أن يكون أقصر ما يمكن.
• الدالة Delay () لا تعمل داخل ISR ويجب تجنبها.

في هذا التدريب الخاص بمقاطعة الاردوينو ، يتم زيادة عدد number من 0 (العمل العادى) ويتم استخدام زري ضغط لتشغيل مقاطعة ، كل واحد متصل بطرف D2 & D3. يتم استخدام ليد LED لبيان المقاطعة. في حالة الضغط على زر الضغط الأول ، يتم تشغيل الليد ON ويظهر العرض interrupt2 ويختفى ، وعندما يتم الضغط على زر الضغط الثانى ، يتم إيقاف تشغيل الليد OFF ويظهر العرض interrupt1 ويختفى .

الدائرة الكهربية :

تدريبات ومشاريع الأردوينو Arduino Tutorials and Projects  - صفحة 4 6C1A18AE62DB419F9E08F8E4BF2E35C7

يتم توصيل اثنين من أزرار الضغط للاردوينو أونو في الأطراف D2 و D3. يتم استخدامها لعمل مقاطعتين خارجيتين ، أحدهما لتشغيل ليد LED والآخر لإيقاف تشغيل الليد LED. كل زر ضغط لديه مقاومة سحب لأسفل بقيمة 10k متصلة بالأرضى. لذلك عند الضغط على زر الضغط ، يكون المنطق HIGH (1) وعندما لا يتم الضغط عليه يكون المنطق LOW (0) . مقاومة السحب لأسفل إلزامية ، وإلا ستكون هناك قيم عائمة عند طرفى الدخل D2 & D3.
كما يتم استخدام ليد LED لبيان أن المقاطعة قد تم تشغيلها أو الضغط على زر.

برمجة مقاطعة الاردوينو :
في هذا التدريب ، يتم زيادة عدد من 0 والذي يتم عرضه بشكل مستمر على شاشة LCD (16x2) المتصلة مع الاردوينو أونو ، كلما تم الضغط على الزر الأيمن (طرف المقاطعة D3) ، يتم تشغيل الليد LED ويظهر العرض Interrupt2 ، وعند الضغط على الزر الأيسر (طرف المقاطعة D2) يتم إيقاف تشغيل الليد LED ويظهر العرض Interrupt1.

البرنامج :


الكود:
//Interrupts using Arduino
//Circuit Digest
#include<LiquidCrystal.h>                        // Including lcd display library
LiquidCrystal lcd (7,8,9,10,11,12);              // Define LCD display pins RS,E,D4,D5,D6,D7
volatile int output = LOW;                     
int i = 0; 
void setup()                                                     
{
  lcd.begin(16,2);                              //  setting LCD as 16x2 type
  lcd.setCursor(0,0);
  lcd.print("CIRCUIT DIGEST");                                   
  lcd.setCursor(0,1);
  lcd.print("ArduinoInterrupt");
  delay(3000);                                                   
  lcd.clear();                                                   
  pinMode(13,OUTPUT);                                         
                                 
  attachInterrupt(digitalPinToInterrupt(2),buttonPressed1,RISING);  //  function for creating external interrupts at pin2 on Rising (LOW to HIGH)
  attachInterrupt(digitalPinToInterrupt(3),buttonPressed2,RISING);  //  function for creating external interrupts at pin3 on Rising (LOW to HIGH) 
 
}
void loop()                                                     

  lcd.clear();                                                 
  lcd.print("COUNTER:");                                         
  lcd.print(i);                                                 
  ++i;                                                           
  delay(1000); 
  digitalWrite(13,output);    //Turns LED ON or OFF depending upon output value
}
void buttonPressed1()          //ISR function excutes when push button at pinD2 is pressed
{                   
  output = LOW;                //Change Output value to LOW                               
  lcd.setCursor(0,1);                                         
  lcd.print("Interrupt 1");
}
void buttonPressed2()          //ISR function excutes when push button at pinD3 is pressed                           
{                   
  output = HIGH;              //Change Output value to HIGH                                   
  lcd.setCursor(0,1);                                         
  lcd.print("Interrupt2");
}


الوصف :

1- فى البداية ً يتم تضمين ملف الرأس لشاشة LCD ومن ثم يتم تعريف أطراف LCD المستخدمة في الاتصال مع الاردوينو .أيضا يتم إعلان المتغيرات . لاحظ إلان المتغير output المستخدم بروتين خدمة المقاطعة باعتباره volatile .

الكود:
#include<LiquidCrystal.h>                       
LiquidCrystal lcd (7,8,9,10,11,12); // Define LCD display pins RS, E, D4, D5, D6, D7

volatile int output = LOW;                     
int i = 0;

2- داخل الدالة setup ، يتم عرض بعد الرسائل الافتتاحية على شاشة LCD .

الكود:
 void setup()                                                     
{
  lcd.begin(16,2);                              //  setting LCD as 16x2 type

  lcd.setCursor(0,0);
  lcd.print("CIRCUIT DIGEST");
                                   
  lcd.setCursor(0,1);
  lcd.print("ArduinoInterrupt");

  delay(3000);
                                                   
  lcd.clear();
                                                 
  pinMode(13,OUTPUT);                                         
                                 
  attachInterrupt(digitalPinToInterrupt(2),buttonPressed1,RISING);  //  function for creating external interrupts at pin2 on Rising (LOW to HIGH)
  attachInterrupt(digitalPinToInterrupt(3),buttonPressed2,RISING);  //  function for creating external interrupts at pin3 on Rising (LOW to HIGH) 
 
}

3- ثم في نفس الدالة setup يجب تحديد أطراف الدخل والخرج . يتم توصيل الطرف D13 بأنود الليد LED ، لذلك يجب تعريف هذا الطرف على أنه خرج .

الكود:
pinMode(13,OUTPUT);

4- الآن الجزء الرئيسي المهم في البرمجة هو الدالة attachInterrupt() ، ويتم تضمينها أيضا داخل الدالة setup .

الكود:
attachInterrupt(digitalPinToInterrupt(2),buttonPressed1,RISING);  //  function for creating external interrupts at pin2 on Rising (LOW to HIGH)
  attachInterrupt(digitalPinToInterrupt(3),buttonPressed2,RISING);  //  function for creating external interrupts at pin3 on Rising (LOW to HIGH) 


هنا ، يتم تحديد أن الطرف 2 هو للمقاطعة الخارجية ، ويتم استدعاء الدالة buttonPressed1 عندما يكون هناك RISING (LOW to HIGH) عند D2. والطرف 3 هو أيضًا للمقاطعة الخارجية ويتم استدعاء الدالة buttonPressed2 عندما يكون هناك RISING على الطرف D3.

5- داخل الدالة loop ، يتم زيادة العدد (i) من الصفر وطباعته على شاشة LCD(16x2) .

الكود:
void loop()                                                     

  lcd.clear();                                                 
  lcd.print("COUNTER:");                                         
  lcd.print(i);                                                 
  ++i;                                                           
  delay(1000); 
  digitalWrite(13,output);    //Turns LED ON or OFF depending upon output value
}

في نفس الدالة loop ، يتم استخدام الدالة digitalWrite على الطرف D13 حيث يتم توصيل أنود الليد LED. اعتمادًا على قيمة المتغير output، سيتم تشغيل الليد LED أو إيقاف تشغيله .

الكود:
 digitalWrite(13,output);    //Turns LED ON or OFF depending upon output value

6- الجزء الأكثر أهمية هو إنشاء دالة معالج المقاطعة وفقًا للاسم المستخدم في الدالة attachInterrupt.
نظرا لأنه تم استخدام أطراف المقاطعة 2 و 3 لذلك مطلوب اثنين ISR كما يلى :

الكود:
void buttonPressed1()          //ISR function excutes when push button at pinD2 is pressed
{                   
  output = LOW;                //Change Output value to LOW                               
  lcd.setCursor(0,1);                                         
  lcd.print("Interrupt 1");
}

يتم تنفيذ هذه الدالة عند الضغط على زر الضغط على الطرف D2 (RISING EDGE) . تعمل هذه الدالة على تغيير حالة الخرج إلى LOW مما يؤدي إلى إيقاف تشغيل الليد LED وطباعة “interrupt1” على شاشة LCD.


الكود:
void buttonPressed2()          //ISR function executes when push button at pinD3 is pressed                           
{                   
  output = HIGH;              //Change Output value to HIGH                                   
  lcd.setCursor(0,1);                                         
  lcd.print("Interrupt2");
}

يتم تنفيذ هذه الدالة عند الضغط على زر الضغط على الطرف D3. تعمل هذه الدالة على تغيير حالة output إلى HIGH مما يؤدي إلى تشغيل الليد LED وطباعة “interrupt2” على شاشة LCD.

Admin
Admin

عدد المساهمات : 1194
تاريخ التسجيل : 28/01/2014

https://fathallaabdelaziz.forumarabia.com

الرجوع الى أعلى الصفحة اذهب الى الأسفل

تدريبات ومشاريع الأردوينو Arduino Tutorials and Projects  - صفحة 4 Empty الاردوينو والمهام المتعددة Multitasking وكيفية استخدام الدالة millis()

مُساهمة من طرف Admin الأحد فبراير 23, 2020 8:15 pm

الاردوينو والمهام المتعددة Multitasking وكيفية استخدام الدالة millis()

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

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

تدريبات ومشاريع الأردوينو Arduino Tutorials and Projects  - صفحة 4 04BEEF8607F14E82A812451C2FCAA7E1

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


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

لماذا استخدام الدالة millis() ؟
للتغلب على المشكلة الناتجة عن التأخير ، يجب على المبرمج استخدام الدالة millis() والتي هي سهلة الاستخدام بمجرد أن تصبح معتادا عليها ، وسوف تستخدم أداء وحدة المعالجة المركزية بنسبة 100 ٪ دون توليد أي تأخير في تنفيذ التعليمات. الدالة millis() هي دالة تقوم فقط بإرجاع مقدار المللي ثانية التي انقضت منذ بدأت لوحة Arduino في تشغيل البرنامج الحالي دون تجميد البرنامج. سيتم تجاوز overflow هذا الرقم الزمني (أي العودة إلى الصفر) ، بعد حوالي 50 يومًا.
تماما مثل ما أن الاردوينو لها الدالة delayMicroseconds() ، فإن لديه النسخة micro من الدالة millis() وهى micros() . الفرق بين micros و millis هو أنه سيتم تجاوز micros() بعد حوالي 70 دقيقة ، مقارنة مع millis() وهو 50 يومًا. بناءً على التطبيق ، يمكنك استخدام millis() أو micros() .

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

الكود:
unsigned long currentMillis = millis();

نحتاج إلى متغيرين آخرين لمعرفة ما إذا كان الوقت المطلوب قد مر. لقد قمنا بتخزين الوقت الحالي في المتغير currentMillis ، لكننا نحتاج أيضًا إلى معرفة متى بدأت فترة التوقيت ومدة هذه الفترة. لذلك يتم الإعلان عن period و PreviousMillis. سيخبرنا الفاصل الزمني بالتأخير الزمني وسيخزن PreviousMillis آخر مرة حدث فيها الحدث.

الكود:
unsigned long previousMillis;
unsigned long period = 1000;

لفهم ذلك ، دعنا نأخذ مثالاً على وميض ليد LED بسيط. ستخبرنا period = 1000 بأن الليد LED سوف يومض لمدة ثانية واحدة أو 1000 مللي ثانية.

تدريبات ومشاريع الأردوينو Arduino Tutorials and Projects  - صفحة 4 45C23C0FCB8446EE87BBDBFECF9CE072


الكود:
const int ledPin =  4; // the LED pin number connected
int ledState = LOW;            // used to set the LED state
unsigned long previousMillis = 0;  //will store last time LED was blinked
const long period = 1000;        // period at which to blink in ms

void setup() {
  pinMode(ledPin, OUTPUT); // set ledpin as output
}

void loop() {
 unsigned long currentMillis = millis(); // store the current time
  if (currentMillis - previousMillis >= period) { // check if 1000ms passed
  previousMillis = currentMillis;  // save the last time you blinked the LED
  if (ledState == LOW) { // if the LED is off turn it on and vice-versa
    ledState = HIGH;
  } else {
ledState = LOW;
}
  digitalWrite(ledPin, ledState);//set LED with ledState to blink again
 }
}


هنا العبارة <if (currentMillis - previousMillis >= period)> تتحقق من ما إذا مر 1000ms . إذا مر 1000ms ، عندئذ يومض الليد ومرة أخرى يأتى إلى نفس الحالة ، ويستمر ذلك . هذا كل شيء ، لقد تعلمنا استخدام millis بدلاً من delay . هذه الطريقة لن توقف البرنامج لفترة زمنية محددة.
المقاطعات Interrupts في الاردوينو تعمل كما هو الحال في الميكروكنترولر الأخرى. تحتوي لوحة Arduino UNO على طرفين منفصلين لتوصيل المقاطعات هى الطرف 2 والطرف 3 . راجع المقاطعة فى الاردوينو.
سنقوم هنا بعرض المهام المتعددة للاردوينو من خلال التعامل مع مهمتين في نفس الوقت. ستشمل المهام وميض اثنين من الليدات في تأخير زمني مختلف جنبا إلى جنب مع زر ضغط الذي سيتم استخدامه للتحكم على حالة ON / OFF لليد . لذلك سيتم تنفيذ ثلاث مهام في وقت واحد.

الدائرة الكهربية :

تدريبات ومشاريع الأردوينو Arduino Tutorials and Projects  - صفحة 4 223F4E875A0F41728E8D0395FB69E699

برمجة الاردوينو أونو للمهام المتعددة Programming Arduino UNO for Multitasking
تتطلب برمجة الاردوينو أونو للمهام المتعددة فقط المنطق وراء كيفية عمل millis() الموضح أعلاه. يوصى بممارسة وميض ليد باستخدام millis() مرارًا وتكرارًا لجعل المنطق واضحًا ولتجعل نفسك مرتاحًا مع millis() قبل البدء في برمجة الاردوينو أونو للقيام بمهام متعددة. في هذا التدريب ، يتم استخدام المقاطعة أيضًا مع millis() في وقت واحد من أجل تعدد المهام. الزر سيكون مقاطعة. لذلك كلما تم توليد مقاطعة ، مثل الضغط على زر ، سوف يتحول الليد وضع التشغيل on أو إيقاف التشغيل off .
1- فى بداية البرنامج :
• يتم إعلان أرقام الأطراف حيث يتم توصيل الليدات والزر الضاغط .

الكود:
int led1 =  6;
int led2 =  7;
int toggleLed = 5;
int pushButton = 2;

• بعد ذلك نعلن عن متغيرًات لتخزين حالة الليدات للاستخدام المستقبلي.

الكود:
int ledState1 = LOW;
int ledState2 = LOW;

• تمامًا كما هو موضح أعلاه في مثال الوميض ، يتم إعلان المتغيرات period و previousmillisللمقارنة وتوليد التأخير لليدات . يومض الليد الأول بعد كل ثانية ويومض الليد الثانى بعد كل 200 مللي ثانية.

الكود:
unsigned long previousMillis1 = 0;
const long period1 = 1000;

unsigned long previousMillis2 = 0;
const long period2 = 200;

• كما يتم استخدام دالة millis لتوليد تأخير منع تأثير الارتداد debounce لتجنب الضغطات المتعددة لزر الضغط.

الكود:
int debouncePeriod = 20; 
int debounceMillis = 0;
 
• ويتم استخدام ثلاثة متغيرات لتخزين حالة زر الضغط كمقاطعة ، وليد التبديل toggle LED وحالة زر الضغط.

الكود:
 bool buttonPushed = false;
int ledChange = LOW; 
int lastState = HIGH;

2- فى الدالة setup :
• يتم تحديد (تعريف) عمل الطرف الذي سيعمل كدخل أو كخرج .

الكود:
pinMode(led1, OUTPUT);           
pinMode(led2, OUTPUT);
pinMode(toggleLed, OUTPUT);
pinMode(pushButton, INPUT);

• كما يتم تحديد (تعريف) طرف المقاطعة عن طريق ربط attaching المقاطعة مع تعريف ISR ووضع Mode المقاطعة. لاحظ أنه يوصى باستخدام digitalPinToInterrupt(pin_number) عند إعلان الدالة attachInterrupt() لترجمة الرقم الرقمي الفعلي إلى رقم المقاطعة المحدد.

الكود:
attachInterrupt(digitalPinToInterrupt(pushButton), pushButton_ISR, CHANGE);

3- تتم كتابة روتين خدمة المقاطعة وسيؤدي فقط إلى تغيير العلم buttonPushed. لاحظ أن روتين خدمة المقاطعة يجب أن يكون قصيرا قدر الإمكان.

الكود:
void pushButton_ISR()
{
  buttonPushed = true;
}

4- تبدأ الدالة loop بتخزين قيمة millis في المتغير CurrentMillis والذي سيخزن قيمة الوقت المنقضي في كل مرة تتكرر فيها الحلقة.

الكود:
unsigned long currentMillis = millis();

يوجد ثلاث مهام متعددة ، وميض ليد عند كل ثانية ، ووميض ليد ثانى كل 200 مللي ثانية ، وإذا تم الضغط على زر الضغط ، يتم تبديل تشغيل/إيقاف ON / OFF ليد ثالث . لذلك سوف نكتب ثلاثة أجزاء للقيام بهذه المهمة.
• المهمة الأولى هى تبديل حالة LED بعد كل ثانية واحدة من خلال مقارنة millis المنقضي.

الكود:
if (currentMillis - previousMillis1 >= period1) {
    previousMillis1 = currentMillis; 
    if (ledState1 == LOW) {
      ledState1 = HIGH;
    } else {
      ledState1 = LOW;
    }
    digitalWrite(led1, ledState1); 
  }

• المهمة الثانية ، وبشكل مشابه ، يتم تبديل ليد بعد كل 200 مللي ثانية من خلال مقارنة millis المنقضي.

الكود:
if (currentMillis - previousMillis2 >= period2) {
    previousMillis2 = currentMillis; 
    if (ledState2 == LOW) {
      ledState2 = HIGH;
    } else {
      ledState2 = LOW;
    }
    digitalWrite(led2, ledState2);
  }

• المهمة الثالثة ، أخيرًا ، يتم مراقبة العلم buttonPushed وبعد إنشاء تأخير إلغاء الارتداد 20 مللي ثانية ، فقط يتم تبديل حالة الليد LED التي تتوافق مع زر الضغط المرفق كمقاطعة.

الكود:
  if (buttonPushed = true)    // check if ISR is called
  {
    if ((currentMillis - debounceMillis) > debouncePeriod && buttonPushed)  // generate 20ms debounce delay to avoid multiple presses
    {
      debounceMillis = currentMillis;      // save the last debounce delay time
      if (digitalRead(pushButton) == LOW && lastState == HIGH)    // change the led after push button is pressed
      {
        ledChange = ! ledChange;
        digitalWrite(toggleLed, ledChange); 
        lastState = LOW;
      }
      else if (digitalRead(pushButton) == HIGH && lastState == LOW)   
      {
        lastState = HIGH;
      }
    buttonPushed = false;
    }
  }

البرنامج :

الكود:
/* Arduino Multitasking
    Author : CircuitDigest (circuitdigest.com)
*/
int led1 =  6;      // led1 connected at pin 6
int led2 =  7;      // led2 connected at pin 7
int toggleLed = 5;    // push button controlled led connected at pin 5
int pushButton = 2;    // push button connected at pin 2 which is also interrupt pin
int ledState1 = LOW;  // to determine the states of led1 and led2
int ledState2 = LOW;
unsigned long previousMillis1 = 0;  //store last time LED1 was blinked
const long period1 = 1000;        // period at which led1 blinks in ms
unsigned long previousMillis2 = 0;  //store last time LED2 was blinked
const long period2 = 200;            // period at which led1 blinks in ms
int debouncePeriod = 20;            // debounce delay of 20ms
int debounceMillis = 0;            // similar to previousMillis
bool buttonPushed = false;    // interrupt routine button status
int ledChange = LOW;      // to track the led status last
int lastState = HIGH;    // to track last button state

void setup() {
  pinMode(led1, OUTPUT);              // define pins as input or output
  pinMode(led2, OUTPUT);
  pinMode(toggleLed, OUTPUT);
  pinMode(pushButton, INPUT);
  attachInterrupt(digitalPinToInterrupt(pushButton), pushButton_ISR, CHANGE);  // use interrupt pin2
}

void pushButton_ISR()
{
  buttonPushed = true;  // ISR should be as short as possible
}

void loop() {
  unsigned long currentMillis = millis(); // store the current time

  if (currentMillis - previousMillis1 >= period1) {    // check if 1000ms passed
    previousMillis1 = currentMillis;  // save the last time you blinked the LED
    if (ledState1 == LOW) {  // if the LED is off turn it on and vice-versa
      ledState1 = HIGH;  //change led state for next iteration
    } else {
      ledState1 = LOW;
    }
    digitalWrite(led1, ledState1);    //set LED with ledState to blink again
  }

  if (currentMillis - previousMillis2 >= period2) { // check if 1000ms passed
    previousMillis2 = currentMillis;  // save the last time you blinked the LED
    if (ledState2 == LOW) { // if the LED is off turn it on and vice-versa
      ledState2 = HIGH;
    } else {
      ledState2 = LOW;
    }
    digitalWrite(led2, ledState2);//set LED with ledState to blink again
  }

  if (buttonPushed = true)    // check if ISR is called
  {
    if ((currentMillis - debounceMillis) > debouncePeriod && buttonPushed)  // generate 20ms debounce delay to avoid multiple presses
    {
      debounceMillis = currentMillis;      // save the last debounce delay time
      if (digitalRead(pushButton) == LOW && lastState == HIGH)    // change the led after push button is pressed
      {
        ledChange = ! ledChange;
        digitalWrite(toggleLed, ledChange);   
        lastState = LOW;
      }
      else if (digitalRead(pushButton) == HIGH && lastState == LOW)   
      {
        lastState = HIGH;
      }
      buttonPushed = false;
    }
  }
}

 

Admin
Admin

عدد المساهمات : 1194
تاريخ التسجيل : 28/01/2014

https://fathallaabdelaziz.forumarabia.com

الرجوع الى أعلى الصفحة اذهب الى الأسفل

تدريبات ومشاريع الأردوينو Arduino Tutorials and Projects  - صفحة 4 Empty قفل رقمي مشفر بكلمة مرور باستخدام Arduino,Keypad,EEPROM,LCD :

مُساهمة من طرف Admin الثلاثاء مارس 03, 2020 6:44 pm

قفل رقمي مشفر بكلمة مرور باستخدام Arduino,Keypad,EEPROM,LCD :

الدائرة الكهربية :

تدريبات ومشاريع الأردوينو Arduino Tutorials and Projects  - صفحة 4 643097d02fcc443199b8a9016d80c20c

البرنامج :

الكود:

#include <Keypad.h>
#include<LiquidCrystal.h>
#include<EEPROM.h>

LiquidCrystal lcd(A0,A1,A2,A3,A4,A5);//RS,E,D4,D5,D6,D7

const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
char hexaKeys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[ROWS] = {2,3,4,5}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {6,7,8,9};  //connect to the column pinouts of the keypad
//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);


char password[4];// Input password
char pass[4],pass1[4];
char customKey=0;

int i=0;// password  characters counter
int led=12;//Green LED connected to pin 12
int buzzer = 10;//Buzzer connected to pin 10
int relay = 11; //relay connected to pin 11

void setup()
{
  lcd.begin(16,2);

  pinMode(relay, OUTPUT);//Relay output
  pinMode(led, OUTPUT);
  pinMode(buzzer, OUTPUT);

 
  lcd.print(" Electronic ");
  lcd.setCursor(0,1);
  lcd.print(" Keypad Lock ");
  delay(2000);
  lcd.clear();

  lcd.print("Enter Ur Passkey:");
  lcd.setCursor(0,1);

//This part must remove after first run
  for(int j=0;j<4;j++)
    EEPROM.write(j, j+49); //49 = character ‘1’
  for(int j=0;j<4;j++)
    pass[j]=EEPROM.read(j);
}

void loop()
{
  digitalWrite(relay, HIGH);//Key locked

  customKey = customKeypad.getKey();

  if(customKey=='#')
    change();

  if (customKey)
  {
    password[i++]=customKey;// Input password
    lcd.print(customKey);
    beep();
  }

  if(i==4)//No. of input characters
  {
    delay(200);

    for(int j=0;j<4;j++)
      pass[j]=EEPROM.read(j);//Saved password
 
 if(!(strncmp(password, pass,4)))// compare password with pass only the first four characters. returns 0, if both are equal
    { //if match
      digitalWrite(led, HIGH);//Open indication
      beep();
      lcd.clear();

      lcd.print("Passkey Accepted");
      digitalWrite(relay, LOW);//Relay off , lock open
      delay(2000);

      lcd.setCursor(0,1);
      lcd.print("#.Change Passkey");
      delay(2000);
      lcd.clear();

      lcd.print("Enter Passkey:");
      lcd.setCursor(0,1);
      i=0;
      digitalWrite(led, LOW);
    }

    else // if not match
    {
      digitalWrite(relay, HIGH);
      digitalWrite(buzzer, HIGH);
      lcd.clear();
      lcd.print("Access Denied...");
      lcd.setCursor(0,1);
      lcd.print("#.Change Passkey");
      delay(2000);
      lcd.clear();
      lcd.print("Enter Passkey:");
      lcd.setCursor(0,1);
      i=0;
      digitalWrite(buzzer, LOW);
    }//end of if…else
  }//end of if(i==4)
}// end of loop


void change()
{
  int j=0;
  lcd.clear();
  lcd.print("UR Current Passk");
  lcd.setCursor(0,1);

  while(j<4)
  {
    char key=customKeypad.getKey();

    if(key)
    {
      pass1[j++]=key;
      lcd.print(key);
      beep();
    }//end if

    key=0;
  }//end while

  delay(500);

  if((strncmp(pass1, pass, 4)))
  {
    lcd.clear();
    lcd.print("Wrong Passkey...");
    lcd.setCursor(0,1);
    lcd.print("Better Luck Again");
    delay(1000);
  }

  else
  {
    j=0;
    lcd.clear();
    lcd.print("Enter New Passk:");
    lcd.setCursor(0,1);

    while(j<4)
    {
      char key=customKeypad.getKey();

      if(key)
      {
        pass[j]=key;
        lcd.print(key);
        EEPROM.write(j,key);
        j++;
        beep();
      }//end if

    }//end while

    lcd.print(" Done......");
    delay(1000);
  }//end else

  lcd.clear();
  lcd.print("Enter Ur Passk:");
  lcd.setCursor(0,1);

  customKey=0;

} // end of void change

void beep()
{
  digitalWrite(buzzer, HIGH);
  delay(20);
  digitalWrite(buzzer, LOW);
}


Admin
Admin

عدد المساهمات : 1194
تاريخ التسجيل : 28/01/2014

https://fathallaabdelaziz.forumarabia.com

الرجوع الى أعلى الصفحة اذهب الى الأسفل

تدريبات ومشاريع الأردوينو Arduino Tutorials and Projects  - صفحة 4 Empty رد: تدريبات ومشاريع الأردوينو Arduino Tutorials and Projects

مُساهمة من طرف Admin الثلاثاء مارس 03, 2020 6:51 pm

تفاصيل البرنامج :

أولا : مقدمة (رأس) البرنامج :
1- يتم تضمين #include ملفات الرأس للمكتبات Keypad.h و LiquidCrystal.h و EEPROM.h .
2- إنشاء الكائن lcd من الفئة LiquidCrystal مع تحديد أطراف توصيل LCD بالاردوينو (9,8,7,6,5,4) .
3- تعريفات لوحة المفاتيح وتشمل : عدد الصفوف ROWS ، وعدد الأعمدة COLS ، والأحرف المستخدمة hexaKeys ، وأطراف توصيل الصفوف rowPins ، وأطراف توصيل الأعمدة colPins ، وأخيرا إنشاء الكائن customKeypad من الفئة Keypad بالوسائط hexaKeys و rowPins و colPins و ROWS و COLS .
4- إعلان المتغيرات العمومية Global المستخدمة فى البرنامج .


الكود:

#include <Keypad.h>
#include<LiquidCrystal.h>
#include<EEPROM.h>

LiquidCrystal lcd(A0,A1,A2,A3,A4,A5);//RS,E,D4,D5,D6,D7

const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
char hexaKeys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[ROWS] = {2,3,4,5}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {6,7,8,9};  //connect to the column pinouts of the keypad
//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);


char password[4];// Input password
char pass[4],pass1[4];
char customKey=0;

int i=0;// password  characters counter
int led=12;//Green LED connected to pin 12
int buzzer = 10;//Buzzer connected to pin 10
int relay = 11; //relay connected to pin 11
 

ثانيا : دالة الإعداد setup :
1- تهيئة شاشة LCD بالدالة lcd.begin .
2- تحديد وضع الأطراف relay و led و buzzer كمخارج OUTPUT .
3- طباعة رسالة افتتاحية : Electronic فى السطر الأول من الشاشة و Keypad Lock فى السطر الثانى مع تأخير 2 ثانية ومسح الشاشة .
4- طباعة العبارة Enter Ur Passkey: فى السطر الأول ، ثم وضع المؤشر على أول السطر الثانى (0,1) تمهيدا لطباعة كلمة المرور المدخلة من لوحة المفاتيح .
5- سوف نستخدم EEPROM الخاص بالاردوينو لحفظ كلمة المرور ، لذلك عندما نقوم بتشغيل هذه الدائرة لأول مرة ، يقرأ البرنامج البيانات النفايات garbage من EEPROM الخاص بالاردوينو ومقارنتها بكلمة مرور الإدخال وإعطاء رسالة على شاشة LCD تم رفض الوصول Access Denied بسبب عدم مطابقة كلمة المرور. لحل هذه المشكلة ، نحتاج إلى تعيين كلمة مرور افتراضية لأول مرة باستخدام البرمجة الواردة أدناه:

الكود:
for(int j=0;j<4;j++)
    EEPROM.write(j, j+49); //49 = character ‘1’
  for(int j=0;j<4;j++)
    pass[j]=EEPROM.read(j);

سيؤدي هذا إلى ضبط كلمة المرور على "1234" على EEPROM للاردوينو وتخزينها فى المصفوفة pass .
بعد تشغيل البرنامج لأول مرة ، نحتاج إلى إزالة هذا الجزء من البرنامج ثم كتابة الكود مرة أخرى فى الاردوينو وتشغيله. الآن سوف يعمل نظامك بشكل جيد. كلمة المرور المستخدمة الآن هى "1234". يمكنك الآن تغييرها عن طريق الضغط على الزر # ثم إدخال كلمة المرور الحالية ثم إدخال كلمة المرور الجديدة.



الكود:
void setup()
{
  lcd.begin(16,2);

  pinMode(relay, OUTPUT);//Relay output
  pinMode(led, OUTPUT);
  pinMode(buzzer, OUTPUT);

 
  lcd.print(" Electronic ");
  lcd.setCursor(0,1);
  lcd.print(" Keypad Lock ");
  delay(2000);
  lcd.clear();

  lcd.print("Enter Ur Passkey:");
  lcd.setCursor(0,1);

//This part must remove after first run
  for(int j=0;j<4;j++)
    EEPROM.write(j, j+49); //49 = character ‘1’
  for(int j=0;j<4;j++)
    pass[j]=EEPROM.read(j);
}

ثالثا : الدالة loop :
1- فى البداية يتم تشغيل relay ليقوم بالغلق .
2- باستخدام الدالة getKey نحصل على الحرف المقابل للزر الذى تم الضغط عليه وتخزينه فى المتغير customKey
3- إذا كان الزر هو المقابل للحرف '#' يتم إستدعاء الدالة change المذكورة بعد الدالة loop .
4- إذا كان الزر أى زر آخر تكون customKey بالقيمة true ويتم تخزين الحرف فى المصفوفة password ثم بعد ذلك زيادة متغير العداد i بواحد مع طباعة الحرف على الشاشة print(customKey) ، واستدعاء الدالة beep لإصدار صفارة عند الضغط على الزر .
5- عندما يصل عداد أحرف كلمة المرور i إلى 4 أى if(i==4) ، بعد تأخير قليل يتم قراءة أحرف كلمة المرور المخزنة فى eeprom وحفظها فى المصفوفة pass >
6- تستخدم الدالة strncmp(password, pass,4) لمقارنة السلسلة password مع السلسلة pass فى مدى الأربع حروف الأولى . إذا حدث تطابق بينهما يكون عائد الدالة “0” ويكون المعكوس بالقيمة true ويتم تنفيذ ما يلى :
أ‌- تشغيل الليد الأخضر لبيان صحة كلمة المرور والتأهل لفتح القفل .
ب‌- إستدعاء الدالة beep لإطلاق صفارة .
ت‌- مسح الشاشة clear .
ث‌- طباعة Passkey Accepted .
ج‌- فصل الريلاى (relay, LOW) مما يؤدى لفتح القفل .
ح‌- التأخير 2 ثانية للسماح بقتح القفل .
خ‌- فى السطر الثانى يتم طباعة #.Change Passkey .
د‌- التأخير 2 ثانية للسماح بتغيير كلمة المرور عند الرغبة .
ذ‌- مسح الشاشة .
ر‌- طباعة Enter Passkey: مرة أخرى ووضع المؤشر على بداية السطر الثانى .
ز‌- تصفير متغير عداد أحرف كلمة المرور i .
س‌- فصل الليد الأخضر لبيان .

إذا لم else تتطابق سلسلة كلمة المرور المدخلة مع سلسلة كلمة المرور المخزنة فى eeprom يتم تنفيذ ما يلى :
أ‌- تأكيد تشغيل الريلاى (الغلق) (relay, HIGH) .
ب‌- تشغيل الصفارة (buzzer, HIGH) .
ت‌- مسح الشاشة clear .
ث‌- طباعة Access Denied... فى السطر الأول .
ج‌- وضع المؤشر على بداية السطر الثانى (0,1) .
ح‌- طباعة #.Change Passkey .
خ‌- التأخير 2 ثانية .
د‌- مسح الشاشة .
ذ‌- كتابة Enter Passkey: فى السطر الأول .
ر‌- وضع المؤشر على بداية السطر الثانى .
ز‌- تصفير متغير عداد أحرف كلمة المرور المدخلة i .
س‌- فصل الصفارة (buzzer, LOW) .


الكود:
 void loop()
{
  digitalWrite(relay, HIGH);//Key locked

  customKey = customKeypad.getKey();

  if(customKey=='#')
    change();

  if (customKey)
  {
    password[i++]=customKey;// Input password
    lcd.print(customKey);
    beep();
  }

  if(i==4)//No. of input characters
  {
    delay(200);

    for(int j=0;j<4;j++)
      pass[j]=EEPROM.read(j);//Saved password
 
 if(!(strncmp(password, pass,4)))// compare password with pass only the first four characters. returns 0, if both are equal
    { //if match
      digitalWrite(led, HIGH);//Open indication
      beep();
      lcd.clear();

      lcd.print("Passkey Accepted");
      digitalWrite(relay, LOW);//Relay off , lock open
      delay(2000);

      lcd.setCursor(0,1);
      lcd.print("#.Change Passkey");
      delay(2000);
      lcd.clear();

      lcd.print("Enter Passkey:");
      lcd.setCursor(0,1);
      i=0;
      digitalWrite(led, LOW);
    }

    else // if not match
    {
      digitalWrite(relay, HIGH);
      digitalWrite(buzzer, HIGH);
      lcd.clear();
      lcd.print("Access Denied...");
      lcd.setCursor(0,1);
      lcd.print("#.Change Passkey");
      delay(2000);
      lcd.clear();
      lcd.print("Enter Passkey:");
      lcd.setCursor(0,1);
      i=0;
      digitalWrite(buzzer, LOW);
    }//end of if…else
  }//end of if(i==4)
}// end of loop

رابعا : الدالة change :
والتى تستدعى عند الضغط على الزر # وفيها يتم :
1- إعلان متغير محلى j كعداد لأحرف كلمة المرور المعدلة مع تعيينه بالقيمة صفر .
2- مسح الشاشة وتبعا لها وضع المؤشر فى بداية السطر الأول .
3- طباعة الرسالة UR Current Passk .
4- وضع المؤشر عند بداية السطر الثانى .
5- إنشاء حلقة while بالشرط j<4 للتكرار 4 مرات ، وفى كل مرة :
أ‌- الحصول على الحرف المقابل للزر المضغوط getKey وحفظه فى المتغير key .
ب‌- التحقق من الحرف if(key) ، وإذا كانت النتيجة true يتم :
• نسخ محتويات المتغير key إلى المصفوفة pass1 ثم زيادة العداد j بواحد .
• طباعة الحرف المقابل للمفتاح key .
• إصدار صفارة عند كل ضغطة على زر.
6- تصفير المتغير key للإعداد للحرف التالى حتى يتم الحصول على 4 أحرف .
7- التأخير 500 مللى ثانية .
8- المقارنة بين السلسلة pass1 (التعديل) والسلسلة pass (المخزنة فى eeprom ) . إذا كان هناك عدم تطابق يتم :
• مسح الشاشة .
• طباعة الرسالة Wrong Passkey... .
• وضع المؤشر عند بداية السطر الثانى .
• طباعة الرسالة Better Luck Again .
• التأخير 1 ثانية .
إما إذا كان هناك تطابق فيتم الآتى (بعد أن تم التأكيد من تطابق كلمة المرور مع كلمة المرور المحفوظة سابقا) :
• إعادة تصفير العداد j .
• مسح الشاشة .
• طباعة الرسالة Enter New Passk: .
• وضع المؤشر عند بداية السطر الثانى .
• إنشاء حلقة while بالشرط j<4 للتكرار 4 مرات وفى كل مرة يتم :
1- الحصول على الحرف المقابل للزر المضغوط وحفظه فى المتغير key .
2- اختبار حالة المتغير key فإذا كانت النتيجة true يتم :
• نسخ محتويات المتغير key إلى المصفوفة pass .
• طباعة الحرف key .
• كتابة write(j,key) الحرف (البايت) key عند العنوان j فى ذاكرة eeprom .
• زيادة متغير العداد j بواحد .
• إصدار صوت الصفارة (بيب) beep عند كل ضغطة على زر .
• التكرار 4 مرات للحصول على كلمة المرور pass المكونة من أربع أحرف .
• طباعة الرسالة Done...... .
• التأخير 1 ثانية .
• مسح الشاشة .
• طباعة الرسالة Enter Ur Passk: .
• وضع المؤشر عند بداية السطر الثانى .
• تصفير المتغير customKey والذى تغير فى loop .


الكود:
void change()
{
  int j=0;
  lcd.clear();
  lcd.print("UR Current Passk");
  lcd.setCursor(0,1);

  while(j<4)
  {
    char key=customKeypad.getKey();

    if(key)
    {
      pass1[j++]=key;
      lcd.print(key);
      beep();
    }//end if

    key=0;
  }//end while

  delay(500);

  if((strncmp(pass1, pass, 4)))
  {
    lcd.clear();
    lcd.print("Wrong Passkey...");
    lcd.setCursor(0,1);
    lcd.print("Better Luck Again");
    delay(1000);
  }

  else
  {
    j=0;
    lcd.clear();
    lcd.print("Enter New Passk:");
    lcd.setCursor(0,1);

    while(j<4)
    {
      char key=customKeypad.getKey();

      if(key)
      {
        pass[j]=key;
        lcd.print(key);
        EEPROM.write(j,key);
        j++;
        beep();
      }//end if

    }//end while

    lcd.print(" Done......");
    delay(1000);
  }//end else

  lcd.clear();
  lcd.print("Enter Ur Passk:");
  lcd.setCursor(0,1);

  customKey=0;

} // end of void change


خامسا : الدالة beep
وفيها يتم تشغيل الصفارة ، والتأخير 20 مللى ثانية ، ثم فصل الصفارة .

الكود:
void beep()
{
  digitalWrite(buzzer, HIGH);
  delay(20);
  digitalWrite(buzzer, LOW);
}


Admin
Admin

عدد المساهمات : 1194
تاريخ التسجيل : 28/01/2014

https://fathallaabdelaziz.forumarabia.com

الرجوع الى أعلى الصفحة اذهب الى الأسفل

تدريبات ومشاريع الأردوينو Arduino Tutorials and Projects  - صفحة 4 Empty مقياس تردد باستخدام الاردوينو

مُساهمة من طرف Admin الخميس مارس 05, 2020 6:30 pm

مقياس تردد باستخدام الاردوينو :
الدائرة الكهربية


تدريبات ومشاريع الأردوينو Arduino Tutorials and Projects  - صفحة 4 0f8042b564614285a38db0fe3b673356

يحتوي الاردوينو على دالة خاصة pulseIn ، والتي تمكننا من تحديد مدة duration الحالة الموجبة أو مدة الحالة السالبة لموجة مستطيلة معينة :

الكود:
Htime = pulseIn(8,HIGH);
Ltime = pulseIn(8, LOW);

تقيس الدالة الوقت الذي يوجد فيه المستوى المرتفع High أو المنخفض Low الموجود على الطرف 8 من الاردوينو . لذلك في دورة واحدة من الموجة ، سيكون لدينا مدة للمستوى الموجب Htime ومدة للمستوى السالب Ltime بالميكروثانية . الدالة pulseIn تقيس الوقت بالميكروثانية . في إشارة معينة ، نفترض أن لدينا وقت مرتفع Htime وليكن 10ms ووقت منخفض Ltime وليكن 30ms ويكون زمن الدورة 10+30=40ms ، ويكون التردد 1000/40 = 25 Hz . سيتم تخزين 30000 في العدد الصحيح Ltime و 10000 في Htime. عندما نضيفهم معًا ، سنحصل على مدة الدورة ، ومن خلال المعكوس (المقلوب) سنحصل على التردد.

البرنامج :


الكود:

#include <LiquidCrystal.h>
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
int Htime;              //integer for storing high time
int Ltime;                //integer for storing low time
float Ttime;            // integer for storing total time of a cycle
float frequency;        //storing frequency
void setup()
{
    pinMode(8,INPUT);
    lcd.begin(16, 2);
}
void loop()
{
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Frequency : ");
    Htime=pulseIn(8,HIGH);      //read high time
    Ltime=pulseIn(8,LOW);        //read low time
   
    Ttime = Htime+Ltime;
    frequency=1000000/Ttime;    //getting frequency with Ttime is in Micro seconds
    lcd.setCursor(0,1);
    lcd.print(frequency);
    lcd.print(" Hz");
    delay(500);
}
 

Admin
Admin

عدد المساهمات : 1194
تاريخ التسجيل : 28/01/2014

https://fathallaabdelaziz.forumarabia.com

الرجوع الى أعلى الصفحة اذهب الى الأسفل

تدريبات ومشاريع الأردوينو Arduino Tutorials and Projects  - صفحة 4 Empty عمل كاشف الموجات فوق الصوتية Ultrasonic Sensor HC-SR04 مع الاردوينو ومشروع متحكم

مُساهمة من طرف Admin الخميس مارس 12, 2020 7:23 pm

عمل كاشف الموجات فوق الصوتية Ultrasonic Sensor HC-SR04 مع الاردوينو ومشروع متحكم فى مستوى المياه بخزان .

ما هى الموجات فوق الصوتية؟
الموجات فوق الصوتية هي موجات صوت عالية النبرة high-pitched بترددات أعلى من الحد المسموع audible limit لسمع الإنسان.

تدريبات ومشاريع الأردوينو Arduino Tutorials and Projects  - صفحة 4 Cc13274a3e40488d8d13128fb99fda55

يمكن أن تسمع آذان الإنسان موجات صوتية تهتز في النطاق من حوالي 20 مرة في الثانية (ضجيج هدير عميق) إلى حوالي 20000 مرة في الثانية (صفير عالي النبرة). ومع ذلك ، فإن الموجات فوق الصوتية لديها تردد أعلا من 20،000 هرتز ، وبالتالي تكون غير مسموعة للبشر.


نبذة عن الحساس HC-SR04 :
في جوهره ، يتكون مستشعر المسافة بالموجات فوق الصوتية HC-SR04 من محوِّلين للموجات فوق الصوتية ultrasonic transducers . يعمل أحدهما كجهاز إرسال يحول الإشارة الكهربائية إلى نبضات صوت فوق صوتية بتردد 40 كيلو هرتز. يستمع (يستقبل) المستقبل النبضات المرسلة. إذا استقبلها ، فإنه ينتج نبضة خرج يمكن استخدام عرضها لتحديد المسافة التي قطعتها النبضة.
المستشعر صغير وسهل الاستخدام في أي مشروع روبوتات ويوفر كشفًا ممتازًا عن مدى عدم التلامس بين 2 سم إلى 400 سم بدقة 3 مم. نظرًا لأنه يعمل على 5 فولت ، يمكن توصيله مباشرةً بأردوينو أو أي ميكروكنترولر 5V آخر.

المواصفات :
• جهد التشغيل : DC 5V .
• تيار التشغيل : 15mA .
• تردد التشغيل : 40KHz .
• أقصى مدى : 4m .
• أدنى مدى : 2cm .
• دقة المدى : 3mm .
• زاوية القياس : 15 degree .
• إشارة دخل البدء Trigger : 10Us TTL pulse .
• الأبعاد : 45 x 20 x 15 mm .

أطراف الحساس :

تدريبات ومشاريع الأردوينو Arduino Tutorials and Projects  - صفحة 4 82c59e2b0e094da68e9b57845d5139dd

• الطرف VCC هو طرف مصدر القدرة للحساس والذى يتم توصيله بطرف 5V للاردوينو .
• الطرف Trig(Trigger) ويستخدم لبدء (قدح) trigger النبضات فوق الصوتية .
• الطرف Echo وينتج نبضة pulse عندما يتم استقبال إشارة منعكسة . طول النبضة يتناسب مع الزمن الذى أخذه من أجل كشف الإشارة المرسلة (زمن الإرسال + زمن الاستقبال) .
• الطرف GND يجب توصيله بأرضى الاردوينو .

مبدأ العمل :
يبدأ العمل ، عندما يتم تطبيق نبضة بعرض duration لا يقل عن 10 µS (10 microseconds) على طرف البدء Trigger . استجابة لذلك يرسل الحساس سلسلة نبضات مكونة من ثماني نبضات عند تردد 40 كيلو هرتز 40 KHz . هذا النمط ذو 8 نبضات يشكل "بصمة الموجات فوق الصوتية" من الجهاز بشكل فريد ، مما يسمح للمستقبل بتمييز النمط المرسل عن الضوضاء فوق الصوتية المحيطة.
تنتقل النبضات الثمانية الفوق صوتية عبر الهواء مبتعدة عن جهاز الإرسال. في هذه الأثناء يصبح الطرف Echo فى الحالة HIGH للبدء في تشكيل بداية إشارة ارتداد الصدى.
في حالة ، إذا لم تنعكس هذه النبضات مرة أخرى ، فستنتهي إشارة الصدى بعد 38 مللي ثانية وتعود إلى المستوى المنخفض low . وبالتالي ، فإن نبضة 38 مللي ثانية تشير إلى عدم وجود أي عوائق داخل نطاق المستشعر.

تدريبات ومشاريع الأردوينو Arduino Tutorials and Projects  - صفحة 4 HC-SR04-Ultrasonic-Sensor-Working-Echo-when-no-Obstacle
تدريبات ومشاريع الأردوينو Arduino Tutorials and Projects  - صفحة 4 E8ecd03d8e6646b78a027d9d5be85ac1

إذا إنعكست هذه النبضات مرة أخرى ، يصبح الطرف Echo منخفضا low بمجرد استلام الإشارة. ينتج عن ذلك نبضة يتراوح عرضها بين 150 µS إلى 25 mS ، اعتمادًا على الوقت الذي يستغرقه استقبال الإشارة.

تدريبات ومشاريع الأردوينو Arduino Tutorials and Projects  - صفحة 4 HC-SR04-Ultrasonic-Sensor-Working-Echo-reflected-from-Obstacle

تدريبات ومشاريع الأردوينو Arduino Tutorials and Projects  - صفحة 4 60bf5621b10d4de4a49fb26a09225ab7

ثم يتم استخدام عرض النبضة المستقبلة لحساب المسافة إلى كائن الانعكاس . يمكن أن يتم ذلك باستخدام معادلة بسيطة بين المسافة والسرعة الوقت.



لنأخذ مثالاً لجعله أكثر وضوحًا. لنفترض أن لدينا كائنًا أمام المستشعر على مسافة غير معروفة واستقبلنا نبضة بعرض 500 µS على الطرف Echo . الآن دعنا نحسب مدى المسافة الموجودة من المستشعر إلى الكائن . سوف نستخدم المعادلة أدناه.
Distance = Speed x Time
هنا ، لدينا قيمة الوقت ، أي 500 µs ونحن نعرف السرعة. ما السرعة التي لدينا؟ سرعة الصوت ، بالطبع! وهى 340 m/s . يتعين علينا تحويل سرعة الصوت إلى cm/µs من أجل حساب المسافة بالسنتيمتر ، وهى 0.034 cm/µs وبهذه المعلومات ، يمكننا حساب المسافة!
Distance = 0.034 cm/µs x 500 µs
ولكن تذكر أن النبضة تشير إلى الوقت الذي استغرقه إرسال الإشارة وانعكاسها مرة أخرى ، لذلك حتى تحصل على المسافة ، ستحتاج إلى قسمة النتيجة على 2 .
Distance = (0.034 cm/µs x 500 µs) / 2
Distance = 8.5 cm
الآن ، نحن نعلم أن الكائن على بعد 8.5 سم من المستشعر.

تدريبات ومشاريع الأردوينو Arduino Tutorials and Projects  - صفحة 4 6bc6e980cfd7445fa3f1704b7a40c2bf

الخلاصة : ينبعث من الحساس موجات فوق صوتية 40 000 Hz التى تنتقل عبر الهواء وإذا كان هناك جسم أو عقبة (عائق) في طريقها فسوف ترتد إلى وحدة الحساس . وبمعرفة زمن الانتقال وسرعة الصوت يمكنك حساب المسافة.

الدائرة الكهربية :

تدريبات ومشاريع الأردوينو Arduino Tutorials and Projects  - صفحة 4 73dfcb18174646538233fb3166941551

البرمجة :
1- فى البداية عليك تحديد الأطراف Trig و Echo. في هذه الحالة ، نستخدم الأطراف رقم 9 و 10 على لوحة Arduino ويُطلق عليهما اسم trigPin و echoPin. ستحتاج بعد ذلك إلى متغير نوع long يسمى “duration” لزمن الانتقال الذي ستحصل عليه من المستشعر ، ومتغير نوع عدد صحيح للمسافة distance.

الكود:
// defines pins numbers
const int trigPin = 9;
const int echoPin = 10;

// defines variables
long duration;
int distance;
 

2- في دالة الإعداد setup ، يجب عليك تعريف trigPin كمخرج و echoPin كمدخل وكذلك بدء الاتصال التسلسلي لإظهار النتائج على الشاشة التسلسلية.

الكود:
void setup() {
pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT); // Sets the echoPin as an Input
Serial.begin(9600); // Starts the serial communication
}

3- في الدالة loop :
أ‌- فى البداية ، يجب عليك التأكد من مسح clear الطرف trigPin ، لذا يجب عليك ضبط هذا الطرف على حالة LOW لمدة 2 µs فقط .
ب‌- الآن لتوليد موجة فوق صوتية الصوت ، علينا أن نضع الطرف trigPin على الحالة HIGH لمدة 10 µs .
ت‌- باستخدام الدالة pulseIn ، عليك قراءة زمن الانتقال ووضع هذه القيمة في المتغير duration . تحتوي هذه الدالة على وسيطين ، أولهما هو اسم طرف الصدى echo pin والثاني يمكنك كتابة إما HIGH أو LOW . في هذه الحالة ، HIGH تعني أن الدالة pulseIn ستنتظر حتى يبدأ الطرف الحالة HIGH بسبب موجة الصوت المرتد وسيبدأ التوقيت ، ثم ستنتظر أن يصبح الطرف LOW عندما تنتهي موجة الصوت والتي ستوقف التوقيت. في النهاية ، تقوم الدالة بإرجاع طول النبضة بالميكرو ثانية. للحصول على المسافة ، سنضرب الزمن فى 0.034 ونقسمها على 2. في النهاية سنقوم بطباعة قيمة المسافة على الشاشة التسلسلية.

الكود:
void loop() {
// Clears the trigPin
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
   
// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
   
// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin, HIGH);
   
// Calculating the distance
distance= duration*0.034/2;
   
// Prints the distance on the Serial Monitor
Serial.print("Distance: ");
Serial.println(distance);
}
 

البرنامج :

الكود:
//Ultrasonic Sensor HC-SR04 and Arduino Tutorial
// defines pins numbers
const int trigPin = 9;
const int echoPin = 10;

// defines variables
long duration;
int distance;

void setup() {
pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT); // Sets the echoPin as an Input
Serial.begin(9600); // Starts the serial communication
}

void loop() {
// Clears the trigPin
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
   
// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
   
// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin, HIGH);
   
// Calculating the distance
distance= duration*0.034/2;
   
// Prints the distance on the Serial Monitor
Serial.print("Distance: ");
Serial.print(distance);
Serial.println(" CM ");
}
 



إذا كنت ترغب في عرض النتائج من جهاز الاستشعار بالموجات فوق الصوتية HC-SR04 على شاشة LCD ، يمكنك استخدام البرنامج التالى :

تدريبات ومشاريع الأردوينو Arduino Tutorials and Projects  - صفحة 4 E41717467e724b44a62355f92fb32bf9

الكود:

#include <LiquidCrystal.h> // includes the LiquidCrystal Library
   
LiquidCrystal lcd(2, 3, 4, 5, 6, 7); // Creates an LCD object. Parameters: (rs, enable, d4, d5, d6, d7)
   
const int trigPin = 9;
const int echoPin = 10;
   
long duration;
int distanceCm, distanceInch;
   
void setup() {
lcd.begin(16,2); // Initializes the interface to the LCD screen, and specifies the dimensions (width and height) of the display
   
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}
   
void loop() {
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
   
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
   
duration = pulseIn(echoPin, HIGH);
distanceCm= duration*0.034/2;
distanceInch = duration*0.0133/2;
   
lcd.setCursor(0,0); // Sets the location at which subsequent text written to the LCD will be displayed
lcd.print("Distance: "); // Prints string "Distance" on the LCD
lcd.print(distanceCm); // Prints the distance value from the sensor
lcd.print(" cm");
delay(10);
lcd.setCursor(0,1);
lcd.print("Distance: ");
lcd.print(distanceInch);
lcd.print(" inch");
delay(10);
}

 

Admin
Admin

عدد المساهمات : 1194
تاريخ التسجيل : 28/01/2014

https://fathallaabdelaziz.forumarabia.com

الرجوع الى أعلى الصفحة اذهب الى الأسفل

تدريبات ومشاريع الأردوينو Arduino Tutorials and Projects  - صفحة 4 Empty رد: تدريبات ومشاريع الأردوينو Arduino Tutorials and Projects

مُساهمة من طرف Admin الجمعة مارس 13, 2020 11:36 am

مشروع مبين ومتحكم لمستوى (منسوب) المياه تلقائيا فى خزان باستخدام الاردوينو

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

الدائرة الكهربية :

تدريبات ومشاريع الأردوينو Arduino Tutorials and Projects  - صفحة 4 C6c357188bc34e259bdfd56db438ad91


تدريبات ومشاريع الأردوينو Arduino Tutorials and Projects  - صفحة 4 9fe6f7d1a68a41fa95a6e9ca9027ef24


في هذه الدائرة ، يتم وضع وحدة الاستشعار بالموجات فوق الصوتية في الجزء العلوي من خزان المياه . ستقوم وحدة الاستشعار هذه بقراءة المسافة بين وحدة المستشعر وسطح الماء ، وسوف تظهر المسافة على شاشة LCD مع رسالة “Water Space in Tank is:” . هذا يعني أننا نعرض هنا المكان الفارغً بدلاً من مستوى الماء. بسبب هذه الوظيفة ، يمكننا استخدام هذا النظام في أي خزان مياه. عندما يصل مستوى فراغ الماء إلى مسافة حوالي 30 سم ، يقوم Arduino بتشغيل مضخة المياه عن طريق تشغيل الريلاى . وحينها ستعرض شاشة LCD “LOW Water Level” “Motor turned ON” ، وسيبدأ ليد LED بيان حالة الريلاى في التوهج .
الآن إذا وصلت المساحة الفارغة على مسافة حوالي 12 سم ، يقوم اردوينو بإيقاف تشغيل الريلاى التتابع وستظهر شاشة LCD “Tank is full” “Motor Turned OFF” . الصفارة أيضا نعطى صفير لبعض الوقت ويتم فصل ليد بيان حالى الريلاى .

البرمجة :
1- فى بداية (مقدمة) البرنامج :
• يتم تضمين مكتبة LCD .
• تعريف الأطراف المستخدمة فى البرنامج لربط الأجهزة الخارجية مثل الحساس والريلاى والصفارة وشاشة LCD .
• إنشاء كائن من فئة الشاشة وليكن lcd مع تحديد الأطراف المستخدمة .
• إعلان المتغيرات المستخدمة .


الكود:
#include <LiquidCrystal.h>
 
#define trigger 10
#define echo 11
#define motor 8
#define buzzer 12
 
LiquidCrystal lcd(7,6,5,4,3,2);
 
float time=0,distance=0;
int temp=0; 

2- فى دالة الإعداد setup :
• تهيئة الشاشة LCD للعمل وتحديد نوعها 16 حرف (عامود) و 2 سطر (صف) .
• تحديد اتجاه الأطراف المستخدم خرج OUTPUT / دخل INPUT .
• عرض رسالة إفتتاحية Water Level فى السطر الأول و Indicator فى السطر الثانى لمدة (تأخير) 2 ثانية .


الكود:
void setup()
{
 lcd.begin(16,2);

 pinMode(trigger,OUTPUT);
 pinMode(echo,INPUT);
 pinMode(motor, OUTPUT);
 pinMode(buzzer, OUTPUT);

 lcd.print("  Water Level ");
 lcd.setCursor(0,1);
 lcd.print("  Indicator  ");
 delay(2000);
}

3- الدالة loop وفيها يتم :
أ‌- الجزء الأول :
• مسح الشاشة .
• مسح المخرج trigger بجعله فى الحالة المنخفضة لمدة 2 ميكروثانية .
• جعل المخرج trigger فى الحالة المرتفعة لمدة 10 ثوانى حتى يتمكن الحساس من توليد الإشارة الفوق صوتية .
• إعادة مسح المخرج trigger بجعله فى الحالة المنخفضة لمدة 2 ثانية ، حيث يتم إرسال الإشارة فوق الصوتية واستقبالها بعد إنعكاسها من العائق ومن ثم تكوين نبضة مدتها تتناسب مع المسافة إلى العائق .
• الحصول على زمن النبضة time باستخدام الدالة pulseIn ومن ثم يمكن حساب المسافة distance .
• طباعة الرسالة Water Space In فى السطر الأول ، وفى السطر الثانى يتم طباعة Tank is: يليها قيمة المسافة distance ووحداتها Cm ، وذلك لمدة 2 ثانية .


الكود:
void loop()
{
 lcd.clear();
 digitalWrite(trigger,LOW);
 delayMicroseconds(2);

 digitalWrite(trigger,HIGH);
 delayMicroseconds(10);

 digitalWrite(trigger,LOW);
 delayMicroseconds(2);

 time=pulseIn(echo,HIGH);
 distance=time*340/20000;

 //lcd.clear();
 lcd.print("Water Space In  ");
 lcd.setCursor(0,1);
 lcd.print("Tank is: ");
 lcd.print(distance);
 lcd.print("Cm");
 delay(2000);
 

ب‌- الجزء الثانى : عمليات المقارنة للتحكم التلقائى فى منسوب المياة ، وهنايتم تنفيذ واحدة من 3 حالات :
• الحالة الأولى : عندما يصل الخزان إلى حالة الملو إى المسافة أقل من 12 سم ، و (&&) المتغير temp==0 . عندئذ يتم إيقاف المحرك ، وإصدار صفير ، ومسح الشاشة وعرض Water Tank Full فى السطر الأول و Motor Turned OFF ولمدة 2 ثانية ، ثم إيقاف الصفير والانتظار 3 ثانية وأخيرا يتم تحويل المتغير temp=1 .
• الحالة الثانية : عندما يكون الحزان مملوء والمتغير temp==1 يتم : إيقاف المحرك ومسح الشاشة وعرض Water Tank Full و Motor Turned OFF لمدة خمس ثوانى .
• الحالة الثالثة : عندما تكون المسافة أكبر من 30 (بما فى ذلك حالة بدء ملو الخزان) يتم : تشغيل المحرك ، ومسح الشاشة وعرض LOW Water Level و Motor Turned ON والتأخير 5 ثانية وتحويل المتغير temp=0 .


الكود:
 if(distance<12 && temp==0)
 {
    digitalWrite(motor, LOW);
    digitalWrite(buzzer, HIGH);

    lcd.clear();
    lcd.print("Water Tank Full ");
    lcd.setCursor(0,1);
    lcd.print("Motor Turned OFF");
    delay(2000);

    digitalWrite(buzzer, LOW);
    delay(3000);

    temp=1;
 }
 
  else if(distance<12 && temp==1)
 {
    digitalWrite(motor, LOW);

    lcd.clear();
    lcd.print("Water Tank Full ");
    lcd.setCursor(0,1);
    lcd.print("Motor Turned OFF");
    delay(5000);
 }
 
 else if(distance>30)
 {
  digitalWrite(motor, HIGH);

  lcd.clear();
  lcd.print("LOW Water Level");
  lcd.setCursor(0,1);
  lcd.print("Motor Turned ON");
  delay(5000);

  temp=0;
 }

}

البرنامج :

الكود:
 
#include <LiquidCrystal.h>
 
#define trigger 10
#define echo 11
#define motor 8
#define buzzer 12
 
LiquidCrystal lcd(7,6,5,4,3,2);
 
float time=0,distance=0;
int temp=0

void setup()
{
 lcd.begin(16,2);

 pinMode(trigger,OUTPUT);
 pinMode(echo,INPUT);
 pinMode(motor, OUTPUT);
 pinMode(buzzer, OUTPUT);

 lcd.print("  Water Level ");
 lcd.setCursor(0,1);
 lcd.print("  Indicator  ");
 delay(2000);
}

void loop()
{
 lcd.clear();
 digitalWrite(trigger,LOW);
 delayMicroseconds(2);

 digitalWrite(trigger,HIGH);
 delayMicroseconds(10);

 digitalWrite(trigger,LOW);
 delayMicroseconds(2);

 time=pulseIn(echo,HIGH);
 distance=time*340/20000;

 //lcd.clear();
 lcd.print("Water Space In  ");
 lcd.setCursor(0,1);
 lcd.print("Tank is: ");
 lcd.print(distance);
 lcd.print("Cm");
 delay(2000);

if(distance<12 && temp==0)
 {
    digitalWrite(motor, LOW);
    digitalWrite(buzzer, HIGH);
    lcd.clear();
    lcd.print("Water Tank Full ");
    lcd.setCursor(0,1);
    lcd.print("Motor Turned OFF");
    delay(2000);

    digitalWrite(buzzer, LOW);
    delay(3000);

    temp=1;
 }
 
  else if(distance<12 && temp==1)
 {
    digitalWrite(motor, LOW);

    lcd.clear();
    lcd.print("Water Tank Full ");
    lcd.setCursor(0,1);
    lcd.print("Motor Turned OFF");
    delay(5000);
 }
 
 else if(distance>30)
 {
  digitalWrite(motor, HIGH);

  lcd.clear();
  lcd.print("LOW Water Level");
  lcd.setCursor(0,1);
  lcd.print("Motor Turned ON");
  delay(5000);

  temp=0;
 }

}

Admin
Admin

عدد المساهمات : 1194
تاريخ التسجيل : 28/01/2014

https://fathallaabdelaziz.forumarabia.com

الرجوع الى أعلى الصفحة اذهب الى الأسفل

تدريبات ومشاريع الأردوينو Arduino Tutorials and Projects  - صفحة 4 Empty ربط كاشف اللهب Flame Sensor مع الاردوينو لبناء نظام إنذار حريق Fire Alarm System

مُساهمة من طرف Admin السبت مارس 14, 2020 11:48 am

ربط كاشف اللهب Flame Sensor مع الاردوينو لبناء نظام إنذار حريق Fire Alarm System


الدائرة الكهربية :


تدريبات ومشاريع الأردوينو Arduino Tutorials and Projects  - صفحة 4 F40f90e661a1478987f96ab83cbae221


تدريبات ومشاريع الأردوينو Arduino Tutorials and Projects  - صفحة 4 Cdc7e24045694c6a8183e1ef62f6c82a


البرنامج :


الكود:
int buzzer = 8;
int LED = 7;
int flame_sensor = 4;
int flame_detected;

void setup()
{
  Serial.begin(9600);
  pinMode(buzzer, OUTPUT);
  pinMode(LED, OUTPUT);
  pinMode(flame_sensor, INPUT);
}
void loop()
{
  flame_detected = digitalRead(flame_sensor);
  if (flame_detected == 1)
  {
    Serial.println("Flame detected...! take action immediately.");
    digitalWrite(buzzer, HIGH);
    digitalWrite(LED, HIGH);
    delay(200);
    digitalWrite(LED, LOW);
    delay(200);
  }
  else
  {
    Serial.println("No flame detected. stay cool");
    digitalWrite(buzzer, LOW);
    digitalWrite(LED, LOW);
  }
  delay(1000);
}

شرح البرنامج :

1- في مقدمة البرنامج تقوم بتعريف أطراف مستشعر اللهب ، و LED والجرس المرتبطين بالاردوينو Arduino. يتم توصيل مستشعر اللهب بالطرف الرقمي 4 من Arduino. الجرس متصل بالطرف الرقمي 8 من Arduino. يتم توصيل LED بالطرف الرقمي 7 من Arduino.
يستخدم المتغير "flame_detected" لتخزين القيمة الرقمية المقروءة من مستشعر اللهب. بناءً على هذه القيمة سنكتشف وجود اللهب.

الكود:
int buzzer = 8 ;
int LED = 7 ;
int flame_sensor = 4 ;
int flame_detected ;
 

2- فى دالة الإعداد setup يتم تحديد حالة الأطراف الرقمية للاردوينو وتهيئة معدل البود Baud rate لمنفذ الاتصال التسلسلى لعرض حالة دائرة اكتشاف اللهب .

الكود:
void setup()
{
  Serial.begin(9600) ;
  pinMode(buzzer, OUTPUT) ;
  pinMode(LED, OUTPUT) ;
  pinMode(flame_sensor, INPUT) ;
}

3- فى الدالة loop :
أ‌- فى السطر الأول يتم قراءة الخرج الرقمى من حساس اللهب وتخزينه قى المتغير flame_detected :

الكود:
flame_detected = digitalRead(flame_sensor) ;

ب‌- بناء على القيمة المخزنة فى المتغير flame_detected ، علينا تشغيل إو إيقاف الصفارة والليد ، حيث يتم مقارنة هذه القيمة مع 0 أو 1 . إذا كانت تساوى 1 فهذا يشير إلى اكتشاف لهب ، وعلينا تشغيل الصفارة والليد وعرض رسالة على المنفذ التسلسلى . وإذا كانت بصفر ، فهذا يشير إلى عدم اكتشاف لهب ، وعلينا إيقاف الصفارة والليد . هذه العملية تتكرر كل ثانية للتعرف على وجود حريق أو لهب .

الكود:
if (flame_detected == 1)
  {
    Serial.println("Flame detected...! take action immediately.");
    digitalWrite(buzzer, HIGH);
    digitalWrite(LED, HIGH);
    delay(200);
    digitalWrite(LED, LOW);
    delay(200);
  }
  else
  {
    Serial.println("No flame detected. stay cool");
    digitalWrite(buzzer, LOW);
    digitalWrite(LED, LOW);
  }
  delay(1000);
 

Admin
Admin

عدد المساهمات : 1194
تاريخ التسجيل : 28/01/2014

https://fathallaabdelaziz.forumarabia.com

الرجوع الى أعلى الصفحة اذهب الى الأسفل

صفحة 4 من اصل 4 الصفحة السابقة  1, 2, 3, 4

الرجوع الى أعلى الصفحة

- مواضيع مماثلة

 
صلاحيات هذا المنتدى:
لاتستطيع الرد على المواضيع في هذا المنتدى