SerialPort Event Handler
-
Hallo,
ich bin neu hier im Forum und auch neu in C++.
Als IDE benutzte ich Visual Studio 2005.Folgendes:
Ich habe an meinem SeriellenPort (usb2seriell) einen TTL Wandler welcher mit einem Atmel MikrKkontroller kommuniziert. Der Atmel sendet mir alle 500ms Debug-Informationen (an dieser Stelle sei angemerkt, ich habe das Programm für den Controller nicht geschrieben), is auch weiter nicht so wichtig. Fakt ist, ich weiss es kommen alle 500ms Daten an, aber der EventHandler (oder was auch immer) reagiert nich darauf. Häng etz ungefähr zwei Tage an dem Sch*** und das will einfach nich klappen. Ein Testweises "Bruteforcen" des Eingangspuffers mit nem Timer der den Befehl this->textBox1->AppendText(this->serialPort1->ReadExisting()); brachte nur einen Teilerfolg, es wurden zwar Daten ausgelesen, aber nicht komplett.Hier mal die komplette Form1.h
#pragma once namespace MK_ { using namespace System; using namespace System::IO::Ports; using namespace System::ComponentModel; using namespace System::Collections; using namespace System::Windows::Forms; using namespace System::Data; using namespace System::Drawing; using namespace System::Text; /// <summary> /// Zusammenfassung für Form1 /// /// Warnung: Wenn Sie den Namen dieser Klasse ändern, müssen Sie auch /// die Ressourcendateiname-Eigenschaft für das Tool zur Kompilierung verwalteter Ressourcen ändern, /// das allen RESX-Dateien zugewiesen ist, von denen diese Klasse abhängt. /// Anderenfalls können die Designer nicht korrekt mit den lokalisierten Ressourcen /// arbeiten, die diesem Formular zugewiesen sind. /// </summary> public ref class Form1 : public System::Windows::Forms::Form { public: Form1(void) { InitializeComponent(); // //TODO: Konstruktorcode hier hinzufügen. // } protected: /// <summary> /// Verwendete Ressourcen bereinigen. /// </summary> ~Form1() { if (components) { delete components; } } private: System::Windows::Forms::TextBox^ textBox1; private: System::IO::Ports::SerialPort^ serialPort1; private: System::Windows::Forms::Label^ label1; private: System::Windows::Forms::Button^ button1; private: System::Windows::Forms::CheckBox^ checkBox1; private: System::ComponentModel::IContainer^ components; protected: private: /// <summary> /// Erforderliche Designervariable. /// </summary> #pragma region Windows Form Designer generated code /// <summary> /// Erforderliche Methode für die Designerunterstützung. /// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden. /// </summary> void InitializeComponent(void) { this->components = (gcnew System::ComponentModel::Container()); this->textBox1 = (gcnew System::Windows::Forms::TextBox()); this->serialPort1 = (gcnew System::IO::Ports::SerialPort(this->components)); this->label1 = (gcnew System::Windows::Forms::Label()); this->button1 = (gcnew System::Windows::Forms::Button()); this->checkBox1 = (gcnew System::Windows::Forms::CheckBox()); this->SuspendLayout(); // // textBox1 // this->textBox1->Location = System::Drawing::Point(12, 12); this->textBox1->Multiline = true; this->textBox1->Name = L"textBox1"; this->textBox1->ReadOnly = true; this->textBox1->Size = System::Drawing::Size(548, 578); this->textBox1->TabIndex = 6; // // serialPort1 // this->serialPort1->BaudRate = 57600; this->serialPort1->PortName = L"COM8"; // // label1 // this->label1->BackColor = System::Drawing::SystemColors::ControlLight; this->label1->Location = System::Drawing::Point(192, 614); this->label1->Name = L"label1"; this->label1->Size = System::Drawing::Size(368, 18); this->label1->TabIndex = 7; // // button1 // this->button1->Location = System::Drawing::Point(714, 357); this->button1->Name = L"button1"; this->button1->Size = System::Drawing::Size(75, 23); this->button1->TabIndex = 8; this->button1->Text = L"button1"; this->button1->UseVisualStyleBackColor = true; this->button1->Click += gcnew System::EventHandler(this, &Form1::button1_Click); // // checkBox1 // this->checkBox1->AutoSize = true; this->checkBox1->Location = System::Drawing::Point(12, 611); this->checkBox1->Name = L"checkBox1"; this->checkBox1->Size = System::Drawing::Size(15, 14); this->checkBox1->TabIndex = 1; this->checkBox1->UseVisualStyleBackColor = true; this->checkBox1->CheckedChanged += gcnew System::EventHandler(this, &Form1::checkBox1_CheckedChanged); // // Form1 // this->AutoScaleDimensions = System::Drawing::SizeF(6, 13); this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font; this->ClientSize = System::Drawing::Size(893, 640); this->Controls->Add(this->checkBox1); this->Controls->Add(this->button1); this->Controls->Add(this->label1); this->Controls->Add(this->textBox1); this->Name = L"Form1"; this->Text = L"MK_Fernsteuerung"; this->Load += gcnew System::EventHandler(this, &Form1::Form1_Load); this->ResumeLayout(false); this->PerformLayout(); } #pragma endregion private: System::Void Form1_Load (System::Object^ sender, System::EventArgs^ e) { } private: void serialPort1_DataReceived(System::Object ^sender, SerialDataReceivedEventArgs ^e) { array<Object^> ^args = {this, e}; this->Invoke(gcnew EventHandler(this, &Form1::DoUpdate), args); } private: void DoUpdate(Object ^o, EventArgs ^e) { this->label1->Text = "Daten erhalten"; this->textBox1->AppendText(this->serialPort1->ReadExisting()); } private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { if (this->checkBox1->Checked == true) { this->DoUpdate(sender, e); } } private: System::Void checkBox1_CheckedChanged(System::Object^ sender, System::EventArgs^ e) { if (this->checkBox1->Checked==true) { try { this->serialPort1->Open(); //if (serialPort1->IsOpen) this->textBox1->AppendText("connected\n"); } catch (Exception^ e ) { //MessageBox::Show("Error: " + e->Message, "MK_", MessageBoxButtons::OK); this->textBox1->Text = e->Message; } } else if (this->checkBox1->Checked==false) { this->serialPort1->Close(); //if (!serialPort1->IsOpen) this->textBox1->AppendText(" \ndisconnected\n"); } } }; }
Der Button1 is auch so ein Provisorium das mir anzeigt, dass es im Prinzip funktioniert aber nur dieses Event nicht aufgerufen wird.
Ich hoffe jemand kann mir weiterhelfen
Thanks in Advance
-
Hallo,
Ich sehe nirgends, dass ein Event registriert und mit der Methode serialPort1_DataReceived verknüpft wird.
private: void serialPort1_DataReceived(System::Object ^sender, SerialDataReceivedEventArgs ^e) { array<Object^> ^args = {this, e}; this->Invoke(gcnew EventHandler(this, &Form1::DoUpdate), args); }
Ev. ist das in einem anderen File?
Wenns fehlt funktionierts nicht.Simon
-
hmm, wie wird denn das registriert?
bitte ausführlich beschreiben, bin noch nich so erfahren mit c++, als dass man erwarten könnte dass ich wüsste wie man ein event registriert oder was auch immeredit// wohoo, es gait ^^ habs geschafft, danke für den tipp
-
Wie hast du das gemacht? Ich muss nämlich genau das selbe machen
-
Ich hab seit par tagen das gleiche Problem, und würd mich über eine Lösung freuen
-
also bei mir funktioniert es jetzt, woran der Fehler lag kann ich allerdings nicht sagen, ich hab einfach ein neues Projekt erstellt und teile aus dem Code von clony rein kopiert
2 Probleme hab ich noch -> siehe Kommentare im Code
#pragma once namespace Terminal_C_3 { using namespace System; using namespace System::ComponentModel; using namespace System::Collections; using namespace System::Windows::Forms; using namespace System::Data; using namespace System::Drawing; using namespace System::IO::Ports; using namespace System::Text; public ref class Form1 : public System::Windows::Forms::Form { public: Form1(void) { InitializeComponent(); } protected: ~Form1() { if (components) { delete components;} } private: System::Windows::Forms::TextBox^ textBox1; protected: private: System::Windows::Forms::TextBox^ textBox2; private: System::Windows::Forms::Button^ button1; private: System::IO::Ports::SerialPort^ serialPort1; private: System::Windows::Forms::Button^ button2; private: System::Windows::Forms::Button^ button3; private: System::ComponentModel::IContainer^ components; private: #pragma region Windows Form Designer generated code void InitializeComponent(void) { this->components = (gcnew System::ComponentModel::Container()); System::ComponentModel::ComponentResourceManager^ resources = (gcnew System::ComponentModel::ComponentResourceManager(Form1::typeid)); this->textBox1 = (gcnew System::Windows::Forms::TextBox()); this->textBox2 = (gcnew System::Windows::Forms::TextBox()); this->button1 = (gcnew System::Windows::Forms::Button()); this->serialPort1 = (gcnew System::IO::Ports::SerialPort(this->components)); this->button2 = (gcnew System::Windows::Forms::Button()); this->button3 = (gcnew System::Windows::Forms::Button()); this->SuspendLayout(); // // textBox1 // this->textBox1->BackColor = System::Drawing::Color::White; this->textBox1->Location = System::Drawing::Point(12, 41); this->textBox1->Multiline = true; this->textBox1->Name = L"textBox1"; this->textBox1->ReadOnly = true; this->textBox1->ScrollBars = System::Windows::Forms::ScrollBars::Vertical; this->textBox1->Size = System::Drawing::Size(379, 128); this->textBox1->TabIndex = 0; // // textBox2 // this->textBox2->Location = System::Drawing::Point(12, 175); this->textBox2->Multiline = true; this->textBox2->Name = L"textBox2"; this->textBox2->Size = System::Drawing::Size(379, 51); this->textBox2->TabIndex = 1; this->textBox2->TextChanged += gcnew System::EventHandler(this, &Form1::textBox2_TextChanged); // // button1 // this->button1->Location = System::Drawing::Point(12, 12); this->button1->Name = L"button1"; this->button1->Size = System::Drawing::Size(75, 23); this->button1->TabIndex = 2; this->button1->Text = L"connect"; this->button1->UseVisualStyleBackColor = true; this->button1->Click += gcnew System::EventHandler(this, &Form1::button1_Click); // // serialPort1 // this->serialPort1->PortName = L"COM14"; this->serialPort1->DataReceived += gcnew System::IO::Ports::SerialDataReceivedEventHandler(this, &Form1::serialPort1_DataReceived); // // button2 // this->button2->Location = System::Drawing::Point(93, 12); this->button2->Name = L"button2"; this->button2->Size = System::Drawing::Size(75, 23); this->button2->TabIndex = 3; this->button2->Text = L"disconnect"; this->button2->UseVisualStyleBackColor = true; this->button2->Click += gcnew System::EventHandler(this, &Form1::button2_Click); // // button3 // this->button3->Location = System::Drawing::Point(12, 232); this->button3->Name = L"button3"; this->button3->Size = System::Drawing::Size(75, 23); this->button3->TabIndex = 4; this->button3->Text = L"send"; this->button3->UseVisualStyleBackColor = true; this->button3->Click += gcnew System::EventHandler(this, &Form1::button3_Click); // // Form1 // this->AutoScaleDimensions = System::Drawing::SizeF(6, 13); this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font; this->ClientSize = System::Drawing::Size(403, 262); this->Controls->Add(this->button3); this->Controls->Add(this->button2); this->Controls->Add(this->button1); this->Controls->Add(this->textBox2); this->Controls->Add(this->textBox1); this->Icon = (cli::safe_cast<System::Drawing::Icon^ >(resources->GetObject(L"$this.Icon"))); this->Name = L"Form1"; this->Text = L"Form1"; this->ResumeLayout(false); this->PerformLayout(); } #pragma endregion private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { try { this->serialPort1->Open(); } catch (Exception^ e ) { this->textBox2->Text = e->Message; } } private: System::Void serialPort1_DataReceived(System::Object^ sender, System::IO::Ports::SerialDataReceivedEventArgs^ e) { array<Object^> ^args = {this, e}; this->Invoke(gcnew EventHandler(this, &Form1::DoUpdate), args); } private: void DoUpdate(Object ^o, EventArgs ^e) { this->textBox1->AppendText(this->serialPort1->ReadExisting()); //soweit ich weiß macht die textBox bei '\n' ne neue Zeile //ich bekomm am serial port aber ein '\r' für ne neue Zeile // gibt es da ne Möglichkeit das umzustellen für die textBox // oder muss ich das dann immer mit ReadChar machen und auf '\r' //überprüfen? } private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) { this->serialPort1->Close(); } private: System::Void textBox2_TextChanged(System::Object^ sender, System::EventArgs^ e) { //Hier wollt ich die zeilen der textbox zählen (c# textBox1.Lines.Count) //und wenn größer 1 (also die Enter Taste gedrückt wurde den Text absenden // ich kann nur keine möglichkeit finden die Zeilen zu zählen //oder gibt es da noch eine bessere Variante ? } private: System::Void button3_Click(System::Object^ sender, System::EventArgs^ e) { serialPort1->Write(textBox2->Text); textBox2->Clear(); } }; }
-
nicht mehr Verzweifelter schrieb:
also bei mir funktioniert es jetzt, woran der Fehler lag kann ich allerdings nicht sagen, ich hab einfach ein neues Projekt erstellt und teile aus dem Code von clony rein kopiert
2 Probleme hab ich noch -> siehe Kommentare im Code
Also bei einem Problem kann ich dir helfen:
private: System::Void textBox2_TextChanged(System::Object^ sender, System::EventArgs^ e) { //Das geht mit GetLength() textBox1->Lines->GetLength(0); //Zählt die Zeilen der 1 Dimension }
-
Danke, den Rest schaffe ich sicherlich selber, ist ja nur suchen und ersetzen