علوم الحاسب

[سلسلة تعلم الأردوينو] التعامل مع المنافذ التسلسلية

توفر لوحة الأردوينو طريقة سهلة لإنشاء قناة اتصال تسلسلية يمكن عبرها تبادل المعلومات بين الأردوينو والحاسوب أو بين الأردوينو ومتحكمات صغرية أخرى

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

1. حول الاتصالات التسلسلية ومعيار UART

عندما نريد إرسال المعلومات بين جهازين إلكترونيين، فإنه يوجد طريقتين أساسيتين لتنفيذ ذلك: إما بشكلٍ تسلسليّ Serial أو تفرعيّ Parallel. أصبحت الاتصالات التسلسلية أكثر انتشاراً بسبب الإيجابيات التي توفرها من ناحية الكلفة وسهولة بناء قناة الاتصال وكشف الأخطاء، وبهذا السياق يبرز اسم معيار UART، أو المرسل / المستقبل غير المتزامن الشامل، الذي يُعتبر من أشهر معايير الاتصالات التسلسلية وأكثرها انتشاراً في مجال المتحكمات الصغرية والأنظمة المدمجة، كما أنها يعتبر أساساً لمعايير اتصالات تسلسلية أخرى أكثر تعقيداً.

بشكلٍ أساسيّ، يتطلب إنشاء قناة اتصال تسلسلي بين جهازين باستخدام معيار UART وجود ثلاث أسلاك (نواقل):

  • سلك إرسال البيانات Tx
  • سلك استقبال البيانات Rx
  • التأريض GND
مبدأ الاتصال التسلسليّ بين جهازين

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

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

2. استخدام بروتوكول الاتصال التسلسلي غير المتزامن UART في لوحة الأردوينو

تدعم لوحات الأردوينو الاتصال التسلسلي عبر معيار UART، ولمعرفة المغارز المستخدمة في عملية الاتصال التسلسليّ، فهي دوماً المغارز الموسومة بالرموز Tx و Rx، وهي تشير إلى المغرز المستخدم لإرسال البيانات (Tx) والمغرز المستخدم لاستقبال البيانات (Rx). تعمل مغارز الاتصالات التسلسلية عند المجال المنطقي TTL عند 5 فولت وبعضها يعمل على منطق CMOS عند 3.5 فولت، وذلك بحسب نوع اللوحة المستخدمة.

تحتوي جميع لوحات أردوينو على منفذ تسلسلي واحد على الأقل وتمتلك بعض اللوحات عدة منافذ اتصال تسلسلي باستخدام معيار UART بما يتيح وصل اللوحة على الحاسب (أي أن منفذ واحد سيكون مشغول) وإجراء عملية اتصال تسلسلي مع متحكم صغري آخر أو لوحة أردوينو أخرى. لتوضيح هذا الأمر علينا تسليط الضوء على بعض التفاصيل المتعلقة بربط الأردوينو بالحاسب: من أجل بناء قناة اتصال تسلسليّ بين أي جهازين عبر معيار UART، فإن كلا الجهازين سيحتاج إلى طرفية أو دارة تدعم الإرسال والاستقبال عبر UART. هذا ما يحصل بحالة الأردوينو عند ربطه بالحاسب؛ تتضمن لوحة الأردوينو وحدة تحويل تقوم بجعل الرسائل والبيانات المنقولة على قناة UART متوافقة وقابلة للنقل على معيار USB (معيار USB هو أيضاً معيار اتصال تسلسلي). تقوم هذه الوحدة بالعملية المعاكسة، أي تحويل الرسائل الواردة من منفذ USB إلى شكلٍ متوافق مع UART بحيث يتم فهمها ومعالجتها بشكلٍ صحيح من قبل المتحكم الصغري في لوحة الأردوينو، وهذه هي الطريقة التي يتم عبرها تبادل البيانات بين لوحة الأردوينو والحاسب.

بالعودة للوحات الأردوينو الشهيرة، ومن أجل معرفة المغارز الخاصة بمنافذ الاتصال التسلسلي، فهي كما يلي:

