قسم الميكروكنترولر والروبوت ودوائر الاتصال بالحاسب الالي قسم المتحكمات الـ microcontroller و المعالجات microprocessor و التحكم الرقمي بالكمبيوتر CNC والانظمة الآلية والروبوت Robots

   

الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 30-03-2020, 03:16 PM المشاركة 17   
افتراضي الدرس الثانى عشر العوامل المنطقية Logical Operators :



دورة برمجة الاردوينو : الدرس الثانى عشر
العوامل المنطقية Logical Operators :


يمكن استخدام العوامل المنطقية مع if و if-else لتبسيط وتوسيع عملية صنع القرار.
العوامل المنطقية الثلاثة هي "أو" OR (||) و "و" AND (&&) و "نفى" NOT (!) التي يتم شرحها وتوضيحها في هذا الدرس .

1- العامل المنطقي OR (||) : The OR Logical Operator (||)
يتم كتابة العامل المنطقي OR في البرامج على هيئة الرمز (||) الموجودة على نفس مفتاح الشرطة المائلة للخلف (\) في لوحة المفاتيح . الضغط على Shift + مفتاح الخط المائل للخلف سيكتب هذا الرمز ( || ) .
يوضح البرنامج التالي استخدام العامل المنطقي OR للتحقق من الحروف الأبجدية ، الكبيرة والصغيرة .

كود:
void setup() {
  Serial.begin(9600);
  pinMode(13, OUTPUT);  // LED on pin 13 of UNO
}

void loop() {
  char rx_byte;
  
  if (Serial.available() > 0) {    // is a character available?
    rx_byte = Serial.read();
    if (rx_byte == 'a' || rx_byte == 'A') {
      digitalWrite(13, HIGH);
    }
    else {
      digitalWrite(13, LOW);
    }
  }
}

سيقوم البرنامج لتشغيل الليد على لوحة Arduino Uno إذا تم إرسال الحرف الصغير 'a' أو or الحرف الكبير 'A' من نافذة الشاشة التسلسلية. إذا تم إرسال أي حرف آخر ، يتم إيقاف تشغيل الليد .

• كيف يعمل العامل المنطقي OR
الكود أدناه مأخوذ من البرنامج أعلاه ويعرض العامل المنطقي OR.

كود:
if (rx_byte == 'a' || rx_byte == 'A') {
  digitalWrite(13, HIGH);
}

سيتم تشغيل الكود الموجود في جسم عبارة if إذا كان المتغير rx_byte يحتوي على 'a' أو OR (||) إذا كان يحتوي على 'A'. تم استخدام العامل OR لاختبار حرف أو آخر (A OR a).
يمكن تعديل الكود لتشغيل الليد إذا تم استقبال الحرف 'a' أو الحرف'b' أو الحرف 'c' ، كما يوضح هذا الكود التالي.

كود:
if ((rx_byte == 'a') || (rx_byte == 'b') || (rx_byte == 'c')) {
  digitalWrite(13, HIGH);
}
في الكود أعلاه ، تم وضع كل عامل المقارنة يساوى (==) للمقارنة بين قوسين () لتسهيل قراءة الكود. يؤدي هذا أيضًا إلى تجنب أي سوء فهم بشأن أي عامل يتم تقييمه أولاً (هل يتم تقييم == أو || أولاً؟).
عامل المقارنة == له أسبقية أعلى من العامل المنطقى || مما يعني أن == يتم تقييمه أولاً. الأقواس لها أعلى أسبقية ، لذلك سيتم تقييم أي شيء يوضع بين قوسين أولاً. في هذه الحالة ، ليس من الضروري وضع الأقواس ، ولكنه يسهل القراءة.

2- العامل المنطقي "و" AND (&&) : The AND Logical Operator (&&)
يوضح البرنامج التالي استخدام العامل المنطقي AND. يختبر البرنامج لمعرفة أنه تم استلام تسلسل (تتابع) sequenc من حرفين قبل تشغيل الليد .

كود:
void setup() {
  Serial.begin(9600);
  pinMode(13, OUTPUT);  // LED on pin 13 of UNO
}

char first_char = 0;

void loop() {
  char rx_byte;
  
  if (Serial.available() > 0) {    // is a character available?
    rx_byte = Serial.read();       // read the character
    if ((first_char == 'c') && (rx_byte == 'd')) {
      digitalWrite(13, HIGH);
    }
    else {
      first_char = rx_byte;        // save the character for next comparison
      digitalWrite(13, LOW);
    }
  }
}

في هذا البرنامج ، يجب إرسال حرفين بالترتيب الصحيح لتشغيل الليد LED. يجب أولاً إرسال حرف 'c' متبوعة بحرف 'd'.

• كيف يعمل العامل المنطقى AND :
يظهر العامل AND من البرنامج أعلاه كما يلى .

كود:
 if ((first_char == 'c') && (rx_byte == 'd')) {
  digitalWrite(13, HIGH);
}

سيتم تشغيل الليد LED فقط عندما يحتوي المتغير first_char على 'c' و AND المتغير rx_byte يحتوي على 'd'.
يتم استخدام المتغير first_char لتخزين الحرف الحالي المستقبل بحيث يمكننا في المرة القادمة تقييم العبارة if ، يمكننا أن نرى ما إذا كان متبوعًا بالحرف 'd' وإذا كان يحتوي على 'c'.

3- العامل المنطقى (نفى أو معكوس) NOT : The Logical NOT Operator (!)
يمكن استخدام العامل NOT للتحقق مما إذا كان المتغير يحتوي على القيمة 0 - بمعنى آخر ، يمكن استخدامه للتحقق مما إذا كان المتغير يقيم على أنه خطأ false .

كود:
int x = 0;
if(!x) {
	// if not x - if x evaluates to false, code here will run
}

// this code is another way of writing the above code
if (x == 0) {
}

• مثال على العامل NOT :
يوضح المثال التالي استخدام العامل NOT المنطقي في برنامج . على الرغم من أن هذا البرنامج ليس تطبيقًا عمليًا جدًا للعامل NOT ، إلا أنه يوضح كيفية عمله.
في البرنامج ، سيقوم كل حرف يتم إرسالها إلى Arduino من النافذة التسلسلية بتشغيل الليد ، باستثناء الحرف 'a'.

كود:
void setup() {
  Serial.begin(9600);
  pinMode(13, OUTPUT);  // LED on pin 13 of UNO
}

void loop() {
  char rx_byte;
  
  if (Serial.available() > 0) {    // is a character available?
    rx_byte = Serial.read();       // read the character
    if (!(rx_byte == 'a')) {
      digitalWrite(13, HIGH);
    }
    else {
      digitalWrite(13, LOW);
    }
  }
}

يقوم العامل not بعكس inverts المنطق في عبارة if الثانية كما هو موضح أدناه .

كود:
if (!(rx_byte == 'a')) {
  digitalWrite(13, HIGH);
}

إذا كان المتغير rx_byte يحتوي على الحرف 'a' ، فسيتم تقييم التعبير في عبارة if إلى true ، ولكن العامل NOT يغير النتيجة إلى false بحيث يتم إيقاف تشغيل LED عند استلام 'a'.
وبالمثل ، إذا كان المتغير rx_byte يحتوي على أي حرف باستثناء 'a' ، فسيتم تقييم التعبير إلى false ، ولكن عامل التشغيل NOT يحول النتيجة false إلى true.

يمكن كتابة الكود أعلاه بسهولة أكبر باستخدام عامل المقارنة (!=) لا يساوي كما يلي.

كود:
if (rx_byte != 'a') {
  digitalWrite(13, HIGH);
}

العامل المنطقي NOT لديه تطبيق عملي في البرامج الأكثر تعقيدًا. تذكر فقط أنه إذا كانت نتيجة المقارنة بحاجة إلى عكسها ، فيمكن استخدام العامل المنطقي NOT. يمكن استخدامه لفرض (لإجبار) عبارة if للتقييم إلى true عندما يتم تقييمها عادةً على false ، وبالتالي تنفيذ الكود في جسم عبارة if بدلاً من الحاجة إلى وجود عبارة if فارغة وتشغيل الكود في كتلة else المقابلة .

