1 Replies - 10256 Views - Last Post: 14 February 2013 - 05:11 AM

#1 ricklei  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 07-February 13

Simple Serial Receive Parser with C++

Posted 07 February 2013 - 03:12 PM

I'm new to C++ and .NET. I am using Visual Studio 2008 and have created a Visual C++ CLR Windows Forms Application.

I placed a textbox and a serialport from the toolbox on the form. After much web searching I was able to add the appropriate code to create a receive event handler and am successfully receiving characters from the COM port.

The problem I am having is placing the parsed text I received into the form's textbox. From my research, the problem is one of multiple threads. I've looked at examples using Delegates and Invokes, etc, but haven't been able to get it to work yet.

Following is the code from the Form class where I added all my code. My code is in red if I worked this interface correctly. The two lines of code that are not working are in green within the SetText function. I found this code for delegates and invoke and had to massage it a bit to get it to complile to this point.

Any help would be appreiciated.

#pragma once


namespace Lumanet {

	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;

[color="#FF0000"]	// declare a delegate
	public delegate void AddCommandToTextBox(String ^commandStr);[/color]
	/// <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
			//
[color="#FF0000"]                        serialPort1->DataReceived += gcnew SerialDataReceivedEventHandler(DataReceivedHandler);
			serialPort1->Open();[/color]		}

	protected:
		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		~Form1()
		{
			if (components)
			{
				delete components;
			}
[color="#FF0000"]			serialPort1->Close();[/color]		}
	private: System::IO::Ports::SerialPort^  serialPort1;
	private: System::Windows::Forms::TextBox^  textBox1;
	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->textBox1 = (gcnew System::Windows::Forms::TextBox());
			this->SuspendLayout();
			// 
			// serialPort1
			// 
			this->serialPort1->BaudRate = 38400;
			this->serialPort1->PortName = L"COM9";
			// 
			// textBox1
			// 
			this->textBox1->Location = System::Drawing::Point(222, 280);
			this->textBox1->Name = L"textBox1";
			this->textBox1->Size = System::Drawing::Size(228, 20);
			this->textBox1->TabIndex = 0;
			this->textBox1->TextChanged += gcnew System::EventHandler(this, &Form1::textBox1_TextChanged);
			// 
			// Form1
			// 
			this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
			this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
			this->ClientSize = System::Drawing::Size(530, 626);
			this->Controls->Add(this->textBox1);
			this->Name = L"Form1";
			this->Text = L"Form1";
			this->ResumeLayout(false);
			this->PerformLayout();

		}
#pragma endregion

[color="#FF0000"]		static unsigned char verifyCommand( unsigned char command, unsigned char compliment )
		{
			if( (compliment ^ command) == 0xFF )
				return( 1 );
			else
				return( 0 );
		}[/color]

[color="#FF0000"]	private: void SetText(String ^text)
		{
			// InvokeRequired required compares the thread ID of the
			// calling thread to the thread ID of the creating thread.
			// If these threads are different, it returns true.
			if (this->InvokeRequired)[/color]
			{
[color="#006400"]				AddCommandToTextBox ^d += gcnew AddCommandToTextBox(text);
				this->Invoke(d, gcnew object[] { text });[/color]			}
[color="#FF0000"]			else
			{
				this->textBox1->Text = this->textBox1->Text + text;
			}
		}[/color]
	private: System::Void textBox1_TextChanged(System::Object^  sender, System::EventArgs^  e) 
	{
	}

[color="#FF0000"]     private: static void DataReceivedHandler( Object^ sender, SerialDataReceivedEventArgs^ e)
    {
		static enum lState {IDLE, TOKEN_COMPLIMENT, TOKEN_ID, 
			                      PANEL_REQUEST_COMPLIMENT, PANEL_REQUEST_ID};

		int b;
		static unsigned char command, lMode = IDLE;
		String^ text;

        SerialPort^ sp = (SerialPort^)sender;
		while( (b = sp->ReadByte()) != -1 )
		{
			switch( lMode )
			{
				case IDLE:
					if( b > 127 )
					{
						command = b;
						switch( b )
						{
							case 0xE0:
								lMode = TOKEN_COMPLIMENT;
								break;

							case 0xF1:
								lMode = PANEL_REQUEST_COMPLIMENT;
								break;
						}
					}
					break;

				case TOKEN_COMPLIMENT:
					if( verifyCommand( command, b ) )
					{
						lMode = TOKEN_ID;
					}
					else
					{
						lMode = IDLE;
					}
					break;

				case TOKEN_ID:
					text = (B)/>/>.ToString();
					// Figure out how to get text to textBox1
					lMode = IDLE;
					break;

				case PANEL_REQUEST_COMPLIMENT:
					lMode = PANEL_REQUEST_ID;
					break;

				default:
					break;
			}
		}
    }[/color]	};
}





Is This A Good Question/Topic? 0
  • +

Replies To: Simple Serial Receive Parser with C++

#2 miltonneal  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 7
  • Joined: 09-November 12

Re: Simple Serial Receive Parser with C++

Posted 14 February 2013 - 05:11 AM

Hi
You code is a bit difficult to read through with all the color tags that don't work :)
But anyway in the TOKEN_ID case use:
Textbox1->Text += b.ToString();



You Delegate should not be necessary for this to work.
Milton
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1