Nano-Mini-Uno: المغرز الرقمي 0 مخصص للاستقبال RX و المغرز الرقمي 1 مخصص للإرسال TX.

Mega Arduino: يتوفر 4 منافذ UART متوزعة على المغارز الرقمية ضمن اللوحة كما يلي:

  • TX هو المغرز الرقمي 1, و RX هو المغرز الرقمي 0.
  • TX هو المغرز الرقمي 18, و RX هو المغرز الرقمي 19.
  • TX هو المغرز الرقمي 16, و RX هو المغرز الرقمي 17.
  • TX هو المغرز الرقمي 14, و RX هو المغرز الرقمي 15.

3. بروتوكول الاتصال التسلسلي غير المتزامن UART البرمجي في لوحة الأردوينو (Software UART)

إذا لم يكن المتحكم الدقيق يحتوي على UART (أو لم يكن لديه ما يكفي)، فيمكن استخدام مكتبة (SoftwareSerial.h) لاستخدام مغارز رقمية أخرى مختلفة عن السابقة كخطوط اتصال تسلسلي RX وTX، وتكون الواجهة التسلسلية متحكم بها من قبل المعالج مباشرة. تُعرف هذه العملية تقنياً باسم “ضرب البت” أو “تقسيم البت” Bit-Banging، وتُعتبر من التقنيات التي تستهلك موارد المعالج، كما أنها قد لا توّفر نفس الدقة التي توفرها المغارز المتصلة مباشرةً بطرفية الاتصال التسلسليّ UART.

4. التعليمات البرمجية المستخدمة بالاتصال التسلسلي

تتضمن بيئة الأردوينو نمطاً يمكن عبره إرسال واستقبال الأوامر عبر منفذ (أو منافذ) الاتصالات التسلسلية المتوفرة في لوحة الأردوينو، وهذا النمط هو Serial. تتضمن بيئة الأردوينو مراقب أو نافذة للاتصالات التسلسلية Serial Monitor التي يمكن عبرها عرض أوامر مختلفة أو حتى إرسال تعليمات إلى لوحة الأردوينو عبر منفذ الاتصالات التسلسلية. يمكن فتح نافذة الاتصالات التسلسلية ضمن بيئة الأردوينو البرمجية عبر النقر على إشارة المكبرة الموجودة أعلى يمين بيئة التطوير البرمجية، كما تُظهر الصورة التالية التي قمنا فيها بإحاطة الزر الخاص بفتح نافذة الاتصال التسلسلي بمربعٍ أحمر.

كما ذكرنا آنفاً، يتيح النمط Serial تنفيذ العديد من الأوامر المتعلقة بمنفذ الاتصالات التسلسلية، وأشهر الأوامر (أو التوابع) التي يمكن استدعاؤها عبر النمط Serial هي كما يلي:

Serial.begin(baudrate) : تهيئة واجهة التخاطب التسلسلية للاستخدام، وسيط التابع هو معدل التراسل بين المرسل والمستقبل وواحدته بت في الثانية bps، شرط الحصول على اتصال تسلسلي غير تزامني سليم أن يكون كلا الطرفي مهيئين على نفس معدل التراسل (سرعة التخاطب).

if(Serial) : يشير إلى ما إذا كان المنفذ التسلسلي المحدد جاهزًا. يعيد قيمة True إذا كان المنفذ التسلسلي المحدد متاحًا، ويرجع False فقط إذا كان الاستعلام عن اتصال USB CDC التسلسلي قبل أن يصبح جاهزًا. نوع البيانات: bool

Serial.available() : من خلال هذا التابع نحصل على عدد البايتات (الأحرف) الجاهزة للقراءة من المنفذ التسلسلي. هذه هي البيانات التي وصلت بالفعل وتم تخزينها في المخزن المؤقت للاستلام التسلسلي (الذي يحتوي على 64 بايت).

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

أمثلة على الأمر السابق:

