الأجهزة التسلسلية وArduino
تتواصل الدوال المضمَّنة Serial* مع أي شيء يظهر كمنفذ COM: لوحة Arduino أو ESP32 أو Raspberry Pi Pico
عبر USB، أو محوّل من USB إلى منفذ تسلسلي، أو جهاز استقبال GPS، أو ماسح رموز شريطية في الوضع التسلسلي، أو
طابعة إيصالات أو ملصقات، أو طابعة ثلاثية الأبعاد أو وحدة تحكم CNC تقبل G-code، أو جهاز مختبري، أو صندوق
أزرار أو لوحة ماكرو أو مقبض دوار أو وحدة تحكم LED مصنوعة يدويًا. يرسل الجهاز أسطرًا نصية ويستقبلها؛ وتحوّل
برامجك النصية تلك الأسطر إلى أي شيء آخر يستطيع Input.Observer فعله.
بعض الأفكار:
- صندوق أزرار أو لوحة ماكرو. تقرأ لوحة Arduino أزرارها وتطبع
B1وB2و... يحوّل مراقب المنفذ التسلسلي كل سطر إلى اختصار أو مفتاح وسائط أو أمر نافذة. - مقبض لمستوى الصوت أو التمرير. يطبع مقياس الجهد أو المشفّر الدوار موضعه؛ ويضبط المراقب مستوى الصوت أو يمرّر.
- أضواء الحالة. ترسل إيماءة أو مفتاح اختصار
LED 255 0 0إلى لوحة تتحكم في شريط LED، فيُظهر ضوء أن التسجيل قيد التشغيل أو أن البناء فشل. - أجهزة الاستشعار. يطلب مؤقت من لوحة درجة الحرارة أو مستوى الإضاءة ويعرضه، أو يسجله في ملف، أو يخفّت الشاشة.
- الماسحات والقارئات. يصبح كل رمز شريطي أو علامة RFID يرسلها القارئ نصًا مكتوبًا، أو بحثًا، أو استعلامًا في ملف.
- الآلات. أرسل أسطر G-code إلى طابعة أو راسمة، استدعاء
SerialWriteTextLineواحد لكل أمر.
العثور على المنفذ
يعطي Windows كل جهاز اسمًا مثل COM3. تسرده «إدارة الأجهزة» ضمن المنافذ (COM وLPT)؛ وتعرضه
Arduino IDE في قائمة اللوحات الخاصة بها. يمكن للبرنامج النصي أيضًا سردها:
n = SerialEnumeratePorts();
if (n == 0) UtilityPrint("No COM ports. Is the board plugged in?");
for (i = 0; i < n; i = i + 1) {
UtilityPrint(SerialGetEnumeratedPortAt(i));
}
تُفرز القائمة حسب الرقم، لذا يأتي COM3 قبل COM10. قد يتغير الرقم عند نقل الجهاز إلى مقبس USB
آخر.
السرعة والتأطير ونهايات الأسطر
- السرعة (
baudRate) يجب أن تطابق الجهاز: الرقم الموجود فيSerial.begin(...)في رسم Arduino التخطيطي (sketch)، وعادةً9600أو115200. - التأطير يكون دائمًا تقريبًا 8 بتات بيانات، بلا تماثل، وبت توقف واحد:
8وSerialParity.NoneوSerialStopBits.One. اكتب الثوابت: الرقم المجرد1كوسيطة لبتات التوقف يعني بت توقف ونصفًا. - نهايات الأسطر. ينتهي السطر المستلم عند
terminatorالذي تحدده، ويُزال من السطر. النص الفارغ يعني CR LF، وهو ما ترسلهSerial.printlnفي Arduino. للجهاز الذي ينهي الأسطر بـ LF وحده، استخدم"\n"؛ ولـ CR وحده، استخدم"\r". تنهيSerialWriteTextLineما ترسله بـ terminator نفسه، أو بـ CR LF عندما يفتح الاستدعاء المنفذ بنفسه. مع CR LF، يحصل رسم Arduino التخطيطي الذي يقرأ باستخدامSerial.readStringUntil('\n')على السطر مع CR في نهايته، تزيلهtrim()؛ ومع"\n"لا يوجد CR لإزالته. - الإشارات. يؤدي فتح منفذ إلى تشغيل إشارتي DTR وRTS الخاصتين به، كما تفعل Arduino IDE. يعيد ذلك تشغيل معظم لوحات Arduino Uno وNano، واللوحات الأخرى التي لها دائرة إعادة التعيين نفسها.
ثلاث طرق للتواصل مع جهاز
-
سؤال واحد، إجابة واحدة. تفتح
SerialWriteTextLineوSerialGetTextLineالمنفذ غير المفتوح بسرعةbaudRateالخاصة بالاستدعاء، 8-N-1، لذلك الاستدعاء الواحد. يتم تجاهل الوسيطةbaudRateعندما يكون المنفذ مفتوحًا بالفعل. هذا مناسب للجهاز الذي لا يُعاد تشغيله عند فتح منفذه. راجع طرح سؤال على جهاز تسلسلي. -
منفذ يبقى مفتوحًا. تفتح
SerialOpenPortالمنفذ بإعداداتك حتىSerialClosePort، وتجمع كل سطر يرسله الجهاز لتقرأهSerialGetTextLine. تُعاد تشغيل معظم لوحات Arduino Uno وNano كلما فُتح منفذها، لذا افتح المنفذ مرة واحدة، في الحدث العام Load، ودع الإيماءات ومفاتيح الاختصار تكتب إليه. تُرجعSerialOpenPortالقيمةfalseللمنفذ المفقود أو المفصول أو المفتوح في برنامج آخر؛ أما المنفذ الذي فتحه Input.Observer بالفعل، أو الذي يحتجزه مراقب، فإنها توقف الإجراء بخطأ:// Load global event: open the port once, at the sketch's speed. An Uno or Nano// restarts every time its port opens, so a port opened per command would lose// the command while the board boots.if (!SerialOpenPort("COM4", 115200, SerialParity.None, 8, SerialStopBits.One, "")) {UtilityPrint("COM4 isn't available: unplugged, or open in the Arduino IDE's Serial Monitor?");}// Any gesture or hotkey: send a command line and read the board's reply.// (The sketch reads a line with Serial.readStringUntil('\n') and answers OK.)if (SerialWriteTextLine("COM4", "LED 255 0 0", 115200)) {reply = SerialGetTextLine("COM4", 1, 115200);if (reply != "OK") UtilityPrint(StringFormat("Board said: {0}", reply, ""));} -
مراقب. تشغّل
SerialMonitorCreateبرنامجًا نصيًا لكل سطر يرسله الجهاز، في الخلفية، حتىSerialMonitorDelete. السطر هوContextGetSerialTextLine(). راجع ربط أزرار جهاز تسلسلي بمفاتيح الوسائط و:// Arduino side: a potentiometer on A0, one reading per line.// void setup() { Serial.begin(115200); }// void loop() { Serial.println(analogRead(A0)); delay(50); }// Empty text as the terminator means CR LF, which Serial.println sends.SerialMonitorCreate("knob", "COM4", 115200, SerialParity.None, 8, SerialStopBits.One, "","line = ContextGetSerialTextLine(); if (StringIsNumber(line, true)) MultimediaSetVolume(AudioEndpoint.Playback, StringToNumber(line, true) / 1023.0);");
ما ينبغي معرفته عن المراقبات.
- تعمل الأسطر واحدًا تلو الآخر، بترتيب وصولها: يبدأ البرنامج النصي للسطر التالي عندما ينتهي البرنامج النصي للسطر السابق. ينتظر ما يصل إلى 256 سطرًا؛ وبعد ذلك يُتخلَّص من الأقدم.
- يؤدي إيقاف كل الإجراءات إلى إيقاف البرنامج النصي الذي يعمل لسطر والتخلص من الأسطر المنتظرة. ويستمر المراقب نفسه في العمل. أما مفتاح اختصار إيقاف كل الإجراءات فيذهب أبعد من ذلك: إذ يحذف كل مراقب ويغلق منفذه.
- يمكن لأي برنامج نصي، بما في ذلك البرنامج النصي للمراقب نفسه، الإرسال إلى منفذ خاضع للمراقبة باستخدام
SerialWriteTextLine، لذا يستطيع المراقب الرد على جهازه. لا تستطيعSerialGetTextLineالقراءة من منفذ خاضع للمراقبة: فكل سطر يذهب إلى المراقب. - كل اسم مراقب يخص منفذًا واحدًا. تستبدل
SerialMonitorCreateباسم مراقب هذا المنفذ ذلك المراقب. وتوقف الإجراء بخطأ عندما يكون الاسم يراقب منفذًا آخر بالفعل، أو عندما يكون المنفذ مفتوحًا باستخدامSerialOpenPort، أو عندما يحتجز مراقب آخر المنفذ. المنفذ المفقود أو المفصول أو المفتوح في برنامج آخر يعطيfalse. - يؤدي فصل الجهاز إلى إنهاء المراقب وكتابة سطر في علامة التبويب النظام في وحدة التحكم. لا شيء يعيد
تشغيل المراقب عند عودة الجهاز. شغّل
SerialMonitorCreateمرة أخرى (من مفتاح اختصار، أو من الحدث Load عند بدء التشغيل التالي).
لا يمكن إلا لبرنامج واحد أن يفتح منفذ COM. أثناء فتح Serial Monitor أو Serial Plotter في Arduino IDE،
لا يستطيع Input.Observer فتح المنفذ، وأثناء فتح Input.Observer له، لا تستطيع بيئة التطوير رفع رسم
تخطيطي. أغلق المنفذ (SerialClosePort أو SerialMonitorDelete) قبل الرفع.