اعلانات

الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 31-03-2020, 01:54 PM المشاركة 18   
افتراضي الدرس الثالث عشر عبارات switch و break


دورة برمجة الاردوينو : الدرس الثالث عشر
عبارات switch و break : Arduino switch and break Statements


عبارة switch تشبه استخدام if مع عدة أبنية else-if . يتم استخدام switch بالتزامن (مقترنة) مع break التى سيتم شرحها أيضًا في هذا الدرس .
استخدام switch بدلاً من العديد من أبنية else-if أسهل في القراءة ولديها المزيد من المرونة.

مثال عبارة switch :
يوضح برنامج اردوينو التالي عبارة switch التى يتم استخدامها بالاقتران مع عبارة break .
قم بتحميل البرنامج إلى Arduino ثم ابدأ تشغيل نافذة الشاشة التسلسلية. سيؤدي إرسال 1 من نافذة الشاشة التسلسلية إلى Arduino إلى تشغيل الليد الموجود على اللوحة ، بينما يؤدي إرسال 2 إلى إيقاف تشغيل الليد .
سيعرض إرسال 3 قائمة الخيارات التي يعمل عليها البرنامج . سيؤدي إرسال أي حرف آخر إلى ظهور رسالة افتراضية توضح أن الخيار الذي تم اختياره غير صالح.

كود:
void setup() {
  Serial.begin(9600);
  pinMode(13, OUTPUT);  // LED on pin 13 of UNO
}

char rx_byte = 0;

void loop() {
  if (Serial.available() > 0) {    // is a character available?
    rx_byte = Serial.read();
  
    switch (rx_byte) {
      case '1':
        digitalWrite(13, HIGH);
        Serial.println("LED is ON");
      break;
      
      case '2':
        digitalWrite(13, LOW);
        Serial.println("LED is OFF");
      break;
      
      case '3':
        Serial.println("------- MENU -------");
        Serial.println("1. Switch LED on.");
        Serial.println("2. Switch LED off.");
        Serial.println("3. This menu.");
        Serial.println("--------------------");
      break;
      
      default:
        Serial.println("Invalid option");
      break;
    } // end: switch (rx_byte)
  } // end: if (Serial.available() > 0)
}

سيتم شرح كيفية عمل البرنامج لاحقًا ، ولكن يجب علينا أولاً أن ننظر إلى بنية عبارة switch وكيف تعمل عبارة break .

بناء عبارة switch : Structure of the switch Statement
توضح الصورة أدناه بناء عبارة switch .



تحتوي عبارة switch على متغير (switch_var في الصورة أعلاه أو rx_byte في المثال السابق ) يمكن أن يكون متغيرًا صحيحًا (int) أو حرفًا (char).
سيتم اختبار متغير switch مقابل القيمة في كل حالة case لمعرفة ما إذا كانت متطابقة. عندما يتم العثور على حالة تطابق ، سيتم تشغيل العبارات الموجودة أسفل الحالة case حتى يتم الوصول إلى الكلمة الأساسية break . سيؤدي ذلك إلى كسر تدفق البرنامج خارج جسم عبارة switch وسيستمر تنفيذ البرنامج أسفل قوس إغلاق عبارة switch .
إذا لم يتم العثور على حالة case مطابقة ، فسيتم تشغيل الكود الموجود أسفل الكلمة الرئيسية default حتى يتم العثور على عبارة break .

كيف يعمل برنامج المثال :
في برنامج المثال، يتم وضع عبارة switch داخل عبارة if في الحلقة الرئيسية. عندئذٍ ، يتم تشغيل عبارة switch فقط في حالة استقبال حرف جديد من نافذة Serial Monitor.
عند استقبال حرف من نافذة Serial Monitor ، ستتحقق عبارة switch من وجود قيمة حالة case مطابقة. في حالة استقبال الحرف '1' ، يتم تشغيل الليد ويتم عرض رسالة في نافذة الشاشة التسلسلية.
إذا تم استقبال '2' ، يتم إيقاف تشغيل الليد . يعرض '3' قائمة بالخيارات المتاحة في البرنامج .
إذا تم إرسال أي حرف لا يتطابق مع الأحرف الموجودة في أي من عبارات الحالة case ، يتم تشغيل الكود الموجود في الجزء الافتراضي default من جسم switch والذي يعرض رسالة افتراضية.

عبارة break : The break Statement
يتم استخدام عبارة break في برنامج المثال للخروج من جسم عبارة switch .
يمكن أيضًا استخدام break للخروج من أي حلقة مثل while أو for . على سبيل المثال ، يمكن اختبار شرط معين في حلقة باستخدام عبارة if وإذا تم تقييم العبارة إلى true ، يمكن تشغيل عبارة break للخروج من الحلقة.

اعلانات اضافية ( قم بتسجيل الدخول لاخفائها )

الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 31-03-2020, 03:08 PM المشاركة 19   
افتراضي لدرس الرابع عشر التعبير الشرطى Conditional expression والعامل الشرطى Conditional Oper


دورة برمجة الاردوينو : الدرس الرابع عشر
التعبير الشرطى Conditional expression والعامل الشرطى Conditional Operator

العامل الشرطي conditional operator هو بناء صنع قرار آخر في برمجة Arduino.
يتكون العامل الشرطي من شرط condition ، يمكن تقييمه إلى صواب true أو خطأ false ، وتعبيران expressions.

إذا تم تقييم الشرط بالقيمة true ، يصبح "التعبير الشرطي" conditional expression مساوياً للتعبير الأول.
إذا تم تقييم الشرط على أنه false ، يصبح "التعبير الشرطى" مساوياً للتعبير الثاني.
سيشرح الجزء المتبقي من هذا الدرس ويوضح كيفية عمل العامل الشرطي.

بناء العامل الشرطى Structure of the Conditional Operator (?
العامل الشرطي يكون له البناء التالي:

كود:
condition ? first_expression : second_expression;

حيث يتم تقييم الشرط condition إما إلى صواب true أو خطأ false مما يؤدي إلى أن يصبح التعبير بأكمله مساويًا للتعبير الأول first_expression (إذا تم تقييم الشرط condition إلى صواب true ) أو التعبير الثاني second_expression (إذا تم تقييم الشرط إلى خطأ false ).

كما يتضح من الكود أعلاه ، يتكون العامل الشرطي conditional operator من علامة الاستفهام (؟) وعلامة النقطتين (.
البرنامج أدناه لإظهار كيفية استخدام التعبير الشرطي.

مثال برنامج "التعبير الشرطي" Conditional Expression
يستخدم البرنامج أدناه العامل الشرطي لتحديد أي رقم أكبر من رقمين.

كود:
int val1, val2, result;

void setup() {
  Serial.begin(9600);
  
  // change the values of val1 and val2 to see what the
  // conditional expression does
  val1 = 2;
  val2 = 5;
  // if val1 is bigger than val2, return val1
  // else if val1 is less than val2, return val2
  result = (val1 > val2) ? val1 : val2;
  
  // show result in serial monitor window
  Serial.print("The bigger number is: ");
  Serial.println(result);
}

void loop() {
}

قم بتغيير قيمة المتغيرات val1 و val2 في البرنامج ، وسيتم عرض أكبر الرقمين دائمًا في نافذة الشاشة التسلسلية في Arduino IDE.

كيف يعمل البرنامج :
يتم تقييم الشرط (val1> val2) وسيتم تقييمه إما إلى صواب true أو خطأ false.
• تقييم الشرط خطأ false
إذا كانت val1 أقل من val2 ، يتم تقييم الشرط إلى false. يأخذ التعبير الشرطي ككل الآن قيمة التعبير الثاني - وهو val2.
ثم يتم تعيين result لقيمة التعبير وهي val2 (أى 5 فى البرنامج ) وهي أكبر رقم من القيمتين val1 و val2.
• تقييم الشرط صواب true
إذا قمنا بتغيير قيمة val1 إلى 12 بحيث يكون لدينا:

كود:
val1 = 12;
val2 = 5;

val1 الآن أكبر من val2 ويتم تقييم الشرط إلى true. يأخذ التعبير الشرطي قيمة التعبير الأول - وهو val1.
يتم تعيين المتغير result لقيمة التعبير وهي val1. val1 هي أكبر القيمتين (بقيمة 12).


الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 31-03-2020, 10:24 PM المشاركة 20   
افتراضي الدرس الخامس عشر الدوال والاردوينو Arduino Functions


دورة برمجة الاردوينو : الدرس الخامس عشر
الدوال والاردوينو Arduino Functions


في هذا الدرس ، ستتعلم كيفية كتابة الدوال الخاصة بك واستخدامها في برامجك . يتم شرح بناء structure واستخدام الدوال بشكل كامل.
تم تناول الدوال بإيجاز في الدرس الأول حيث تعرفنا على بعض الحقائق الأساسية حول الدوال حيث تم ذكرها :
1) يجب أن يكون لكل دالة اسم فريد ،
2) يتبع اسم الدالة بأقواس ()
3) الدوال لها نوع إرجاع ، على سبيل المثال void
4) جسم الدالة محاط داخل أقواس الفتح والإغلاق {}.
سنبدأ بفحص بناء الدالة ثم نرى كيفية كتابة الدوال .

