using namespace System::IO::Ports;

To Discover Available Comm Ports On The PC


	 array<String^> ^AvailableSerialPorts;
	 array<unsigned char> ^aTemp;
	 String ^sTemp;

	 try
	 {
		AvailableSerialPorts = SerialPort::GetPortNames();

		cmbCommPort->Items->Add("None");
		for(int Count = 0; Count < AvailableSerialPorts->Length; Count++)
		{
			sTemp = AvailableSerialPorts[Count];

			//Remove any non numeric last letter which can be added by microsoft bluetooth drivers
			aTemp = System::Text::Encoding::UTF8->GetBytes(sTemp);
			while (
				(aTemp->Length > 1) && 
				((aTemp[(aTemp->Length - 1)] < '0') || (aTemp[(aTemp->Length - 1)] > '9'))
				)
			{
				Array::Resize(aTemp, (aTemp->Length - 1));
			}
			sTemp = System::Text::Encoding::UTF8->GetString(aTemp);

			cmbCommPort->Items->Add(sTemp);
		}
		cmbCommPort->SelectedIndex = 0;
	 }
	 catch(System::Exception^ e)
	 {
	 }

To use a simple form based SerialPort

(This is no use if you want to use in a seperate class!)
Place the serialport from the tool box onto the form (not the old Comm control that used to be used in VB).
You can set its properties by selecting it and using the properties box
To create a new event, such as datareceived press the lightning bolt 'events' icon in the properties box and double click the event you want to create.

To create a serial port in a class

In the class private declarations area

	System::IO::Ports::SerialPort ^serialPort1;
In the class constructor function

	serialPort1 = gcnew System::IO::Ports::SerialPort();
	serialPort1->BaudRate = 19200;
	serialPort1->DataBits = 8;
	serialPort1->Parity = Parity::None;
	serialPort1->StopBits = StopBits::One;
	serialPort1->Handshake = Handshake::None;

	serialPort1->DataReceived += gcnew System::IO::Ports::SerialDataReceivedEventHandler(this, &MyClass::serialPort1_DataReceived);
In a function that wants to set the port number and open it

	try
	{
		serialPort1->PortName = "COM" + CommPort;
		if (serialPort1->IsOpen)			//Port should not already be open
			return(0);
		serialPort1->Open();			//Try and open it
		return(1);					//Sucess
	}
	catch (Exception^ e)
	{
		return(0);
	}
In a function that wants to send data

	serialPort1->Write("SCIP2.0\n");
	//or
	String ^buffer;
	buffer = "BM\n";
	serialPort1->Write(buffer);
Function to receive

	void MyClass::serialPort1_DataReceived(System::Object^  sender, System::IO::Ports::SerialDataReceivedEventArgs^  e)
	{
		int RxBytes;
		int rxByte;

		RxBytes = serialPort1->BytesToRead;

		//----- GET WAITING BYTES -----
		while (RxBytes--)
		{
			rxByte = serialPort1->ReadByte();

		}

Threading On DataReceived

The DataReceived event will not necessarily occur on the same thread as your form UI so you need to use a thread safe call to a new function if you want to update form components in response to data being received.

Issue where the _DataReceived event might occasionally not get triggered

See http://www.codeproject.com/KB/dotnet/NET_20_SerialPort.aspx?msg=2729827#xx2729827xx

One fix is to add this into the waiting for response loop


	System::Windows::Forms::Application::DoEvents();
Feel free to comment if you can add help to this page or point out issues and solutions you have found. I do not provide support on this site, if you need help with a problem head over to stack overflow.

Comments

Your email address will not be published. Required fields are marked *