Serial.print(78) //gives "78"
Serial.print(1.23456) //gives "1.23"
Serial.print('N') //gives "N"
Serial.print("Hello world.") //gives "Hello world."

يحدد الوسيط الثاني الاختياري التنسيق المراد استخدامه و القيم التي يأخذها هي :
BIN  ثنائي ،OCT ثماني ، DECعشري ،HEX  سداسي عشر.
بالنسبة لأرقام الفاصلة العائمة، يحدد هذا الوسيط الاختياري عدد المنازل العشرية المراد استخدامها. على سبيل المثال:

Serial.print(78, BIN) //gives "1001110"
Serial.print(78, OCT) //gives "116"
Serial.print(78, DEC) //gives "78"
Serial.print(78, HEX) //gives "4E"
Serial.print(1.23456, 0) //gives "1"
Serial.print(1.23456, 2) //gives "1.23"
Serial.print(1.23456, 4) //gives "1.2345"

Serial.println() : يطبع البيانات إلى المنفذ التسلسلي كنص ASCII قابل للقراءة البشرية متبوعًا بحرف إرجاع  \r و حرف سطر جديد \n يأخذ هذا الأمر نفس أشكال Serial.print() .

Serial.read() : يقرأ البايت الأول من البيانات التسلسلية الواردة المتاحة، نوع البيانات: int.

Serial.readString() : يقرأ الأحرف من المخزن المؤقت التسلسلي في سلسلة.

Serial.write() : يكتب البيانات الثنائية إلى المنفذ التسلسلي. يتم إرسال هذه البيانات على هيئة بايت أو سلسلة من البايتات؛ لإرسال الأحرف التي تمثل أرقام استخدم الأمر print () بدلاً من ذلك , سيعيد write() عدد البايتات المكتوبة، على الرغم من أن قراءة هذا الرقم اختيارية.

Serial.parseFloat() : يُرجع أول رقم فاصلة عائمة صالح من المخزن المؤقت التسلسلي.
يتم تجاهل جميع الأحرف باستثناء علامة الطرح أو الفاصلة العشرية أو الأرقام عند مسح التدفق بحثًا عن رقم فاصلة عائمة. هذا هو الوضع الافتراضي (SKIP_ALL).

Serial.end()‎ : يعطِّل التابع الاتصال التسلسلي المفتوح محرِّر بذلك المغارز الرقمية 0 و1 لتصبح قابلةً للاستعمال كدخل أو خرج رقمي.

إن استعملت إحدى الدوال الموجودة في القسم السابق في تهيئة واجهة التخاطب التسلسلية والبدء باستعمالها، فلن تتمكن من استعمال المنافذ 0 و1 من أجل الدخل أو الخرج الرقمي بعدئذٍ.

5. مشروع بسيط: إضاءة ثنائي مُصدر للضوء باستخدام لوحة أردوينو أونو باستخدام نافذة المراقب التسلسلي

من أجل توضيح الأفكار السابقة وفهم كيفية تنفيذها مع بعضها البعض، سنقوم بتنفيذ برنامج بسيط وهو إضاءة ثنائي مصدر للضوء (ليد LED) بحيث يُضيء المصباح عند إرسال المحرف “T” ويتوقف عن العمل عند إرسال المحرف “F”، وبكلا المحرفين يطبع حالة الثنائي المصدر للضوء.

1.5 العتاد المستخدم
  • لوحة أردوينو أونو Arduino UNO، أو أي لوحة متوافقة معها.
  • لوحة تجريب إلكترونية.
  • أسلاك توصيل Jumper-Wire.
  • ديود ضوئي LED.
  • مقاومة أومية 220 أوم.
2.5 البرامج المستخدمة
  • بيئة التطوير الرسمية الخاصة بلوحات الأردوينو
3.5 توصيل العتاد

يتم توصيل الديود الضوئي مع المقاومة الأومية على المغرز الرقمي 13 وفق مخطط الدارة الآتي:

4.5 الشيفرة البرمجية
/***************************************************************
                Reading Characters From Serial Monitor
****************************************************************/