بناء الدالة The Structure of a Function
قبل أن يتم (يمكن) استخدام دالة في برنامج ، يجب إنشاؤها. الكود التالى هو مثال على دالة تم إنشاؤها لطباعة خط متقطع dashed line في Arduino IDE.

كود:
void DashedLine()
{
    Serial.println("----------------");
}

الكود أعلاه والذي ينشىء creates الدالة يسمى "تعريف الدالة" function definition . توضح الصورة أدناه مكونات الدالة .



1- اسم الدالة Function Name
عندما نقوم بإنشاء دالة ، يجب أن يكون لها اسم name. اصطلاح التسمية للدوال هو نفسه للمتغيرات:
• يمكن أن يتكون اسم الدالة من أحرف أبجدية (A to Z; a to z; 0 to 9) والشرطة السفلية (_).
• لا يبدأ اسم الدالة برقم number ، أي الأرقام من 0 إلى 9.
• يجب عدم استخدام اسم دالة هو نفس الكلمة الرئيسية للغة أو دالة موجودة.
ينتهي اسم الدالة بالأقواس (). لا يتم تمرير أي شيء إلى دالة المثال أعلاه ، لذلك تكون الأقواس فارغة. سيتم شرح تمرير القيم values أو البارامترات parameters إلى الدوال لاحقًا في هذا الدرس .


2- نوع الإرجاع Return Type
يجب أن يكون للدالة نوع إرجاع. لا ترجع دالة المثال أي شيء ، لذلك يوجد لها نوع إرجاع فارغ void. سيتم شرح إرجاع قيمة من دالة في الجزء التالي من هذا الدرس .

3- جسم الدالة Function Body
يتكون جسم الدالة من العبارات statements الموضوعة بين القوسين {}. تشكل العبارات وظيفة الدالة (ماذا ستفعل الدالة عندما يتم استدعاؤها).
عند استخدام دالة ، يقال أنها "تستدعى " "called". سنلقي نظرة على كيفية استدعاء دالة بعد ذلك.

استدعاء دالة Calling a Function
لاستخدام الدالة التي تم إنشاؤها أعلاه ، يجب استدعاؤها في البرنامج كما هو موضح في البرنامج أدناه.

كود:
void setup() {
  Serial.begin(9600);
  
  DashedLine();
  Serial.println("| Program Menu |");
  DashedLine();
}

void loop() {
}

void DashedLine()
{
  Serial.println("----------------");
}

في البرنامج أعلاه ، يتم إنشاء الدالة DashedLine() في أسفل البرنامج ثم يتم استدعاؤها مرتين في أعلى البرنامج كما هو موضح في الصورة أدناه.



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



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

لماذا استخدام الدوال Why Use Functions
الدالة المستخدمة في المثال أعلاه بسيطة للغاية ، لذلك لن يتم رؤية جميع مزايا استخدام الدوال على الفور.
إحدى مزايا استخدام الدوال هي أنها تتجنب الاضطرار إلى كتابة نفس الكود مرارًا وتكرارًا في البرنامج يوفر الوقت والذاكرة. في كل مرة يتم فيها استدعاء دالة ، فإننا نعيد استخدام الكود الذي تمت كتابته مرة واحدة فقط.

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

يمكن استخدام الدوال الوظائف لتقطيع (تكسير - تجزئة) break برنامج إلى أجزاء تجعله أكثر وحدات modular وأسهل في الفهم. يمكن إعادة استخدام الدوال في برامج الأخرى.

تمرير قيمة إلى دالة Passing a Value to a Function
في البرنامج أعلاه ، طول الخط الذي تطبعه الدالة يكون ثابت فى الدالة . إذا قمنا بتغيير النص الموجود في المربع ، فقد لا يتناسب مع المربع بشكل صحيح. يجب تعديل الدالة حتى تتمكن من معرفة حجم الخط الذي يجب رسمه.
يمكن تعديل الدالة أعلاه لتمرير قيمة value لها تخبرها بعدد الأحرف التي تصنع الخط الذي ترسمه.
يظهر البرنامج المعدّل أدناه.

كود:
 void setup() {
  Serial.begin(9600);
  
  // draw the menu box
  DashedLine(24);
  Serial.println("| Program Options Menu |");
  DashedLine(24);
}

void loop() {
}

void DashedLine(int len)
{
  int i;
  
  // draw the line
  for (i = 0; i < len; i++) {
    Serial.print("-");
  }
  // move the cursor to the next line
  Serial.println("");
}

يتم تعديل الدالة DashedLine() في البرنامج أعلاه بحيث يمكن تمرير قيمة عدد صحيح إليها. يجب أن يتألف الخط (السطر) line من 24 حرفًا ليتناسب مع نص القائمة الجديدة ، لذلك نمرر لها القيمة 24.

كود:
DashedLine(24);  // passing a value of 24 to the function

بالطبع يجب تعديل الدالة للتعامل مع القيمة التي يتم تمريرها إليها:

كود:
void DashedLine(int len)
{
  int i;
  
  // draw the line
  for (i = 0; i < len; i++) {
    Serial.print("-");
  }
  // move the cursor to the next line
  Serial.println("");
}

يجب أن تكون الدالة قادرة على قبول قيمة عدد صحيح يتم تمريره إليها. يتم إدراج نوع المتغير واسم المتغير بين قوسى الفتح والإغلاق بعد اسم الدالة .

كود:
void DashedLine(int len)

يمكننا الآن استخدام متغير العدد الصحيح len في جسم الدالة DashedLine() . سيحتوي المتغير على أي قيمة يتم تمريرها إليها عند استدعاء الدالة .
يستخدم جسم الدالة المتغير len في حلقة لطباعة العدد الصحيح من الشرطات التي تشكل الخط المتقطع لمربع القائمة.
يتم نقل المؤشر إلى السطر التالي في جهاز العرض التسلسلي عن طريق استدعاء Serial.println(""); بسلسلة فارغة.
بعد أن تقوم الدالة بتشغيل العبارة الأخيرة في جسمها ، يقال أنها "تعود أو ترجع" "return". عندما تعود إحدى الدوال ، يستمر تنفيذ البرنامج أسفل العبارة التي تستدعى الدالة - أي يتم تشغيل العبارة التالية لاستدعاء الدالة بعد ذلك.


الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 01-04-2020, 02:38 PM المشاركة 21   
افتراضي الدرس السادس عشر إرجاع (إعادة) قيمة من دالة Returning a Value from a Function


دورة برمجة الاردوينو : الدرس السادس عشر
إرجاع (إعادة) قيمة من دالة Returning a Value from a Function


في الدرس السابق ، تناولنا في كيفية تمرير قيمة إلى دالة. الآن نلقي نظرة على كيفية استعادة قيمة من دالة.
تسمى استعادة قيمة من دالة "إرجاع أو إعادة" "returning"القيمة من الدالة. يتم استخدام الكلمة الأساسية "العائد" return في نهاية الدالة لاستعادة القيمة. يجب أن نذكر أيضًا نوع القيمة التي ترجعها الدالة ، على سبيل المثال int ، float ، إلخ.
يستخدم البرنامج أدناه دالة لإجراء حساب رياضي ثم إرجاع return نتيجة الحساب التي يمكن استخدامها بعد ذلك في برنامج الاردوينو الرئيسي.

الدالة التى تعيد (ترجع) قيمة Function that Returns a Value

كود:
void setup() {
    float area;
  
    Serial.begin(9600);
    // calculate the area of a circle with radius of 9.2
    area = CircleArea(9.2);
    Serial.print("Area of circle is: ");
    // print area to 4 decimal places
    Serial.println(area, 4);
}

void loop() {
}

// calculate the area of a circle
float CircleArea(float radius)
{
    float result;
    
    result = 3.141592654 * radius * radius;
    
    return result;
}

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

صيغة حساب مساحة الدائرة هي:

كود:
A = π × r²
OR
A = π × r × r

Where:
A = area of the circle
π = PI = 3.141592654
r = radius of the circle

بمعنى آخر ، إذا كنا نعرف نصف قطر الدائرة (نصف القطر هو المسافة من مركز الدائرة إلى الحافة) يمكننا حساب مساحة الدائرة.
يمكن أن تكون الوحدة unit التي يوجد بها نصف القطر أي وحدة تُستخدم لقياس المسافة وستكون المساحة مربعات للوحدة المستخدمة ، على سبيل المثال إذا كان نصف القطر بالسنتيمتر ، فستكون المساحة بالسنتيمتر المربع ، إذا كان نصف القطر بالقدم ، فستكون النتيجة بالأقدام المربعة.

كيف يعمل البرنامج :
يجب أن تُرجع الدالة CircleArea() قيمة ، لذلك يسبقها نوع القيمة التي يجب أن تُرجعها - في هذه الحالة float . يتم أيضًا تمرير قيمة float تسمى radius إلى الدالة كما هو موضح في الدرس السابق .

كود:
float CircleArea(float radius)

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

كود:
return result;

يتم ترجمة الصيغة إلى كود Arduino على النحو التالي:

كود:
A = π × r × r

Becomes:

result = 3.141592654 * radius * radius;

في جزء البرنامج الذي يستدعي الدالة CircleArea() ، تصبح الدالة بشكل أساسي القيمة التي تُرجعها ويمكن تعيينها لمتغير.
يتم تعيين المتغير area للقيمة التي ترجعها الدالة CircleArea() :

كود:
 area = CircleArea(9.2);

بعد ذلك ، يتم إرسال نتيجة الحساب ، وهي مساحة الدائرة ، إلى المنفذ التسلسلي ليتم عرضه في النافذة التسلسلية Arduino IDE.

نسخة أقصر من البرنامج :
يمكن كتابة البرنامج أعلاه بطريقة أقصر بدون استخدام بعض المتغيرات المتوسطة كما هو موضح أدناه.

كود:
void setup() {
    Serial.begin(9600);
    Serial.print("Area of circle is: ");
    // print area to 4 decimal places
    Serial.println(CircleArea(9.2), 4);
}

void loop() {
}

// calculate the area of a circle
float CircleArea(float radius)
{
    return (3.141592654 * radius * radius);
}

في هذا البرنامج ، تُرجع الدالة CircleArea() نتيجة الحساب على سطر واحد دون تعيينها أولاً إلى متغير.

كود:
return (3.141592654 * radius * radius);

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

كود:
Serial.println(CircleArea(9.2), 4);
حجم ملف الإخراج الثنائي (الملف الذي يتم تحميله إلى Arduino بعد الترجمة) من مترجم Arduino هو 4,040 bytes لكل من البرنامجين في الإصدار Arduino IDE 1.0.6.


الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 01-04-2020, 09:13 PM المشاركة 22   
افتراضي الدرس السابع عشر المصفوفات والاردوينو Arduino Arrays


دورة برمجة الاردوينو : الدرس السابع عشر
المصفوفات والاردوينو Arduino Arrays


المصفوفات Arrays هي مجموعات من نفس النوع من البيانات data التي يتم وضعها على التوالي في الذاكرة. على سبيل المثال ، يمكن أن يكون لدينا مصفوفة من الأعداد الصحيحة (النوع int) وهى رقمان صحيحان أو أكثر يحدثان الواحد تلو الآخر.
المفتاح هنا هو أن كل عنصر element في المصفوفة يتم وضعه مباشرة بعد العنصر السابق مما يسمح لنا بالوصول إلى كل عنصر بدوره باستخدام حلقة loop.
يشير عنصر في مصفوفة إلى قيمة في المصفوفة . إذا كان لدينا مصفوفة من الأعداد الصحيحة ، فسيتم الإشارة إلى كل عدد صحيح فردي كعنصر من المصفوفة . في مصفوفة من البايتات bytes ، يكون كل عنصر بايت (من نوع byte).

استخدام المصفوفات Using Arrays
يوضح البرنامج أدناه الاستخدام الأساسي للمصفوفة .

كود:
void setup() {
  int my_array[5];     // an array with 5 integer elements
  int i;               // used as an index into the array
  
  Serial.begin(9600);
  
  my_array[0] = 23;    // assign a value of 23 to the 1st element
  my_array[1] = 1001;  // assign a value of 1001 to the 2nd element, etc.
  my_array[2] = 9;
  my_array[3] = 1234;
  my_array[4] = 987;
  
  // display each number from the array in the serial monitor window
  for (i = 0; i < 5; i++) {
    Serial.println(my_array[i]);
  }
}

void loop() {
}

تعريف المصفوفة Defining the Array
في هذا البرنامج ، يتم تعريف مصفوفة من 5 عناصر. هذا يصنع مساحة في الذاكرة لخمسة أعداد صحيحة يتم وضعها في الذاكرة واحدة تلو الأخرى. يمكن أن تحتوي القيم التي يحتوي عليها كل عنصر بعد تعريف المصفوفة على أي بيانات عشوائية. من الممكن أيضًا أن يتم التعيين بمعرفة المترجم compiler لجعل القيم صفرًا ، ولكن لا يمكننا الاعتماد على ذلك.

تعريف مصفوفة من 5 أعداد صحيحة:

كود:
int my_array[5];     // an array with 5 integer elements

في هذا المثال ، المصفوفة من النوع int ، ولكن يمكن أن يكون float أو byte ، إلخ.
المصفوفة لها اسم وهو my_array في المثال.
المصفوفة لها طول [5] مما يعني أن مساحة 5 أعداد صحيحة متتالية يتم صنعها في الذاكرة.

تعيين (تخصيص) القيم للعناصر في المصفوفة Assigning Values to Elements in the Array
يتم تعيين قيمة عدد صحيح لكل عنصر من خلال الرجوع (الإشارة) إليه باستخدام الأقواس المربعة [] مع رقم العنصر بين الأقواس للوصول إليه.

كود:
my_array[0] = 23;
my_array[1] = 1001;
my_array[2] = 9;
my_array[3] = 1234;
my_array[4] = 987;

