إرسال أوامر متعددة إلى المنفذ التسلسلي وانتظر الرد قبل إرسال أمر آخر

[ad_1]

أهلاً بكم،

اطلب المساعدة بشأن بيانات المنفذ التسلسلي التي تم الحصول عليها.

لدي ملف مخزن أوامر متعددة.
أحتاج إلى إرسال الأمر واحدًا تلو الآخر إلى المنفذ التسلسلي وانتظر الرد والعرض لمواصلة إرسال الأمر الآخر.

أنا أستخدم thread.sleep بين كل أمر إرسال لكنه لا يعمل.

الرجاء المساعدة.

شكرًا

ما حاولت:

I'm using thread.sleep between each command send but it does not work. 

الحل 1

توقف عن اللعب بـ Thread.Sleep: ربما لن يساعدك ذلك.
الطريقة التي سأفعل بها ذلك هي إعداد قائمة انتظار من الأوامر، واستخدام حدث DataReceived للحصول على الاستجابة. عند اكتمال الاستجابة، أخرج الأمر التالي من قائمة الانتظار، وأرسله، واترك الحدث DataReceived يعالج استجابته عند وصوله.
عندما تكون قائمة الانتظار فارغة، تكون مجموعة الأوامر قد اكتملت.

الحل 2

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

بالنسبة لحالتك، ستحتاج إلى موضوع واحد على الأقل لتلقي الردود ونقل الأوامر الموضوعة في قائمة الانتظار.

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

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

يمكن أن يرسل مؤشر ترابط الإرسال ببساطة باستخدام مكالمة حظر لأنه يجب عليه الانتظار على أي حال. بعد الإرسال عليه أن ينتظر الرد المستلم للإشارة.

يمكنك وضع الإرسال والاستقبال في موضوع واحد أو موضوعين.

رمز زائف للاستلام (بافتراض البيانات النصية):

ج#
// Check for kill (terminate thread) event (wait with no timeout)
while (!KillEvent)
{
    do 
    {
        // Blocking call until a character is available
        // Should have a timeout and corresponding handling (break here)
        rxChar = ReceiveChar();
        Buffer += rxChar;
    }
    while (rxChar != '\n');
    // Signal other threads that a response has been received
    // Pass a copy of Buffer to the main thread for display
}

في سلسلة الإرسال، بعد إرسال الأمر، اتصل بما ورد أعلاه أو انتظر الحدث عندما يتم الاستلام في سلسلة الرسائل الخاصة.

باستخدام المواضيع والأحداث يمكنك تجنب الاتصال sleep والتي يجب تجنبها بشكل عام والتأكد من عدم إضاعة وقت النظام.

الحل 3

لي SerialDevice الطبقة هنا:
اتصالات متعددة الخيوط لواجهات GPIB/Visa/Serial[^]

ينفذ بالضبط العملية الموضحة في الحل 2 أعلاه: باستخدام الأوامر غير المتزامنة، يتم إجراء الإدخال/الإخراج في سلسلة رسائل منفصلة تستخدم مكالمات حظر بسيطة للكتابة/القراءة.

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

الحل 4

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

لكن لست متأكدًا مما إذا كانت هذه هي الطريقة الصحيحة للقيام بذلك.
مثال:
يكتب()؛
يقرأ()؛

[ad_2]

コメント

タイトルとURLをコピーしました