locked
DataReceived - Read from serial port ??

    Question

  • hello..

     

    how to read data available from serial port automatically.. i try to use DataReceived function but got error. . below my source code and error.. i use visual C++ 2005 express edition with Windows Xp Pro OS ..

     

    #pragma once


    namespace Chatting {

     using namespace System;
     using namespace System::ComponentModel;
     using namespace System::Collections;
     using namespace System::Windows::Forms;
     using namespace System:Big Smileata;
     using namespace System:Big Smilerawing;
     using namespace System::IO;
     using namespace System::IO:Stick out tongueorts;
     

     /// <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
       //
      }

     
      
      /// <summary>
      /// Clean up any resources being used.
      /// </summary>
      ~Form1()
      {
       if (components)
       {
        delete components;
       }
      }
     private: System::Windows::Forms::TabControl^  tabControl1;
     private: System::Windows::Forms::TabPage^  tabPage1;
     private: System::Windows::Forms::TabPage^  tabPage2;
     private: System::Windows::Forms::TabPage^  tabPage3;
     private: System::Windows::Forms::Label^  label1;
     private: System::Windows::Forms::GroupBox^  groupBox1;
     private: System::Windows::Forms::Button^  button1;
     private: System::Windows::Forms::Button^  button3;
     private: System::Windows::Forms::Button^  button2;
     private: System::Windows::Forms::TextBox^  textBox3;
     private: System::Windows::Forms::TextBox^  textBox4;
     private: System::Windows::Forms:Big SmileateTimePicker^  dateTimePicker1;
     private: System::IO:Stick out tongueorts:Tongue TiederialPort^  serialport1;
     private: System::Windows::Forms::TextBox^  textBox2;
     private: System::Windows::Forms::TextBox^  textBox1;

     

     

     private: System::Windows::Forms:SurprisepenFileDialog^  openFileDialog1;
     public:  System::Void readfromfile(String^ filename) {
        StreamReader^ myStream = gcnew StreamReader(filename);}
     private: System::ComponentModel::IContainer^  components;

     


      /// <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->tabControl1 = (gcnew System::Windows::Forms::TabControl());
       this->tabPage1 = (gcnew System::Windows::Forms::TabPage());
       this->label1 = (gcnew System::Windows::Forms::Label());
       this->tabPage2 = (gcnew System::Windows::Forms::TabPage());
       this->groupBox1 = (gcnew System::Windows::Forms::GroupBox());
       this->textBox2 = (gcnew System::Windows::Forms::TextBox());
       this->textBox1 = (gcnew System::Windows::Forms::TextBox());
       this->button1 = (gcnew System::Windows::Forms::Button());
       this->tabPage3 = (gcnew System::Windows::Forms::TabPage());
       this->button3 = (gcnew System::Windows::Forms::Button());
       this->button2 = (gcnew System::Windows::Forms::Button());
       this->textBox3 = (gcnew System::Windows::Forms::TextBox());
       this->textBox4 = (gcnew System::Windows::Forms::TextBox());
       this->openFileDialog1 = (gcnew System::Windows::Forms:SurprisepenFileDialog());
       this->dateTimePicker1 = (gcnew System::Windows::Forms:Big SmileateTimePicker());
       this->serialport1 = (gcnew System::IO:Stick out tongueorts:Tongue TiederialPort(this->components));
       this->tabControl1->SuspendLayout();
       this->tabPage1->SuspendLayout();
       this->tabPage2->SuspendLayout();
       this->groupBox1->SuspendLayout();
       this->tabPage3->SuspendLayout();
       this->SuspendLayout();
       //
       // tabControl1
       //
       this->tabControl1->Controls->Add(this->tabPage1);
       this->tabControl1->Controls->Add(this->tabPage2);
       this->tabControl1->Controls->Add(this->tabPage3);
       this->tabControl1->Font = (gcnew System:Big Smilerawing::Font(L"Comic Sans MS", 9.75F, System:Big Smilerawing::FontStyle::Regular, System:Big Smilerawing::GraphicsUnit:Stick out tongueoint,
        static_cast<System::Byte>(0)));
       this->tabControl1->Location = System:Big Smilerawing:Stick out tongueoint(39, 37);
       this->tabControl1->Name = L"tabControl1";
       this->tabControl1->SelectedIndex = 0;
       this->tabControl1->Size = System:Big Smilerawing:Tongue Tiedize(592, 312);
       this->tabControl1->TabIndex = 0;
       //
       // tabPage1
       //
       this->tabPage1->BackColor = System:Big Smilerawing::Color:Tongue TiedeaShell;
       this->tabPage1->BackgroundImageLayout = System::Windows::Forms::ImageLayout::None;
       this->tabPage1->BorderStyle = System::Windows::Forms::BorderStyle::FixedSingle;
       this->tabPage1->Controls->Add(this->label1);
       this->tabPage1->Font = (gcnew System:Big Smilerawing::Font(L"Microsoft Sans Serif", 9.75F, System:Big Smilerawing::FontStyle::Bold, System:Big Smilerawing::GraphicsUnit:Stick out tongueoint,
        static_cast<System::Byte>(0)));
       this->tabPage1->Location = System:Big Smilerawing:Stick out tongueoint(4, 27);
       this->tabPage1->Name = L"tabPage1";
       this->tabPage1->Padding = System::Windows::Forms:Stick out tongueadding(3);
       this->tabPage1->Size = System:Big Smilerawing:Tongue Tiedize(584, 281);
       this->tabPage1->TabIndex = 0;
       this->tabPage1->Text = L"Welcome Screen";
       //
       // label1
       //
       this->label1->AutoSize = true;
       this->label1->Font = (gcnew System:Big Smilerawing::Font(L"Comic Sans MS", 18, System:Big Smilerawing::FontStyle::Bold, System:Big Smilerawing::GraphicsUnit:Stick out tongueoint,
        static_cast<System::Byte>(0)));
       this->label1->ForeColor = System:Big Smilerawing::Color::RoyalBlue;
       this->label1->Location = System:Big Smilerawing:Stick out tongueoint(176, 55);
       this->label1->Name = L"label1";
       this->label1->Size = System:Big Smilerawing:Tongue Tiedize(222, 35);
       this->label1->TabIndex = 0;
       this->label1->Text = L"PC to PC Chatting";
       this->label1->TextAlign = System:Big Smilerawing::ContentAlignment::MiddleCenter;
       //
       // tabPage2
       //
       this->tabPage2->BackColor = System:Big Smilerawing::Color:Tongue TiedeaShell;
       this->tabPage2->BorderStyle = System::Windows::Forms::BorderStyle::FixedSingle;
       this->tabPage2->Controls->Add(this->groupBox1);
       this->tabPage2->Location = System:Big Smilerawing:Stick out tongueoint(4, 27);
       this->tabPage2->Name = L"tabPage2";
       this->tabPage2->Padding = System::Windows::Forms:Stick out tongueadding(3);
       this->tabPage2->Size = System:Big Smilerawing:Tongue Tiedize(584, 281);
       this->tabPage2->TabIndex = 1;
       this->tabPage2->Text = L"Chat";
       //
       // groupBox1
       //
       this->groupBox1->Controls->Add(this->textBox2);
       this->groupBox1->Controls->Add(this->textBox1);
       this->groupBox1->Controls->Add(this->button1);
       this->groupBox1->Location = System:Big Smilerawing:Stick out tongueoint(24, 22);
       this->groupBox1->Name = L"groupBox1";
       this->groupBox1->Size = System:Big Smilerawing:Tongue Tiedize(535, 240);
       this->groupBox1->TabIndex = 0;
       this->groupBox1->TabStop = false;
       this->groupBox1->Text = L"Send/Rcv Msg";
       //
       // textBox2
       //
       this->textBox2->Location = System:Big Smilerawing:Stick out tongueoint(40, 200);
       this->textBox2->Name = L"textBox2";
       this->textBox2->Size = System:Big Smilerawing:Tongue Tiedize(368, 26);
       this->textBox2->TabIndex = 4;
       //
       // textBox1
       //
       this->textBox1->Location = System:Big Smilerawing:Stick out tongueoint(40, 21);
       this->textBox1->Multiline = true;
       this->textBox1->Name = L"textBox1";
       this->textBox1->ScrollBars = System::Windows::Forms:Tongue TiedcrollBars::Vertical;
       this->textBox1->Size = System:Big Smilerawing:Tongue Tiedize(460, 162);
       this->textBox1->TabIndex = 3;
       //
       // button1
       //
       this->button1->Location = System:Big Smilerawing:Stick out tongueoint(425, 199);
       this->button1->Name = L"button1";
       this->button1->Size = System:Big Smilerawing:Tongue Tiedize(75, 27);
       this->button1->TabIndex = 2;
       this->button1->Text = L"Send";
       this->button1->UseVisualStyleBackColor = true;
       this->button1->Click += gcnew System::EventHandler(this, &Form1::button1_Click);
       //
       // tabPage3
       //
       this->tabPage3->BackColor = System:Big Smilerawing::Color:Tongue TiedeaShell;
       this->tabPage3->BorderStyle = System::Windows::Forms::BorderStyle::FixedSingle;
       this->tabPage3->Controls->Add(this->button3);
       this->tabPage3->Controls->Add(this->button2);
       this->tabPage3->Controls->Add(this->textBox3);
       this->tabPage3->Controls->Add(this->textBox4);
       this->tabPage3->Location = System:Big Smilerawing:Stick out tongueoint(4, 27);
       this->tabPage3->Name = L"tabPage3";
       this->tabPage3->Padding = System::Windows::Forms:Stick out tongueadding(3);
       this->tabPage3->Size = System:Big Smilerawing:Tongue Tiedize(584, 281);
       this->tabPage3->TabIndex = 2;
       this->tabPage3->Text = L"File Transfer";
       //
       // button3
       //
       this->button3->Location = System:Big Smilerawing:Stick out tongueoint(34, 130);
       this->button3->Name = L"button3";
       this->button3->Size = System:Big Smilerawing:Tongue Tiedize(75, 27);
       this->button3->TabIndex = 3;
       this->button3->Text = L"Upload";
       this->button3->UseVisualStyleBackColor = true;
       this->button3->Click += gcnew System::EventHandler(this, &Form1::button3_Click);
       //
       // button2
       //
       this->button2->Location = System:Big Smilerawing:Stick out tongueoint(34, 79);
       this->button2->Name = L"button2";
       this->button2->Size = System:Big Smilerawing:Tongue Tiedize(75, 26);
       this->button2->TabIndex = 2;
       this->button2->Text = L"Browse";
       this->button2->UseVisualStyleBackColor = true;
       this->button2->Click += gcnew System::EventHandler(this, &Form1::button2_Click);
       //
       // textBox3
       //
       this->textBox3->Location = System:Big Smilerawing:Stick out tongueoint(137, 79);
       this->textBox3->Name = L"textBox3";
       this->textBox3->Size = System:Big Smilerawing:Tongue Tiedize(382, 26);
       this->textBox3->TabIndex = 1;
       this->textBox3->TextChanged += gcnew System::EventHandler(this, &Form1::textBox3_TextChanged);
       //
       // textBox4
       //
       this->textBox4->Location = System:Big Smilerawing:Stick out tongueoint(137, 130);
       this->textBox4->Multiline = true;
       this->textBox4->Name = L"textBox4";
       this->textBox4->Size = System:Big Smilerawing:Tongue Tiedize(382, 48);
       this->textBox4->TabIndex = 0;
       //
       // openFileDialog1
       //
       this->openFileDialog1->DereferenceLinks = false;
       this->openFileDialog1->FileName = L"openFileDialog1";
       this->openFileDialog1->Multiselect = true;
       this->openFileDialog1->FileOk += gcnew System::ComponentModel::CancelEventHandler(this, &Form1:SurprisepenFileDialog1_FileOk);
       //
       // dateTimePicker1
       //
       this->dateTimePicker1->Font = (gcnew System:Big Smilerawing::Font(L"Comic Sans MS", 8.25F, System:Big Smilerawing::FontStyle::Regular, System:Big Smilerawing::GraphicsUnit:Stick out tongueoint,
        static_cast<System::Byte>(0)));
       this->dateTimePicker1->Location = System:Big Smilerawing:Stick out tongueoint(436, 22);
       this->dateTimePicker1->Name = L"dateTimePicker1";
       this->dateTimePicker1->RightToLeft = System::Windows::Forms::RightToLeft::No;
       this->dateTimePicker1->Size = System:Big Smilerawing:Tongue Tiedize(195, 23);
       this->dateTimePicker1->TabIndex = 2;
       //
       // serialport1
       //
       this->serialport1->PortName = L"COM1";
       this->serialport1->DataReceived += gcnew System::IO:Stick out tongueorts:Tongue TiederialDataReceivedEventHandler(this, &Form1:Tongue TiederialPort1_DataReceived);
       //
       // Form1
       //
       this->AutoScaleDimensions = System:Big Smilerawing:Tongue TiedizeF(6, 13);
       this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
       this->AutoScroll = true;
       this->AutoSize = true;
       this->BackColor = System:Big Smilerawing:Tongue TiedystemColors::Info;
       this->ClientSize = System:Big Smilerawing:Tongue Tiedize(662, 396);
       this->Controls->Add(this->dateTimePicker1);
       this->Controls->Add(this->tabControl1);
       this->FormBorderStyle = System::Windows::Forms::FormBorderStyle::Fixed3D;
       this->Name = L"Form1";
       this->Text = L"Pc2Pc Chatting";
       this->FormClosed += gcnew System::Windows::Forms::FormClosedEventHandler(this, &Form1::Form1_FormClosed);
       this->Load += gcnew System::EventHandler(this, &Form1::Form1_Load);
       this->tabControl1->ResumeLayout(false);
       this->tabPage1->ResumeLayout(false);
       this->tabPage1->PerformLayout();
       this->tabPage2->ResumeLayout(false);
       this->groupBox1->ResumeLayout(false);
       this->groupBox1->PerformLayout();
       this->tabPage3->ResumeLayout(false);
       this->tabPage3->PerformLayout();
       this->ResumeLayout(false);

      }
    #pragma endregion
     
    private: System::Void button1_Click(System:Surprisebject^  sender, System::EventArgs^  e) {
       
        String^ msg;
       
        msg = textBox2->Text;
        textBox1->Text = textBox1->Text + "PC 1 : " + msg + Char(13) + Char(10) ;
       
        //Write to serial port
        serialport1->Write( "MPIZ" + msg + Char(13) + Char(10) );
        textBox2->Text = "";   
     
       }
    //Check the availability of COM1, if it is not available, all the tabpages will be disable
    //Open the serial port
    private: System::Void Form1_Load(System:Surprisebject^  sender, System::EventArgs^  e) {
       

       tabControl1->Enabled = false;
       array <String^>^ gp = gcnew array <String^> (10);
       
       gp = SerialPort::GetPortNames();

       if (gp->Length > 0) {
            

         for (int i = 0; i < gp->Length; i++) {
         if (gpIdea == "COM1") {

       serialport1->Open();
       
       tabControl1->Enabled = true;

       break;
        
        
        
         }}}

      }
    //Close the serial port
    private: System::Void Form1_FormClosed(System:Surprisebject^  sender, System::Windows::Forms::FormClosedEventArgs^  e) {
        serialport1->Close();

       
       }

    private: System::Void button2_Click(System:Surprisebject^  sender, System::EventArgs^  e) {
       
        OpenFileDialog^ opd = gcnew OpenFileDialog();

        opd->InitialDirectory = "C:\temp";
        opd->Filter = "Zip files (*.zip)|*.zip|All files (*.*)|*.*";
        opd->FilterIndex = 1;
        opd->RestoreDirectory = true; // to restore the last opened directory

        if (opd->ShowDialog() == System::Windows::Forms:Big SmileialogResult:SurpriseK) {
         readfromfile(opd->FileName);
        }

        textBox3->Text = opd->FileName->ToString();
        textBox4->Clear();
      
       }

    private: System::Void button3_Click(System:Surprisebject^  sender, System::EventArgs^  e) {
                textBox3->Clear();
       textBox4->Text = "Done";
       }

    private: System::Void openFileDialog1_FileOk(System:Surprisebject^  sender, System::ComponentModel::CancelEventArgs^  e) {
       }
    private: System::Void textBox3_TextChanged(System:Surprisebject^  sender, System::EventArgs^  e) {
       
       }
    private: System::Void serialPort1_DataReceived(System:Surprisebject^  sender, System::IO:Stick out tongueorts:Tongue TiederialDataReceivedEventArgs^  e) {
        
        //Read from serial port
           int reg;
        String^ reg1;

       
      
        
        do {
           reg = serialport1->ReadChar();
         } while (reg != 80); // 80 = P

        

        do {
           reg = serialport1->ReadChar();
         } while (reg != 73); // 73 = I


        do {
           reg = serialport1->ReadChar();
         } while (reg != 90); // 90 = Z

        do {
        
           reg = serialport1->ReadChar();
           reg1 = reg1 + Char(reg);
            } while (reg != 13); // 13 = carriage return
        


          textBox1->Text = textBox1->Text + "PC 2 : " + reg1 + Char(13) + Char(10);
      
      
      
       }


    };
    }

     

     

     

    and the error,

     

    An unhandled exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll

    Additional information: Cross-thread operation not valid: Control 'textBox1' accessed from a thread other than the thread it was created on.

     

    Wednesday, April 25, 2007 5:07 AM