لاحظ أن ترقيم numbering العناصر يبدأ من صفر [0] وليس واحد [1] ، لذا فإن العنصر الأول في المصفوفة هو العنصر 0.
بالطريقة نفسها ، يتم ترقيم العنصر الأخير في المصفوفة بحجم المصفوفة ناقص عنصر واحد أقل . في المثال ، حجم المصفوفة هو 5 ، وبالتالي فإن رقم العنصر الأخير هو 4 - مرة أخرى هذا لأننا نرقم العناصر بدءًا من 0.

الوصول إلى المصفوفة في حلقة Accessing an Array in a Loop
يتم استخدام حلقة for للحصول على محتويات كل عنصر في المصفوفة كل بدوره وطباعة القيم إلى النافذة التسلسلية .

كود:
 for (i = 0; i < 5; i++) {
  Serial.println(my_array[i]);
}

يستخدم المتغير i في حلقة for كمؤشر (فهرس) index في المصفوفة للوصول إلى كل عنصر من عناصر المصفوفة.
في الحلقة ، تتم تهيئة i إلى 0 ثم تتم زيادته بمقدار واحد في كل مرة من خلال الحلقة بحيث يتم حسابه من 0 إلى 4. ويتم الخروج من الحلقة عندما يصبح 5.
يستخدم المتغير i في المصفوفة للحصول على القيمة التي يحتفظ بها عنصر المصفوفة بدءًا من العنصر 0 وينتهي بالعنصر 4.

كود:
(my_array[i]);

في الكود أعلاه ، عندما تكون i بصفر 0 ، يتم الوصول إلى العنصر الأول من المصفوفة ويمكننا بعد ذلك الحصول على القيمة التي يحتوي عليها والتي هي 23 في برنامج المثال .

المزيد عن تهيئة المصفوفات More on Initializing Arrays
بدلاً من تهيئة كل عنصر في المصفوفة بشكل فردي ، يمكن تعريف المصفوفة وتهيئتها في سطر واحد كما هو موضح في هذا الكود .
يعمل هذا البرنامج تمامًا مثل البرنامج السابق.

كود:
void setup() {
  int my_array[5] = {23, 1001, 9, 1234, 987};
  int i;
  
  Serial.begin(9600);
  
  // display each number from the array in the serial monitor window
  for (i = 0; i < 5; i++) {
    Serial.println(my_array[i]);
  }
}

void loop() {
}

يتم وضع القيم لتهيئة كل عنصر بها بين الأقواس {} بعد عامل التعيين (علامة يساوي =). سيتم تعيين القيمة الأولى بين الأقواس للعنصر الأول في المصفوفة (رقم العنصر 0) ، وسيتم تعيين الرقم الثاني بين الأقواس للعنصر الثاني في المصفوفة (العنصر رقم 1) ، إلخ.
يمكن أيضًا كتابة التعليمات البرمجية التي تقوم بالتعريف defining والتهيئة initializing دون عدد العناصر في المصفوفة بين القوسين المربعين:

كود:
int my_array[] = {23, 1001, 9, 1234, 987};

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

استخدامات المصفوفات Uses of Arrays
يوضح هذا الدرس أن المصفوفات يمكنها تخزين متغيرات البيانات من نفس النوع على التوالي في الذاكرة مما يسمح بالوصول السهل باستخدام حلقة.
هناك العديد من الاستخدامات للمصفوفات في البرمجة ، على سبيل المثال ، يمكن للمصفوفات تخزين البيانات التي يتم تسجيلها ، مثل درجات الحرارة. السلاسل النصية Strings ، وهي أسطر نصية ، هي في الواقع مصفوفات كما سنرى في الدرس التالي .


الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 02-04-2020, 09:26 PM المشاركة 23   
افتراضي الدرس الثامن عشر السلاسل النصية والاردوينو Arduino Strings


دورة برمجة الاردوينو : الدرس الثامن عشر
السلاسل النصية والاردوينو Arduino Strings


تُستخدم السلاسل Strings لتخزين نص text. يمكن استخدامها لعرض النص على شاشة LCD أو في نافذة الاردوينو التسلسلية لبيئة التطوير Arduino IDE.
السلاسل مفيدة أيضًا لتخزين إدخال input المستخدم - على سبيل المثال الأحرف التي يكتبها المستخدم على لوحة مفاتيح متصلة بالاردوينو .

هناك نوعان من السلاسل في برمجة الاردوينو Arduino:
1) مصفوفات Arrays الأحرف التي هي نفس السلاسل المستخدمة في برمجة لغة C.
2) سلسلة الاردوينو Arduino String التي تتيح لنا استخدام كائن السلسلة string object في البرنامج .
يتم بالكامل شرح السلاسل Strings والكائنات objects وكيفية استخدام السلاسل في برامج Arduino في هذا الدرس . يتم الإجابة على السؤال عن نوع السلسلة التي سيتم استخدامها في البرنامج في نهاية هذا الدرس .

سلسلة مصفوفات الحرف String Character Arrays
النوع الأول من السلسلة الذي سنتناوله هو السلسلة التي هي سلسلة (متتالية) series من الأحرف من نوع char. أوضح الدرس السابق ما هي المصفوقة - سلسلة متتالية consecutive series من نفس النوع من المتغيرات المخزنة في الذاكرة. السلسلة string هي مصفوفة من متغيرات الحرف char.
السلسلة هي مصفوفة خاصة تحتوي على عنصر إضافي واحد في نهاية السلسلة والذي يكون دائمًا له القيمة 0 (صفر). يُعرف هذا "سلسلة منتهية بحرف عديم الوجود أو لاشىء""null terminated string".

مثال برنامج على سلسلة مصفوفة الحرف :
سيوضح هذا البرنامج كيفية صنع (عمل) سلسلة وطباعتها إلى نافذة الشاشة التسلسلية.

كود:
void setup() {
  char my_str[6];    // an array big enough for a 5 character string
  
  Serial.begin(9600);
  
  my_str[0] = 'H';  // the string consists of 5 characters
  my_str[1] = 'e';
  my_str[2] = 'l';
  my_str[3] = 'l';
  my_str[4] = 'o';
  my_str[5] = 0;    // 6th array element is a null terminator
  
  Serial.println(my_str);
}

void loop() {
}

يُظهر البرنامج مما تتكون السلسلة من - تتكون من مصفوفة حرف بأحرف قابلة للطباعة و 0 في العنصر الأخير من المصفوفة لإظهار أن هذا حيث تنتهي السلسلة.
يمكن طباعة السلسلة إلى نافذة الشاشة التسلسلية باستخدام Serial.println() وتمريرها باسم السلسلة.
يمكن كتابة نفس هذا البرنامج بسهولة أكبر بهذه الطريقة:

كود:
void setup() {
  char my_str[] = "Hello";
  
  Serial.begin(9600);
  
  Serial.println(my_str);
}

void loop() {
}

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

السلاسل والحروف Strings and Characters :
تتم كتابة الأحرف بين علامات الاقتباس الفردية مثل هذا:

كود:
'w'

تتم كتابة السلاسل بين علامات الاقتباس المزدوجة مثل هذا:

كود:
"This is a string"

معالجة مصفوفات السلسلة Manipulating String Arrays
يمكننا تغيير مصفوفة سلسلة داخل برنامج كما يظهر البرنامج التالي.

كود:
void setup() {
  char like[] = "I like coffee and cake";  // create a string
  
  Serial.begin(9600);
  
  // (1) print the string
  Serial.println(like);
  
  // (2) delete part of the string
  like[13] = 0;
  Serial.println(like);
  
  // (3) substitute a word into the string
  like[13] = ' ';  // replace the null terminator with a space
  like[18] = 't';  // insert the new word
  like[19] = 'e';
  like[20] = 'a';
  like[21] = 0;    // terminate the string
  Serial.println(like);
}

void loop() {
}

• إنشاء وطباعة السلسلة Creating and Printing the String
في هذا البرنامج ، يتم إنشاء سلسلة جديدة ثم طباعتها للعرض في النافذة التسلسلية (1) .

