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();