Answers

  • The DataReceived event is fired on another thread.  You can't access controls on your form directly from that thread, you'll have to use the Control.Invoke() method.  Check the MSDN library documentation for an example.
    Wednesday, April 25, 2007 5:11 PM
    Moderator

All replies

  • The DataReceived event is fired on another thread.  You can't access controls on your form directly from that thread, you'll have to use the Control.Invoke() method.  Check the MSDN library documentation for an example.
    Wednesday, April 25, 2007 5:11 PM
    Moderator
  • How do I find out what thread the DataReceived event is using?

     

    Here is my problem:

     

    I am using a SerialPort DataReceived Event to Invoke a Delegate that updates some Textboxes with GPS info.  Data is always coming in and the App works great. But, when I go to close the form, it intermittently hangs or throws an Exception.

     

    I'm thinking the problem is the DataReceived thread is still busy when I start closing the form and that I need to do a "Thread->Join" before closing the form.

     

    But how do I find out the name of the thread I need to Join?

     

    ...Or, am I on the wrong path?

     

    TIA

    Monday, May 07, 2007 5:10 PM
  • You can't find out what thread is being used.  DataReceived is running on threads from the thread pool and you might get different threads for different invocations.  You can't do Thread.Join().  Knowing what exception you get would be *really* helpful, especially with a stack trace. 

    One thing to try: remove the event handler and sleep for 250 msec or so to wait for pending DataReceived calls to execute.  Then close the port.
    Monday, May 07, 2007 7:40 PM
    Moderator
  • 9 out of 10 times it will just hang while closing the app but that 1 out of 10 times I get an exception, it is:

     

    "The I/O operation has been aborted because of either a thread exit or an application request."

     

    How do I remove an Event Handler anyway?

     

    Thanks for your help.

    Monday, May 07, 2007 8:51 PM
  • SerialPort.Close() hanging is a known problem.  You remove an event handler with code like this:

      serialPort1.DataReceived -= serialPort1_DataReceived;

    Substitute the name you used for your serialport object instance.
    Monday, May 07, 2007 9:18 PM
    Moderator
  • I assume you mean:

     

    serialPort1->DataReceived -= serialPort1_DataReceived;

     

    as I am working with VC++. My SerialPort instance is named serialPort1 just like your example. However, I get the following error when I try to compile it:

     

    Error 1 error C3867: 'GPSReaderinC::Form1:Tongue TiederialPort1_DataReceived': function call missing argument list; use '&GPSReaderinC::Form1:Tongue TiederialPort1_DataReceived' to create a pointer to member c:\source files\c++ application\gps reader in c\gps reader in c\gps reader in c\Form1.h 477 

    I guess it doesn't matter since It looks like I need to open a new thread to close the serialport for the Known Problem you provided a link too.

     

    But what's interesting, if I open and close the SerialPort with a button, I will get the intermittent hang or exception as decribed. But if I close the form without even closing the serial port first, it will still hang or throw exception 90% of the time.

     

    Is that consistent with the Known Bug?

     

    I just want a way to close the app without hanging.

     

    Anyway, thanks for your help.


    Monday, May 07, 2007 11:57 PM