Timeout bei serieller Schnittstelle
-
Hallo Leute,
ich habe hier ein kleines Problem wo ich nicht weiter weiss. Das Programm öffnet eine serielle Schnittstelle (Im Konstruktor von Form1), ReadTimeout ist auf 3 Sekunden eingestellt. Wenn auf Button1 geklickt wird, dann wird zunächst ein String auf die Schnittstelle gesendet. Soweit funktioniert alles. Dann soll ein String von der Schnittstelle gelesen werden. Es kommt sofort folgende Fehlermeldung:
"An unhandled exception of type 'System.TimeoutException' occured in System.dll
Additional information: The operation has timed out."
Frage: Warum kommt diese Fehlermeldung sofort und nicht erst nach 3 Sekunden?Gruß
Michael#pragma once namespace test_7_11_11 { using namespace System; using namespace System::ComponentModel; using namespace System::Collections; using namespace System::Windows::Forms; using namespace System::Data; using namespace System::Drawing; /// <summary> /// Summary for Form1 /// /// WARNING: If you change the name of this class, you will need to change the /// 'Resource File Name' property for the managed resource compiler tool /// associated with all .resx files this class depends on. Otherwise, /// the designers will not be able to interact properly with localized /// resources associated with this form. /// </summary> public ref class Form1 : public System::Windows::Forms::Form { public: Form1(void) { InitializeComponent(); // //TODO: Add the constructor code here // serialPort1->Open(); } protected: /// <summary> /// Clean up any resources being used. /// </summary> ~Form1() { if (components) { delete components; } } private: System::IO::Ports::SerialPort^ serialPort1; private: System::Windows::Forms::Button^ button1; protected: private: System::ComponentModel::IContainer^ components; private: /// <summary> /// Required designer variable. /// </summary> #pragma region Windows Form Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> void InitializeComponent(void) { this->components = (gcnew System::ComponentModel::Container()); this->serialPort1 = (gcnew System::IO::Ports::SerialPort(this->components)); this->button1 = (gcnew System::Windows::Forms::Button()); this->SuspendLayout(); // // serialPort1 // this->serialPort1->PortName = L"COM2"; this->serialPort1->ReadTimeout = 3000; // // button1 // this->button1->Location = System::Drawing::Point(48, 168); this->button1->Name = L"button1"; this->button1->Size = System::Drawing::Size(112, 56); this->button1->TabIndex = 0; this->button1->Text = L"button1"; this->button1->UseVisualStyleBackColor = true; this->button1->Click += gcnew System::EventHandler(this, &Form1::button1_Click); // // Form1 // this->AutoScaleDimensions = System::Drawing::SizeF(6, 13); this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font; this->ClientSize = System::Drawing::Size(292, 266); this->Controls->Add(this->button1); this->Name = L"Form1"; this->Text = L"Form1"; this->ResumeLayout(false); } #pragma endregion private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { String^ s = "\001" + "S23170.0078" + "\027"; serialPort1->Write(s); s = serialPort1->ReadLine(); } }; }
-
P.S. Falls das von Bedeutung ist: Es ist keine echte serielle Schnittstelle, sondern ein Bluetooth-Dongle an einem USB Port. Schreiben auf die Schnittstelle funktioniert problemlos, der String kommt am anderen Ende an.
-
P.S.
Wenn ich kein ReadTimeout verwende (also auf -1 setze), dann kommt eine andere Fehlermeldung:"An unhandled exception of type 'System.IO.IOException' occured in System.dll
Additional information: The I/O operation has been aborted because of either a thread exit or an application request."Was hat das zu bedeuten?
Gruß
Michael
-
Hallo,
inzwischen habe ich selber eine Lösung gefunden. Es scheint so zu sein, dass die Methoden ReadChar und ReadLine mit diesem Bluetooth-Dongle nur dann funktionieren, wenn man vorher mit BytesToRead geprüft hat ob tatsächlich schon Daten vorhanden sind.
Am Rande ist noch eine andere Frage aufgetaucht:
Wie kann ich ein char in einen String der Länge 1 umwandeln?
Also wenn beispielsweise char a = 65 gegeben ist, dann möchte ich daraus nicht den String "65" erzeugen, sondern den String "A".Gruß
Michael
-
Hallo,
ich habe jetzt eine Methode geschrieben die eine Zeile von dem Bluetooth-Dongle liest, ohne dabei das problematische serialPort->readLine zu verwenden. Auch für die Umwandlung von char nach String habe ich eine Lösung gefunden, die funktioniert. Ich verstehe aber noch nicht, warum diese Umwandlung so kompliziert sein muss. Geht das auch irgendwie einfacher?
Gruß
MichaelString^ myReadLine(int timeout, char eol){ String^ s = ""; char c; do { if (serialPort1->BytesToRead > 0){ c = serialPort1->ReadChar(); s += System::Convert::ToString(System::Convert::ToChar(c)); // wie kann man das besser machen? } System::Threading::Thread::Sleep(1); timeout--; } while ((c != eol) && (timeout > 0)); return(s); }
-
Hallo,
s += System::Convert::ToString(System::Convert::ToChar(c));
Auch falls dies bereits die einfachste Lösung für das Problem sein sollte, so würde mich dennoch interessieren, warum man hier die Variable c (die als char deklariert ist), explizit nochmal in ein char umwandeln muss, um das gewünschte Ergebnis zu erhalten. Denn wenn ich stattdessen
s += System::Convert::ToString(c);
verwende, dann wird nicht das gewünschte Zeichen zum String addiert, sondern dessen ASCII-Code in Dezimaldarstellung.
Ich würde gerne verstehen warum das so ist. Es erscheint mir unlogisch dass ein char in ein char konvertiert werden muss.Gruß
Michael
-
micha7 schrieb:
Hallo Leute,
ich habe hier ein kleines Problem wo ich nicht weiter weiss. Das Programm öffnet eine serielle Schnittstelle (Im Konstruktor von Form1), ReadTimeout ist auf 3 Sekunden eingestellt. Wenn auf Button1 geklickt wird, dann wird zunächst ein String auf die Schnittstelle gesendet. Soweit funktioniert alles. Dann soll ein String von der Schnittstelle gelesen werden. Es kommt sofort folgende Fehlermeldung:
"An unhandled exception of type 'System.TimeoutException' occured in System.dll
Additional information: The operation has timed out."
Frage: Warum kommt diese Fehlermeldung sofort und nicht erst nach 3 Sekunden?Gruß
Michael#pragma once well this C++ coding is very helpful for me and i would like to use this for my flash websites. namespace test_7_11_11 { using namespace System; using namespace System::ComponentModel; using namespace System::Collections; using namespace System::Windows::Forms; using namespace System::Data; using namespace System::Drawing; /// <summary> /// Summary for Form1 /// /// WARNING: If you change the name of this class, you will need to change the /// 'Resource File Name' property for the managed resource compiler tool /// associated with all .resx files this class depends on. Otherwise, /// the designers will not be able to interact properly with localized /// resources associated with this form. /// </summary> public ref class Form1 : public System::Windows::Forms::Form { public: Form1(void) { InitializeComponent(); // //TODO: Add the constructor code here // serialPort1->Open(); } protected: /// <summary> /// Clean up any resources being used. /// </summary> ~Form1() { if (components) { delete components; } } private: System::IO::Ports::SerialPort^ serialPort1; private: System::Windows::Forms::Button^ button1; protected: private: System::ComponentModel::IContainer^ components; private: /// <summary> /// Required designer variable. /// </summary> #pragma region Windows Form Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> void InitializeComponent(void) { this->components = (gcnew System::ComponentModel::Container()); this->serialPort1 = (gcnew System::IO::Ports::SerialPort(this->components)); this->button1 = (gcnew System::Windows::Forms::Button()); this->SuspendLayout(); // // serialPort1 // this->serialPort1->PortName = L"COM2"; this->serialPort1->ReadTimeout = 3000; // // button1 // this->button1->Location = System::Drawing::Point(48, 168); this->button1->Name = L"button1"; this->button1->Size = System::Drawing::Size(112, 56); this->button1->TabIndex = 0; this->button1->Text = L"button1"; this->button1->UseVisualStyleBackColor = true; this->button1->Click += gcnew System::EventHandler(this, &Form1::button1_Click); // // Form1 // this->AutoScaleDimensions = System::Drawing::SizeF(6, 13); this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font; this->ClientSize = System::Drawing::Size(292, 266); this->Controls->Add(this->button1); this->Name = L"Form1"; this->Text = L"Form1"; this->ResumeLayout(false); } #pragma endregion private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { String^ s = "\001" + "S23170.0078" + "\027"; serialPort1->Write(s); s = serialPort1->ReadLine(); } }; }