دمج الوحدات · الدرس 3.3
التحكم بالمصابيح من المراقب التسلسلي
العودة إلى الدروسإرسال الأوامر من الحاسوب
يبني هذا الدرس على 2.22، ويضيف التحكم في LEDs من الحاسوب عبر Serial Monitor. فهو يرسل النصوص ويستقبلها عبر USB، مما يفيد التصحيح والتحكم من لوحة المفاتيح. استخدم المكونات نفسها وترتيبًا مشابهًا؛ نفذ 2.22 أولًا إن لم تكن أعددته.
التجربة
بعد الرفع اضغط زر المراقب التسلسلي في أقصى يمين شريط IDE. يشرح الدرس 2.4 «المراقب التسلسلي» طريقة فتح الأداة وضبط سرعة الاتصال وقراءة البيانات. تظهر نافذة لإرسال الرسائل إلى UNO واستقبالها.

تعني الرسالة Enter LED Number 0 to 7 or 'x' to clear: أدخل رقم LED من 0 إلى 7 أو x لإطفاء الجميع. الرقم 0 للمصباح السفلي، ثم 1 للأعلى منه، حتى 7 في الأعلى.

اكتب x ثم 0 ثم 3 ثم 5 في خانة الإرسال، واضغط Send بعد كل محرف. x لا يغير شيئًا إذا كانت جميع LEDs مطفأة. كل رقم يشغل LED الموافق، وترسل اللوحة تأكيدًا. أرسل x مجددًا لإطفاء الجميع.

البرنامج والاتصال التسلسلي
افتح ملف البرنامج The_Serial_Monitor.ino من ملفات الدرس في بيئة Arduino IDE. بعد إتمام التوصيلات، وصّل لوحة أردوينو (UNO R3 Board) بالحاسوب بكابل توصيل (USB Cable)، ثم اضغط زر Upload (رفع) لنقل البرنامج إلى اللوحة وتشغيله عليها.
إذا تعذر نقل البرنامج إلى اللوحة، فراجع قسم «رفع البرنامج ومعالجة خطأ الاتصال» في الدرس 1.5 «وميض LED وإضافة المكتبات» للتحقق من اتصال USB واختيار نوع اللوحة والمنفذ التسلسلي في بيئة Arduino IDE.
يعتمد على كود 2.22؛ نشرح هنا الإضافات إلى البرنامج؛ افتح نسخته الكاملة في IDE لمتابعة الشرح.
setup()
تضاف ثلاث تعليمات. Serial.begin(9600) يبدأ الاتصال عبر USB بمعدل 9600 baud. إذا غيرته، يجب أن تغير معدل المراقب إلى القيمة نفسها؛ اتركه 9600 الآن.
Serial.begin(9600);
while (!Serial);
Serial.println("Enter LED Number 0 to 7 or 'x' to clear");تنتظر while جاهزية الطرف الآخر حتى لا تضيع الرسالة الأولى. تحتاجها Leonardo؛ أما UNO فتعيد الضبط تلقائيًا عند فتح المراقب. ترسل println() رسالة التعليمات.
loop()
تنفذ loop() الأوامر داخل شرط Serial.available(). تعيد الدالة عدد بايتات البيانات المتاحة في المخزن المؤقت (Buffer). إذا كانت القيمة أكبر من صفر، توجد بيانات جاهزة للمعالجة؛ وإذا كان المخزن فارغًا، لا تُنفَّذ بقية الكتلة.
قراءة المحارف وتحديث LEDs
char ch = Serial.read();تقرأ التعليمة المحرف التالي وتحذفه من Buffer وتحفظه في ch. نوع char يحمل محرفًا واحدًا. حسب التعليمات يكون 0–7 أو x.
يفحص الشرط ch >= '0' && ch <= '7'. لكل محرف قيمة ASCII فريدة؛ لذلك تقارن <= و>= هذه القيم العددية، وهو استخدام صحيح.
int led = ch - '0';
bitSet(leds, led);
updateShiftRegister();
Serial.print("Turned on LED ");
Serial.println(led);طرح '0' يحول المحرف إلى الرقم: '0'-'0' يساوي 0، و '7'-'0' يساوي 7 لأن الحساب يستخدم ASCII. ثم يضبط البت في leds ويحدث المسجل.
تطبع print() الجزء الأول دون الانتقال لسطر جديد، ثم تطبع println() رقم LED وتنهي السطر. الرقم int لا نص؛ ويمكن print() طباعة نص بين علامتي اقتباس أو int أو أنواع أخرى عديدة.
تفحص if ثانية ما إذا كان ch يساوي 'x'. عندئذ تصفر leds وتحدث المسجل وترسل Cleared لإبلاغ المستخدم بإطفاء الجميع.
الكود
The_Serial_Monitor/The_Serial_Monitor.ino
//www.elegoo.com
//2016.12.9
int latchPin = 11;
int clockPin = 9;
int dataPin = 12;
byte leds = 0;
/* The most common method of using 74CH595
* lctchPin->LOW : Begin transmitting signals.
* shiftOut(dataPin, clockPin, bitOrder, value)
* dataPin: the pin on which to output each bit. Allowed data types: int.
* clockPin: the pin to toggle once the dataPin has been set to the correct value. Allowed data types: int.
* bitOrder: which order to shift out the bits; either MSBFIRST or LSBFIRST. (Most Significant Bit First, or, Least Significant Bit First).
* value: the data to shift out. Allowed data types: byte.
* lctchPin->HIch : The end of the transmission signal.
*/
void updateShiftRegister()
{
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, LSBFIRST, leds);
digitalWrite(latchPin, HIGH);
}
void setup()
{
pinMode(latchPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
updateShiftRegister();
Serial.begin(9600);
while (! Serial); // Wait untilSerial is ready - Leonardo
Serial.println("Enter LED Number 0 to 7 or 'x' to clear");
}
void loop()
{
if (Serial.available())//judge the serial if receive data
{
char ch = Serial.read();//Read serial data and save it in "ch"
if (ch >= '0' && ch <= '7') //If the data of "ch" is the character'0'~character'7'
{
int led = ch - '0'; //Converting strings to binary numbers example: '0' -> 0 or '1' -> 1
bitSet(leds, led);
updateShiftRegister();
Serial.print("Turned on LED ");
Serial.println(led);
}
if (ch == 'x')
{
leds = 0;
updateShiftRegister();
Serial.println("Cleared");
}
}
}