• تقصير السلسلة Shortening the String
يتم تقصير السلسلة عن طريق استبدال الحرف الرابع عشر في السلسلة بصفر الانتهاء (2). هذا هو العنصر رقم 13 في مصفوفة السلسلة العد من 0.
عند طباعة السلسلة ، تتم طباعة جميع الأحرف حتى صفر الانتهاء الجديد . لا تختفي الحروف الأخرى - فهي لا تزال موجودة في الذاكرة ولا تزال مصفوفة السلسلة بنفس الحجم. والفرق الوحيد هو أن أي دالة تعمل مع السلاسل لن ترى سوى السلسلة حتى حرف النهاية null الأول.


• تغيير كلمة في السلسلة Changing a Word in the String
وأخيرًا يستبدل البرنامج كلمة "cake" بكلمة "tea" (3). يجب أولاً استبدال حرف النهاية null في like[13] بمسافة space بحيث تتم استعادة السلسلة إلى كيفية إنشائها في الأصل.
الحروف الجديدة تستبدل "cak" من كلمة "cake" بكلمة tea" . يتم ذلك عن طريق استبدال الأحرف الفردية. يتم استبدال حرف "e" من "cake" بحرف إنهاء null جديد . والنتيجة هي أن السلسلة تنتهي فعليًا بحرفين فارغين - الحرف الأصلي في نهاية السلسلة والحرف الجديد الذي يحل محل حرف "e" في "cake" . لا يحدث هذا فرقًا عند طباعة السلسلة الجديدة لأن الدالة التي تطبع السلسلة تتوقف عن طباعة أحرف السلسلة عندما تواجه أول حرف نهاية null .

دوال لمعالجة مصفوفات السلسلة Functions to Manipulate String Arrays
في البرنامج السابق تم معالجة السلسلة بطريقة يدوية للغاية عن طريق الوصول إلى أحرف فردية في السلسلة. لتسهيل معالجة مصفوفات السلسلة ، يمكنك كتابة الدوال الخاصة بك للقيام بذلك ، أو استخدام بعض دوال السلسلة من مكتبة لغة C.
يستخدم البرنامج التالي بعض دوال سلسلة لغة C.

كود:
void setup() {
  char str[] = "This is my string";  // create a string
  char out_str[40];                  // output from string functions placed here
  int num;                           // general purpose integer
  
  Serial.begin(9600);
  
  // (1) print the string
  Serial.println(str);
  
  // (2) get the length of the string (excludes null terminator)
  num = strlen(str);
  Serial.print("String length is: ");
  Serial.println(num);
  
  // (3) get the length of the array (includes null terminator)
  num = sizeof(str);  // sizeof() is not a C string function
  Serial.print("Size of the array: ");
  Serial.println(num);
  
  // (4) copy a string
  strcpy(out_str, str);
  Serial.println(out_str);
  
  // (5) add a string to the end of a string (append)
  strcat(out_str, " sketch.");
  Serial.println(out_str);
  num = strlen(out_str);
  Serial.print("String length is: ");
  Serial.println(num);
  num = sizeof(out_str);
  Serial.print("Size of the array out_str[]: ");
  Serial.println(num);
}

void loop() {
}

يعمل البرنامج بالطريقة التالية.

(1) طباعة السلسلة Print the String
تتم طباعة السلسلة التي تم إنشاؤها حديثًا إلى النافذة التسلسلية كما تم في البرامج السابقة.

(2) الحصول على طول السلسلة Get the Length of the String
يتم استخدام الدالة strlen() للحصول على طول السلسلة. طول السلسلة مخصص للأحرف القابلة للطباعة فقط ولا يتضمن حرف النهاية null .
تحتوي السلسلة على 17 حرفًا ، لذلك نرى 17 مطبوعة في النافذة التسلسلية .

(3) الحصول على طول المصفوفة Get the Length of the Array
يستخدم العامل sizeof() للحصول على طول المصفوفة التي تحتوي على السلسلة. يشتمل الطول على حرف نهاية null ، لذا فإن الطول أكبر بواحد من طول السلسلة.
العامل sizeof() يشبه دالة ، ولكن من الناحية الفنية هو عامل operator . وهو ليس جزءًا من مكتبة السلسلة string للغة C ، ولكن تم استخدامه في البرنامج لإظهار الفرق بين حجم المصفوفة وحجم السلسلة (أو طول السلسلة).

(4) نسخ سلسلة Copy a String
يتم استخدام الدالة strcpy() لنسخ السلسلة str[] إلى المصفوفة out_num[] . تنسخ الدالة strcpy() السلسلة الثانية التي تم تمريرها إليها في السلسلة الأولى. توجد نسخة من السلسلة الآن في المصفوفة out_num[] ، ولكنها لا تستوعب سوى 18 عنصرًا من المصفوفة ، لذلك لا يزال لدينا 22 عنصرًا char حرا في المصفوفة . يتم العثور على هذه العناصر الحرة بعد السلسلة في الذاكرة.
تم نسخ السلسلة إلى المصفوفة بحيث يكون لدينا مساحة إضافية في المصفوفة لاستخدامها في الجزء التالي من البرنامج الذي يضيف سلسلة إلى نهاية السلسلة.

(5) إلحاق سلسلة بسلسلة (تسلسل) Append a String to a String (Concatenate)
يربط البرنامج سلسلة بأخرى ، والتي تُعرف بالسلسلة أو التسلسل concatenation . يتم ذلك باستخدام الدالة strcat() . تضع الدالة strcat() السلسلة الثانية التي تم تمريرها إليها في نهاية السلسلة الأولى التي تم تمريرها إليها.
بعد التسلسل ، تتم طباعة طول السلسلة لإظهار طول السلسلة الجديدة. ثم يتم طباعة طول المصفوفة لإظهار أن لدينا سلسلة طويلة مكونة من 25 حرفًا في مصفوفة بطول 40 عنصرًا.
تذكر أن السلسلة الطويلة المكونة من 25 حرفًا تستهلك في الواقع 26 حرفًا من المصفوفة بسبب حرف الانتهاء null .

حدود المصفوفة Array Bounds
عند العمل مع السلاسل والمصفوفات ، من المهم جدًا العمل ضمن حدود bounds السلسلة أو المصفوفة. في برنامج المثال ، تم إنشاء مصفوفة مكونة من 40 حرفًا من أجل تخصيص الذاكرة التي يمكن استخدامها لمعالجة السلاسل.

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

كائن سلسلة الاردوينو The Arduino String Object
النوع الثاني من السلسلة المستخدمة في برمجة الاردوينو هو الكائن String.

ما هو الكائن ؟ What is an Object?
الكائن هو بناء construct يحتوي على كل من البيانات data والدوال functions . يمكن إنشاء كائن String تمامًا مثل المتغير وتعيين قيمة أو سلسلة. يحتوي كائن String على دوال (والتي تسمى "طرق" "methods"في البرمجة الموجهة للكائنات (OOP)) والتي تعمل على بيانات السلسلة الموجودة في كائن السلسلة String.
سوف يوضح البرنامج والشرح التاليان ما هو الكائن وكيف يتم استخدام كائن String.

كود:
 void setup() {
  String my_str = "This is my string.";
  
  Serial.begin(9600);
  
  // (1) print the string
  Serial.println(my_str);
  
  // (2) change the string to upper-case
  my_str.toUpperCase();
  Serial.println(my_str);
  
  // (3) overwrite the string
  my_str = "My new string.";
  Serial.println(my_str);
  
  // (4) replace a word in the string
  my_str.replace("string", "Arduino sketch");
  Serial.println(my_str);
  
  // (5) get the length of the string
  Serial.print("String length is: ");
  Serial.println(my_str.length());
}

void loop() {
}

يتم إنشاء كائن سلسلة string object وتعيين قيمة (أو سلسلة) في أعلى البرنامج .

