كيف أجبر طريقة كتابة المنفذ التسلسلي على الانتظار حتى يتم مسح الخط قبل إرسال بياناته؟

StackOverflow https://stackoverflow.com/questions/222455

سؤال

إليك بعض المعلومات الأساسية عما أحاول القيام به:

  1. افتح منفذًا تسلسليًا من جهاز محمول إلى طابعة Bluetooth.
  2. أرسل نموذج EPL/2 إلى طابعة البلوتوث، حتى تفهم كيفية التعامل مع البيانات التي على وشك استلامها.
  3. بمجرد استلام النموذج، أرسل بعض البيانات إلى الطابعة والتي سيتم طباعتها على مخزون الملصقات.
  4. كرر الخطوة 3 عدة مرات حسب الضرورة حتى تتم طباعة كل ملصق.

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

لقد وجدت طريقة للتغلب على المشكلة عن طريق القيام بما يلي:

for (int attempt = 0; attempt < 3; attempt++)
{
    try
    {
        serialPort.Write(labelData);
        break;
    }
    catch (TimeoutException ex)
    {
        // Log info or display info based on ex.Message
        Thread.Sleep(3000);
    }
}

لذا، في الأساس، يمكنني التقاط TimeoutException وإعادة محاولة طريقة الكتابة بعد الانتظار لفترة معينة من الوقت (يبدو أن ثلاث ثوانٍ تعمل طوال الوقت، ولكن أقل من ذلك ويبدو أنها تطرح الاستثناء في كل محاولة).بعد ثلاث محاولات، أفترض أن المنفذ التسلسلي به خطأ ما وأعلم المستخدم بذلك.

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

فيما يلي قائمة بالخصائص التي لعبت بها:

  • CDHolding
  • CtsHolding
  • DsrHolding
  • DtrEnable
  • مصافحة
  • رتسينابل

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

أنا أستخدم C# (إطار عمل 2.0)، وطابعة Bluetooth Zebra QL 220+ وجهاز محمول يعمل بنظام Windows Mobile 6، إذا كان ذلك يُحدث أي فرق في الحلول.

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

[تحديث]

يجب أن أشير أيضًا إلى أن الجهاز المحمول يستخدم Bluetooth 2.0، في حين أن الطابعة تعمل بالإصدار 1.1 فقط.أفترض أن فرق السرعة هو ما يتسبب في تأخر الطابعة في تلقي البيانات.

هل كانت مفيدة؟

المحلول

التحكم في التدفق هو الإجابة الصحيحة هنا، وقد لا يكون موجودًا/منفذًا/قابلاً للتطبيق على اتصال البلوتوث الخاص بك.

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

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

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

-آدم

نصائح أخرى

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

serialPort.Handshake = Handshake.RequestToSendXOnXOff;
serialPort.WriteTimeout = 10000; // Could use a lower value here.

ثم أحتاج فقط إلى إجراء مكالمة الكتابة:

serialPort.Write(labelData);

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

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

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

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

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

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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top