int pin_led     = 13;    // LED pin
char key; // Save the received character
bool led_state  = 0;    // Save led state

void setup()
{
  // Initlize The Serial Monitor with baud rate 9600 bps
  Serial.begin(9600);
  pinMode(pin_led, OUTPUT);
}

void loop()
{

  // Check if any bytes is ready on serial port
  if (Serial.available() > 0)
  {
    // read the received character and save it in key variable
    key = Serial.read();

    //check the saved character
    if (key == 'T')
    {
      // Make the state of boolean variable = HIGH
      led_state = HIGH;

      // Print "The led Is On" on Serial monitor and make new line
      Serial.println("The led Is On");

    }
    else if (key == 'F')
    {
      // Make the state of boolean variable = LOW
      led_state = LOW;

      // Print "The led Is Off" on Serial monitor and make new line
      Serial.println("The led Is Off");
    }
  }

  digitalWrite(pin_led, led_state );
}

نتيجة تنفيذ المثال السابق

النافذة السابقة تدعى نافذة المراقب التسلسلي، تم تعليم 5 تفاصيل منها وهي:

  1. موضع إدخال المحارف سواء كانت سلاسل أو أرقام أو رموز أو أحرف.
  2. Send: هو زر الإرسال للمتحكم.
  3. AutoScroll: الهدف منها تحريك الصفحة التي يتم الطباعة عليها عند امتلائها بالمحتوى (للتوضيح أكثر جرب إلغاء تعليمها عند امتلاء الصفحة وراقب النتيجة)
  4. سرعة التخاطب والتي تم تحديدها ضمن الشيفرة البرمجية باستخدام التعليمة begin().
5.5 أفكار تطويرية
  • يمكنك تجريب الشيفرة السابقة مع تغير المحارف المستخدمة “T”، “F”.
  • يمكنك عمل دارة مكونة من مفتاحين ضاغطين أحدهما لتشغيل ديود ضوئي والآخر لإطفائه مع طباعة حالة المفتاح ضمن نافذة المراقب التسلسلي وملاحظة تطوير لشيفرة البرمجية شيئا فشيء. يمكن الاستفادة بحل هذا التطوير من المقال السابق: قراءة الإشارات الرقمية في لوحة الأردوينو
  • يمكنك تجريب التعليمات المذكورة بالقسم النظري في الأعلى ومشاهدة النتائج.

6. ملخص

  • يتيح الاتصال التسلسلي نقل البيانات والمعلومات في الأنظمة الرقمية بشكلٍ متتالي، أي عبر الإرسال البتات الواحدة تلو الأخرى، بخلاف الاتصال التفرعي الذي يتيح إرسال مجموعة من البتات مع بعضها البعض بنفس الوقت
  • يعتبر المرسل / المستقبل غير التزامني الشامل UART أحد أشهر أنواع معايير الاتصال التسلسلي وأكثرها استخداماً في مجال الأنظمة المدمجة
  • تمتلك لوحة أردوينو أونو نافذة واحدة للاتصال التسلسلي الغير متزامن UART يمكن استخدامها لتحقيق اتصال بين المتحكم المضمن على اللوحة ومتحكم أو حاسب آخر.
  • عند استخدام هذه النافذة لا يمكن استخدام المغرزين الرقميين 0 , 1 كمداخل ومخارج رقمية.
  • تستخدم نافذة المراقب التسلسلي لطباعة رسائل معينة أو قراءة خرج حساس معين ويمكن أيضا من خلالها التواصل مع طرفيات من أجل برمجتها مثل لوحة البلوتوث HC-05 ويمكن استخدامها كما في المثال السابق لإرسال بيانات للمتحكم.

Mouhamad Hadid

مهندس في الالكترونيات و الاتصالات من جامعة دمشق مهتم بعالم الالكترونيات الرقمية و المتحكمات وأنظمة الـ IOT والتيار الخفيف.

مقالات ذات صلة

زر الذهاب إلى الأعلى