كود:
String my_str = "This is my string.";

يؤدي هذا إلى إنشاء كائن من الفئة String باسم my_str ويعطيه قيمة "This is my string." .
يمكن مقارنة ذلك بإنشاء متغير وتعيين قيمة له مثل عدد صحيح:

كود:
int my_var = 102;

(1) طباعة السلسلة Printing the String
يمكن طباعة السلسلة إلى النافذة التسلسلية تمامًا مثل سلسلة مصفوفة الأحرف.

(2) تحويل السلسلة إلى أحرف كبيرة Convert the String to Upper-case
يحتوي كائن السلسلة my_str الذي تم إنشاؤه على عدد من الدوال أو الأساليب methods التي يمكن عملها عليه. يتم استدعاء هذه الطرق باستخدام اسم الكائنات متبوعًا بعامل النقطة (.) ثم اسم الدالة المراد استخدامها.

كود:
my_str.toUpperCase();

تعمل الدالة toUpperCase() على السلسلة الموجودة في الكائن my_str وهو من النوع String وتحول بيانات السلسلة (أو النص) التي يحتوي عليها الكائن إلى أحرف كبيرة.
يمكن العثور على قائمة بالدوال التي تحتوي عليها الفئة String في مرجع سلسلة الاردوينو Arduino String reference .
فنيا تُسمى String فئة class وتُستخدم لإنشاء كائنات String.

(3) استبدال سلسلة Overwrite a String
يتم استخدام عامل التخصيص assignment operator لتعيين سلسلة جديدة إلى كائن my_str الذي يحل محل السلسلة القديمة.

كود:
my_str = "My new string.";

لا يمكن استخدام عامل التخصيص في سلاسل مصفوفات الأحرف ، ولكنه يعمل على كائنات سلسلة String فقط.

(4) استبدال كلمة في السلسلة Replacing a Word in the String
يتم استخدام الدالة replace() لاستبدال السلسلة الأولى التي تم تمريرها إليها بالسلسلة الثانية التي تم تمريرها إليها. replace() هي دالة أخرى مضمنة في الفئة String وهي متاحة للاستخدام على كائن String وهو my_str.

(5) الحصول على طول السلسلة Getting the Length of the String
يتم الحصول على طول السلسلة بسهولة باستخدام الدالة length() . في برنامج المثال ، يتم تمرير النتيجة التي تم إرجاعها بواسطة length() مباشرةً إلى Serial.println() بدون استخدام متغير وسيط.

متى يتم استخدام كائن سلسلة String Object أو مصفوفة أحرف سلسلة String Character Array
يعتبر استخدام كائن String أسهل بكثير من استخدام مصفوفة أحرف سلسلة. يحتوي الكائن على دوال مضمنة يمكنها إجراء عدد من العمليات على سلاسل موثقة بالكامل في القسم المرجعي على موقع Arduino على الويب.

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

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

أين يتم استخدام السلاسل Where Strings are Used
تناول هذا الدرس ما هي السلاسل وكيف تبدو في الذاكرة وبعض العمليات التي يمكن القيام بها على السلاسل.
سيتم تغطية الاستخدامات العملية الفعلية للسلاسل في الدرس التالي عندما نتناول كيفية الحصول على إدخال المستخدم من نافذة الشاشة التسلسلية وحفظ الإدخال في سلسلة.


الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 03-04-2020, 09:29 PM المشاركة 24   
افتراضي الدرس التاسع عشر الحصول على واستخدام الإدخال التسلسلى


دورة برمجة الاردوينو : الدرس التاسع عشر
الحصول على واستخدام الإدخال التسلسلى والاردوينو Getting and Using Arduino Serial Input

يوضح هذا الدرس كيفية الحصول على البيانات في برنامج الاردوينو من المنفذ التسلسلي serial port. يمكن إرسال البيانات إلى الاردوينو من نافذة المراقبة التسلسلية فى في Arduino IDE.

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

الحصول على الإدخال التسلسلي Getting Serial Input
يوضح البرنامج التالي كيفية الحصول على حرف واحد من نافذة المراقبة التسلسلية Serial Monitor وتحديد ما إذا كان الحرف رقمًا أم لا.

كود:
void setup() {
  Serial.begin(9600);
}

char rx_byte = 0;

void loop() {
  if (Serial.available() > 0) {    // is a character available?
    rx_byte = Serial.read();       // get the character
  
    // check if a number was received
    if ((rx_byte >= '0') && (rx_byte <= '9')) {
      Serial.print("Number received: ");
      Serial.println(rx_byte);
    }
    else {
      Serial.println("Not a number.");
    }
  } // end: if (Serial.available() > 0)
}

كيف يعمل البرنامج How the Sketch Works

1- التحقق من وجود حرف Checking for a Character
في الدالة الرئيسية loop() ، يتم استخدام عبارة if للتحقق مما إذا كان الحرف متاحًا على المنفذ التسلسلي - أي إذا تم إرسال حرف من نافذة Serial Monitor واستقبله Arduino.
يتم تشغيل عبارة if هذه بسرعة لتشغيل العبارة if والعودة إلى أعلى الحلقة لتشغيلها مرة أخرى.

كود:
if (Serial.available() > 0) {    // is a character available?
}

لا يتم تشغيل أي شيء في جسم عبارة if حتى يتم استقبال حرف.

2- الحصول على حرف Getting a Character
عند استقبال حرف على المنفذ التسلسلي ، يتم تخزينه في متغير حرف (من نوع char) يسمى rx_byte.

كود:
rx_byte = Serial.read();       // get the character

يتم الآن تخزين نسخة من الحرف المستقبل في المتغير rx_byte ويمكننا استخدام الحرف المستقبل في برنامجنا .

3- التحقق مما إذا كان الحرف المستقبل رقمًا Check if the Received Character is a Number
يختبر البرنامج ما إذا كان الحرف المستقبل رقمًا أم لا عن طريق التحقق مما إذا كان الحرف أكبر من أو يساوي "0" وأقل من أو يساوي "9".

كود:
if ((rx_byte >= '0') && (rx_byte <= '9')) {
}

نحن نتحقق فعليًا من "أحرف الأرقام" من '0' إلى '9' وليس الأرقام الصحيحة الفعلية من 0 إلى 9. وذلك لأن البيانات التي يتم استقبالها من نافذة Serial Monitor تكون بتنسيق ASCII.
من الجدول الذي يظهر أحرف ASCII القابلة للطباعة ، يمكننا أن نرى أن حرف '0' له القيمة الصحيحة 48 عشري وأن حرف '9' له قيمة 57 عشرى . وبعبارة أخرى عند كتابة '0' على لوحة المفاتيح في حقل "إرسال" "send" من نافذة Serial Monitor ويتم النقر فوق الزر إرسال Send ، يتم إرسال القيمة الصحيحة 48 إلى Arduino. في البرنامج ، يمكننا الإشارة إلى هذا الحرف باسم '0' أو 48.
نفس الشيء يمكن كتابة عبارة if باستخدام الأعداد الصحيحة العشرية على النحو التالي:

كود:
if ((rx_byte >= 48) && (rx_byte <= 57)) {
}

سيفعل هذا الكود تمامًا نفس عمل الكود الذي يتحقق من الأحرف.
إذا كان الحرف الذي تم استقباله هو أحد أحرف الأرقام ، فسيتم طباعة حرف الرقم. تهتم عبارة else بأي حرف ليس حرفًا لرقم .

الحصول على إدخال السلسلة Getting String Input
تم استخدام البرنامج السابق للحصول على ومعالجة حرف واحد في كل مرة. سيكون أكثر فائدة إذا تمكنا من الحصول على سلسلة كاملة في كل مرة ، ثم يمكننا الحصول على اسم كدخل ، أو عدد number يتكون من أكثر من رقم digit واحد.

إيجاد نهاية سلسلة Finding the End of a String
السلسلة String هي سلسلة series من الأحرف. حتى نتمكن من قراءة سلسلة من المنفذ التسلسلي في Arduino ، سنحتاج إلى معرفة متى تنتهي السلسلة. إحدى الطرق للقيام بذلك هي إدراج حرف سطر جديد newline في نهاية السلسلة. حرف سطر جديد هو حرف ASCII غير قابل للطباعة يسمى "تغذية السطر" "line feed" في جدول كود ASCII.
حرف line feed له القيمة 10 عشرى ولكن يمكن كتابته كرمز هروب escape في برنامج الاردوينو على النحو التالي: '\n' .
البرنامج التالي هو نسخة معدلة من البرنامج السابق. بالإضافة إلى التحقق مما إذا تم استلام رقم number أو غير رقم non-number ، فإنه يتحقق أيضًا من استلام حرف السطر الجديد newline .
عند تشغيل البرنامج وإرسال حرف من نافذة Serial Monitor ، يجب تغيير إعداد في أسفل نافذة Serial Monitor بحيث يتم إلحاق حرف سطر جديد بالحرف المرسل كما هو موضح في الصورة أسفل البرنامج .

كود:
void setup() {
  Serial.begin(9600);
}

char rx_byte = 0;

void loop() {
  if (Serial.available() > 0) {    // is a character available?
    rx_byte = Serial.read();       // get the character
  
    // check if a number was received
    if ((rx_byte >= '0') && (rx_byte <= '9')) {
      Serial.print("Number received: ");
      Serial.println(rx_byte);
    }
    else if (rx_byte == '\n') {
      Serial.println("Newline");
    }
    else {
      Serial.println("Not a number.");
    }
  } // end: if (Serial.available() > 0)
}

قبل تشغيل البرنامج ، تأكد من ضبط نافذة شاشة Arduino Serial Monitor على "Newline" كما هو موضح في هذه الصورة.



عندما يتم تعيين "Newline" في نافذة Serial Monitor ، فإن كل ما يتم كتابته في حقل "send" في نافذة Serial Monitor ، سيتبعه حرف سطر جديد.
تم استخدام else if لاختبار إذا ما تم تلقي حرف سطر جديد كما هو موضح في هذا السطر من التعليمات البرمجية.

كود:
else if (rx_byte == '\n') {

يتحقق هذا الكود من وجود حرف السطر الجديد الذي يمثله '\n' ويطبع "Newline" في نافذة Serial Monitor إن وجدت.

قراءة سلسلة Reading a String
يقرأ البرنامج أدناه سلسلة في Arduino ويستخدم حرف السطر الجديد لتحديد متى تنتهي السلسلة.

كود:
void setup() {
  Serial.begin(9600);
  Serial.println("Enter your name.");
}

char rx_byte = 0;
String rx_str = "";

void loop() {
  if (Serial.available() > 0) {    // is a character available?
    rx_byte = Serial.read();       // get the character
    
    if (rx_byte != '\n') {
      // a character of the string was received
      rx_str += rx_byte;
    }
    else {
      // end of string
      Serial.print("Welcome ");
      Serial.println(rx_str);
      rx_str = "";                // clear the string for reuse
      Serial.println("");
      Serial.println("Enter your name.");
    }
  } // end: if (Serial.available() > 0)
}

يتم الحصول على كل حرف فردي من السلسلة بنفس الطريقة مثل البرامج السابقة وتخزينها في المتغير rx_byte.
إذا لم يكن الحرف مساويًا لحرف السطر الجديد ، فسيتم إضافته إلى الكائن rx_str للفئة String.

كود:
 if (rx_byte != '\n') {
  // a character of the string was received
  rx_str += rx_byte;
}

سطر الكود

كود:
rx_str += rx_byte;

بالضبط مثل:

كود:
rx_str = rx_str + rx_byte;

فهو ببساطة يضع كل حرف في نهاية السلسلة لبناء السلسلة من الأحرف المستلمة.
بعد تجميع السلسلة ، سيتم استلام حرف السطر الجديد الذي سيقوم بعد ذلك بتشغيل عبارة else ويتم طباعة السلسلة المستلمة إلى نافذة Serial Monitor كجزء من رسالة ترحيب.

الحصول على رقم Getting a Number
عندما يتم استلام رقم من نافذة Serial Monitor ، فإنه يكون عبارة عن سلسلة من أحرف الأرقام ويجب تحويلها إلى رقم يمكن تخزينه في متغير لرقم مثل عدد صحيح أو int .
يتحقق البرنامج التالي لمعرفة أن الأحرف المستلمة هي أحرف رقمية ثم يحول الرقم إلى عدد صحيح.

كود:
void setup() {
  Serial.begin(9600);
  Serial.println("Enter a number to multiply by 2.");
}

char rx_byte = 0;
String rx_str = "";
boolean not_number = false;
int result;

void loop() {
  if (Serial.available() > 0) {    // is a character available?
    rx_byte = Serial.read();       // get the character
    
    if ((rx_byte >= '0') && (rx_byte <= '9')) {
      rx_str += rx_byte;
    }
    else if (rx_byte == '\n') {
      // end of string
      if (not_number) {
        Serial.println("Not a number");
      }
      else {
        // multiply the number by 2
        result = rx_str.toInt() * 2;
        // print the result
        Serial.print(rx_str);
        Serial.print(" x 2 = ");
        Serial.print(result);
        Serial.println("");
        Serial.println("Enter a number to multiply by 2.");
      }
      not_number = false;         // reset flag
      rx_str = "";                // clear the string for reuse
    }
    else {
      // non-number character received
      not_number = true;    // flag a non-number
    }
  } // end: if (Serial.available() > 0)
}

• بناء السلسلة Building the String
يتم بناء سلسلة من الأحرف المستلمة كما تم في البرنامج السابق. إذا كان أي حرف مستلم ليس حرف رقم ، فسيتم تعيين المتغير not_number على true كإشارة أو"علم" flag على أنه تم استلام حرف غير رقمي.

• استخدام العلم المنطقي Using a Boolean Flag
المتغير not_number هو من نوع Boolean (منطقي) يمكن أن يكون له قيمة صواب true أو خطأ false . في البرنامج ، يتم استخدام هذا المتغير كعلامة flag يتم التحقق منها لاحقًا لمعرفة ما إذا تم استلام أي أحرف غير رقمية.
بعد استلام السلسلة الكاملة ، التي تحدث عند استلام حرف السطر الجديد ، يتم التحقق من علامة المتغير not_number ويتم عرض رسالة إذا لم يكن أي حرف تم استلامه رقمًا.

• معالجة السلسلة Processing the String
إذا كانت جميع الأحرف المستلمة عبارة عن أرقام ، يتم تحويل السلسلة إلى عدد صحيح باستخدام rx_str.toInt() ، مضروبة في 2 والنتيجة تخزن في المتغير result . نتيجة الحساب يتم طباعتها في نافذة المراقبة التسلسلية.

• قيود البرنامج Sketch Limitations
هناك بعض القيود على هذا البرنامج . لا يمكننا الحصول على نتيجة عند إرسال رقم سالب إلى Arduino لأن علامة الطرح ستؤدي إلى إنطلاق (تشغيل) علامة المتغير not_number. حجم الرقم الذي يمكن ضربه محدود أيضًا بحجم عدد موجب على Arduino.




الساعة معتمدة بتوقيت جرينتش +3 الساعة الآن: 04:56 PM
موقع القرية الالكترونية غير مسؤول عن أي اتفاق تجاري أو تعاوني بين الأعضاء
فعلى كل شخص تحمل مسئولية نفسه إتجاه مايقوم به من بيع وشراء وإتفاق وأعطاء معلومات موقعه
التعليقات المنشورة لا تعبر عن رأي موقع القرية الالكترونية ولايتحمل الموقع أي مسؤولية قانونية حيال ذلك (ويتحمل كاتبها مسؤولية النشر)