how to use this code for receiving data from serial port????
it works fine for transmission...but how to receive????
Serial Port Communication in C#
#48 Guest_Michael*
Posted 09 June 2010 - 08:40 AM
Hi, thanks for the tutorial, I downloaded Visual C# 2008 Express, opened and converted the project and mostly it has been fine. I am working with an FTDI USB Com port device that maps to COM3.
Just to re-iterate what has been said in earlier posts, the program has a "bug" and only opens COM1, even if you have selected COM3 in the combo box. To fix this bug, add "comm.PortName = cboPort.Text;" to the cmdOpen_Click method (shown below).
Once this was done, everything worked fine. Other earlier suggestions such as adding code to the Close Port button are also valid.
Thanks,
Michael
private void cmdOpen_Click(object sender, EventArgs e)
{
comm.Parity = cboParity.Text;
comm.StopBits = cboStop.Text;
comm.DataBits = cboData.Text;
comm.BaudRate = cboBaud.Text;
comm.DisplayWindow = rtbDisplay;
comm.PortName = cboPort.Text; // add this line here
comm.OpenPort();
cmdOpen.Enabled = false;
cmdClose.Enabled = true;
cmdSend.Enabled = true;
}
Just to re-iterate what has been said in earlier posts, the program has a "bug" and only opens COM1, even if you have selected COM3 in the combo box. To fix this bug, add "comm.PortName = cboPort.Text;" to the cmdOpen_Click method (shown below).
Once this was done, everything worked fine. Other earlier suggestions such as adding code to the Close Port button are also valid.
Thanks,
Michael
private void cmdOpen_Click(object sender, EventArgs e)
{
comm.Parity = cboParity.Text;
comm.StopBits = cboStop.Text;
comm.DataBits = cboData.Text;
comm.BaudRate = cboBaud.Text;
comm.DisplayWindow = rtbDisplay;
comm.PortName = cboPort.Text; // add this line here
comm.OpenPort();
cmdOpen.Enabled = false;
cmdClose.Enabled = true;
cmdSend.Enabled = true;
}
#49 Guest_fenterbug*
Posted 28 June 2010 - 01:11 PM
I'm having issues receiving data that don't seem to be discussed yet here. I've fixed the open and close buttons. I can run the app. However, sometimes a read doesn't read all of the data available. I scan a barcode with a value of "48057276448". Sometimes, I get all of that data on a single line. Most of the time, I get "4805727" on one line followed by "6448" on the next line. I realize that this is likely a buffering issue in the scanner's wireless hardware. What I need to know, however, is how to work around that. If anyone has any suggestions, please respond here as well as email me at fenterbug_AT_gmail_DOT_com. Thanks!
#50 Guest_fenterbug*
Posted 28 June 2010 - 01:27 PM
fenterbug, on 28 June 2010 - 12:11 PM, said:
I'm having issues receiving data that don't seem to be discussed yet here. I've fixed the open and close buttons. I can run the app. However, sometimes a read doesn't read all of the data available. I scan a barcode with a value of "48057276448". Sometimes, I get all of that data on a single line. Most of the time, I get "4805727" on one line followed by "6448" on the next line. I realize that this is likely a buffering issue in the scanner's wireless hardware. What I need to know, however, is how to work around that. If anyone has any suggestions, please respond here as well as email me at fenterbug_AT_gmail_DOT_com. Thanks!
I figured out a work-around. Just before the ReadExisting() call, I call "System.Threading.Thread.Sleep(333);". That gives the wireless / transmission buffer plenty of time to move all of the data. WOOT!
#51 Guest_naveen*
Posted 29 June 2010 - 12:27 AM
Hi,
I am new to C# i have been assigned the task of changing the existing code All the software has been written including the driver the issue is the device reads the constant value of data and it has to be changed to i.e send the address 5A 04 02 if this is sent my device replies with 0B 80 this value has to be displayed on the screen I need the code for sending the same and receiving it.
Regards
Naveen
I am new to C# i have been assigned the task of changing the existing code All the software has been written including the driver the issue is the device reads the constant value of data and it has to be changed to i.e send the address 5A 04 02 if this is sent my device replies with 0B 80 this value has to be displayed on the screen I need the code for sending the same and receiving it.
Regards
Naveen
#52 Guest_Francesco Giossi*
Posted 29 June 2010 - 03:03 AM
umer, on 16 May 2010 - 11:01 PM, said:
how to use this code for receiving data from serial port????
it works fine for transmission...but how to receive????
it works fine for transmission...but how to receive????
hi,
I had the same problem and drove me a bit crazy.
I found the solution
In the OpenPort method of the class ComponentManager, just set RtsEnable to true, like this
//now open the port
comPort.RtsEnable = true;
comPort.Open();
//display message
and the delegate will work pretty well
Hope this helps
#53
Posted 30 June 2010 - 02:04 PM
Hi.
I get timeout trying to read from the port.
What am I doing wrong?
Thanks.
I get timeout trying to read from the port.
What am I doing wrong?
Thanks.
#54 Guest_john aitken*
Posted 01 July 2010 - 04:16 AM
PsychoCoder, on 20 October 2007 - 07:09 PM, said:
Welcome to my tutorial on Serial Port Communication in C#. Lately Ive seen a lot of questions on how to send and receive data through a serial port, so I thought it was time to write on the topic. Back in the days of Visual Basic 6.0, you had to use the MSComm Control that was shipped with VB6, the only problem with this method was you needed to make sure you included that control in your installation package, not really that big of a deal. The control did exactly what was needed for the task.
Then along comes .Net 2.0, and this time Microsoft added the System.IO.Ports Namespace, and within that was the SerialPort Class. DotNet developers finally had an intrinsic way of serial port communication, without having to deal with the complexities of interoping with an old legacy ActiveX OCX control. One of the most useful methods in the SerialPort class is the GetPortNames Method. This allows you to retrieve a list of available ports (COM1,COM2,etc.) available for the computer the application is running on.
Now that we have that out of the way, lets move on to programming our application. As with all application I create, I keep functionality separated from presentation, I do this by creating Manager classes that manage the functionality for a given process. What we will be looking at is the code in my CommunicationManager class. As with anything you write in .Net you need to add the references to the Namespace's you'll be using:
In this application I wanted to give the user the option of what format they wanted to send the message in, either string or binary, so we have an enumeration for that, and an enumerations for the type of message i.e; Incoming, Outgoing, Error, etc. The main purpose of this enumeration is for changing the color of the text displayed to the user according to message type. Here are the enumerations:
Next we have our variable list, 6 of them are for populating our class Properties, the other 2 are access throughout the class so they needed to be made global:
NOTE:I always separate my code into sections using the #region ... #endregion to make it easier when scanning my code. It is a design choice so it's not necessary if you don't want to do it.
Now we need to create our class properties. All the properties in this class are public read/write properties. We have properties for the following items of the Serial Port:
To be able to instantiate any class object we create we need Constructors. Constructors are the entry point to your class, and is the first code executed when instantiating a class object. We have 2 constructors for our manager class, one that sets our properties to a specified value, and one that sets our properties to an empty value, thus initializing the variables preventing a NullReferenceException from occurring. We also add an EventHandler in the constructor, the event will be executed whenever there's data waiting in the buffer:
The first think you need to know about serial port communication is writing data to the port. The first thing we do in our WriteData method is to check what transmission mode the user has selected, since binary data needs to be converted into binary, then back to string for displaying to the user. Next we need to make sure the port is open, for this we use the IsOpen Property of the SerialPort Class. If the port isn't open we open it by calling the Open Method of the SerialPort Class. For writing to the port we use the Write Method:
You will notice in this method we call three methods:
Here we convert the provided string to a byte array, then the WriteData method sends it out the port. For displaying we need to convert it back into string format, so we use the ByteToHex method we created:
The last method that WriteData depends on is the DisplayData method. Here we use the Invoke Method of our RichTextBox, the control used to display the data, to create a new EventHandler which creates a new Delegate for setting the properties we wish for our message, then appending it to the value already displayed:
NOTE: You will notice that we hyave added the STAThread Attribute to our method. This is used when a single thread apartment is required by a control, like the RichTextBox.
The next method we will look at it used when we need to open the port initially. Here we set the BaudRate, Parity, StopBits, DataBits and PortName Properties of the SerialPort Class:
Next lets take a look at our event handler. This event will be executed whenever there's data waiting in the buffer. This method looks identical to our WriteData method, because it has to do the same exact work:
We have 3 small methods left, and these are actually optional, for the lack of a better word. These methods are used to populate my ComboBox's on my UI with the port names available on the computer, Parity values and Stop Bit values. The Parity and Stop Bits are available in enumerations included with the .Net Framework 2.0:
That is how you do Serial Port Communication in C#. Microsoft finally gave us intrinsic tools to perform this task, no more relying on legacy objects. I am providing this class and a sample application to show how to implement what we just learned. What I am providing is under the GNU General Public License meaning you can modify and distribute how you see fit, but the license header must stay in tact. I hope you found this tutorial useful and informative, thank you for reading.
Happy Coding
attachment
Then along comes .Net 2.0, and this time Microsoft added the System.IO.Ports Namespace, and within that was the SerialPort Class. DotNet developers finally had an intrinsic way of serial port communication, without having to deal with the complexities of interoping with an old legacy ActiveX OCX control. One of the most useful methods in the SerialPort class is the GetPortNames Method. This allows you to retrieve a list of available ports (COM1,COM2,etc.) available for the computer the application is running on.
Now that we have that out of the way, lets move on to programming our application. As with all application I create, I keep functionality separated from presentation, I do this by creating Manager classes that manage the functionality for a given process. What we will be looking at is the code in my CommunicationManager class. As with anything you write in .Net you need to add the references to the Namespace's you'll be using:
using System; using System.Text; using System.Drawing; using System.IO.Ports;
In this application I wanted to give the user the option of what format they wanted to send the message in, either string or binary, so we have an enumeration for that, and an enumerations for the type of message i.e; Incoming, Outgoing, Error, etc. The main purpose of this enumeration is for changing the color of the text displayed to the user according to message type. Here are the enumerations:
#region Manager Enums
/// <summary>
/// enumeration to hold our transmission types
/// </summary>
public enum TransmissionType { Text, Hex }
/// <summary>
/// enumeration to hold our message types
/// </summary>
public enum MessageType { Incoming, Outgoing, Normal, Warning, Error };
#endregion
Next we have our variable list, 6 of them are for populating our class Properties, the other 2 are access throughout the class so they needed to be made global:
#region Manager Variables
//property variables
private string _baudRate = string.Empty;
private string _parity = string.Empty;
private string _stopBits = string.Empty;
private string _dataBits = string.Empty;
private string _portName = string.Empty;
private TransmissionType _transType;
private RichTextBox _displayWindow;
//global manager variables
private Color[] MessageColor = { Color.Blue, Color.Green, Color.Black, Color.Orange, Color.Red };
private SerialPort comPort = new SerialPort();
#endregion
NOTE:I always separate my code into sections using the #region ... #endregion to make it easier when scanning my code. It is a design choice so it's not necessary if you don't want to do it.
Now we need to create our class properties. All the properties in this class are public read/write properties. We have properties for the following items of the Serial Port:
- Baud Rate: A measure of the speed of serial communication, roughly equivalent to bits per second.
- Parity: The even or odd quality of the number of 1's or 0's in a binary code, often used to determine the integrity of data especially after transmission.
- Stop Bits: A bit that signals the end of a transmission unit
- Data Bits: The number of bits used to represent one character of data.
- Port Name: The port with which we're communicating through, i.e; COM1, COM2, etc.
#region Manager Properties
/// <summary>
/// Property to hold the BaudRate
/// of our manager class
/// </summary>
public string BaudRate
{
get { return _baudRate; }
set { _baudRate = value; }
}
/// <summary>
/// property to hold the Parity
/// of our manager class
/// </summary>
public string Parity
{
get { return _parity; }
set { _parity = value; }
}
/// <summary>
/// property to hold the StopBits
/// of our manager class
/// </summary>
public string StopBits
{
get { return _stopBits; }
set { _stopBits = value; }
}
/// <summary>
/// property to hold the DataBits
/// of our manager class
/// </summary>
public string DataBits
{
get { return _dataBits; }
set { _dataBits = value; }
}
/// <summary>
/// property to hold the PortName
/// of our manager class
/// </summary>
public string PortName
{
get { return _portName; }
set { _portName = value; }
}
/// <summary>
/// property to hold our TransmissionType
/// of our manager class
/// </summary>
public TransmissionType CurrentTransmissionType
{
get{ return _transType;}
set{ _transType = value;}
}
/// <summary>
/// property to hold our display window
/// value
/// </summary>
public RichTextBox DisplayWindow
{
get { return _displayWindow; }
set { _displayWindow = value; }
}
#endregion
To be able to instantiate any class object we create we need Constructors. Constructors are the entry point to your class, and is the first code executed when instantiating a class object. We have 2 constructors for our manager class, one that sets our properties to a specified value, and one that sets our properties to an empty value, thus initializing the variables preventing a NullReferenceException from occurring. We also add an EventHandler in the constructor, the event will be executed whenever there's data waiting in the buffer:
#region Manager Constructors
/// <summary>
/// Constructor to set the properties of our Manager Class
/// </summary>
/// <param name="baud">Desired BaudRate</param>
/// <param name="par">Desired Parity</param>
/// <param name="sBits">Desired StopBits</param>
/// <param name="dBits">Desired DataBits</param>
/// <param name="name">Desired PortName</param>
public CommunicationManager(string baud, string par, string sBits, string dBits, string name, RichTextBox rtb)
{
_baudRate = baud;
_parity = par;
_stopBits = sBits;
_dataBits = dBits;
_portName = name;
_displayWindow = rtb;
//now add an event handler
comPort.DataReceived += new SerialDataReceivedEventHandler(comPort_DataReceived);
}
/// <summary>
/// Comstructor to set the properties of our
/// serial port communicator to nothing
/// </summary>
public CommunicationManager()
{
_baudRate = string.Empty;
_parity = string.Empty;
_stopBits = string.Empty;
_dataBits = string.Empty;
_portName = "COM1";
_displayWindow = null;
//add event handler
comPort.DataReceived+=new SerialDataReceivedEventHandler(comPort_DataReceived);
}
#endregion
The first think you need to know about serial port communication is writing data to the port. The first thing we do in our WriteData method is to check what transmission mode the user has selected, since binary data needs to be converted into binary, then back to string for displaying to the user. Next we need to make sure the port is open, for this we use the IsOpen Property of the SerialPort Class. If the port isn't open we open it by calling the Open Method of the SerialPort Class. For writing to the port we use the Write Method:
#region WriteData
public void WriteData(string msg)
{
switch (CurrentTransmissionType)
{
case TransmissionType.Text:
//first make sure the port is open
//if its not open then open it
if (!(comPort.IsOpen == true)) comPort.Open();
//send the message to the port
comPort.Write(msg);
//display the message
DisplayData(MessageType.Outgoing, msg + "\n");
break;
case TransmissionType.Hex:
try
{
//convert the message to byte array
byte[] newMsg = HexToByte(msg);
//send the message to the port
comPort.Write(newMsg,0,newMsg.Length);
//convert back to hex and display
DisplayData(MessageType.Outgoing, ByteToHex(newMsg) + "\n");
}
catch (FormatException ex)
{
//display error message
DisplayData(MessageType.Error, ex.Message);
}
finally
{
_displaywindow.SelectAll();
}
break;
default:
//first make sure the port is open
//if its not open then open it
if (!(comPort.IsOpen == true)) comPort.Open();
//send the message to the port
comPort.Write(msg);
//display the message
DisplayData(MessageType.Outgoing, msg + "\n");
break;
break;
}
}
#endregion
You will notice in this method we call three methods:
- HexToByte
- ByteToHex
- DisplayData
#region HexToByte
/// <summary>
/// method to convert hex string into a byte array
/// </summary>
/// <param name="msg">string to convert</param>
/// <returns>a byte array</returns>
private byte[] HexToByte(string msg)
{
//remove any spaces from the string
msg = msg.Replace(" ", "");
//create a byte array the length of the
//string divided by 2
byte[] comBuffer = new byte[msg.Length / 2];
//loop through the length of the provided string
for (int i = 0; i < msg.Length; i += 2)
//convert each set of 2 characters to a byte
//and add to the array
comBuffer[i / 2] = (byte)Convert.ToByte(msg.Substring(i, 2), 16);
//return the array
return comBuffer;
}
#endregion
Here we convert the provided string to a byte array, then the WriteData method sends it out the port. For displaying we need to convert it back into string format, so we use the ByteToHex method we created:
#region ByteToHex
/// <summary>
/// method to convert a byte array into a hex string
/// </summary>
/// <param name="comByte">byte array to convert</param>
/// <returns>a hex string</returns>
private string ByteToHex(byte[] comByte)
{
//create a new StringBuilder object
StringBuilder builder = new StringBuilder(comByte.Length * 3);
//loop through each byte in the array
foreach (byte data in comByte)
//convert the byte to a string and add to the stringbuilder
builder.Append(Convert.ToString(data, 16).PadLeft(2, '0').PadRight(3, ' '));
//return the converted value
return builder.ToString().ToUpper();
}
#endregion
The last method that WriteData depends on is the DisplayData method. Here we use the Invoke Method of our RichTextBox, the control used to display the data, to create a new EventHandler which creates a new Delegate for setting the properties we wish for our message, then appending it to the value already displayed:
#region DisplayData
/// <summary>
/// method to display the data to & from the port
/// on the screen
/// </summary>
/// <param name="type">MessageType of the message</param>
/// <param name="msg">Message to display</param>
[STAThread]
private void DisplayData(MessageType type, string msg)
{
_displaywindow.Invoke(new EventHandler(delegate
{
_displaywindow.SelectedText = string.Empty;
_displaywindow.SelectionFont = new Font(_displaywindow.SelectionFont, FontStyle.Bold);
_displaywindow.SelectionColor = MessageColor[(int)type];
_displaywindow.AppendText(msg);
_displaywindow.ScrollToCaret();
}));
}
#endregion
NOTE: You will notice that we hyave added the STAThread Attribute to our method. This is used when a single thread apartment is required by a control, like the RichTextBox.
The next method we will look at it used when we need to open the port initially. Here we set the BaudRate, Parity, StopBits, DataBits and PortName Properties of the SerialPort Class:
#region OpenPort
public bool OpenPort()
{
try
{
//first check if the port is already open
//if its open then close it
if (comPort.IsOpen == true) comPort.Close();
//set the properties of our SerialPort Object
comPort.BaudRate = int.Parse(_baudRate); //BaudRate
comPort.DataBits = int.Parse(_dataBits); //DataBits
comPort.StopBits = (StopBits)Enum.Parse(typeof(StopBits),_stopBits); //StopBits
comPort.Parity = (Parity)Enum.Parse(typeof(Parity),_parity); //Parity
comPort.PortName = _portName; //PortName
//now open the port
comPort.Open();
//display message
DisplayData(MessageType.Normal, "Port opened at " + DateTime.Now + "\n");
//return true
return true;
}
catch (Exception ex)
{
DisplayData(MessageType.Error, ex.Message);
return false;
}
}
#endregion
Next lets take a look at our event handler. This event will be executed whenever there's data waiting in the buffer. This method looks identical to our WriteData method, because it has to do the same exact work:
#region comPort_DataReceived
/// <summary>
/// method that will be called when theres data waiting in the buffer
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void comPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
//determine the mode the user selected (binary/string)
switch (CurrentTransmissionType)
{
//user chose string
case TransmissionType.Text:
//read data waiting in the buffer
string msg = comPort.ReadExisting();
//display the data to the user
DisplayData(MessageType.Incoming, msg + "\n");
break;
//user chose binary
case TransmissionType.Hex:
//retrieve number of bytes in the buffer
int bytes = comPort.BytesToRead;
//create a byte array to hold the awaiting data
byte[] comBuffer = new byte[bytes];
//read the data and store it
comPort.Read(comBuffer, 0, bytes);
//display the data to the user
DisplayData(MessageType.Incoming, ByteToHex(comBuffer) + "\n");
break;
default:
//read data waiting in the buffer
string str = comPort.ReadExisting();
//display the data to the user
DisplayData(MessageType.Incoming, str + "\n");
break;
}
}
#endregion
We have 3 small methods left, and these are actually optional, for the lack of a better word. These methods are used to populate my ComboBox's on my UI with the port names available on the computer, Parity values and Stop Bit values. The Parity and Stop Bits are available in enumerations included with the .Net Framework 2.0:
#region SetParityValues
public void SetParityValues(object obj)
{
foreach (string str in Enum.GetNames(typeof(Parity)))
{
((ComboBox)obj).Items.Add(str);
}
}
#endregion
#region SetStopBitValues
public void SetStopBitValues(object obj)
{
foreach (string str in Enum.GetNames(typeof(StopBits)))
{
((ComboBox)obj).Items.Add(str);
}
}
#endregion
#region SetPortNameValues
public void SetPortNameValues(object obj)
{
foreach (string str in SerialPort.GetPortNames())
{
((ComboBox)obj).Items.Add(str);
}
}
#endregion
That is how you do Serial Port Communication in C#. Microsoft finally gave us intrinsic tools to perform this task, no more relying on legacy objects. I am providing this class and a sample application to show how to implement what we just learned. What I am providing is under the GNU General Public License meaning you can modify and distribute how you see fit, but the license header must stay in tact. I hope you found this tutorial useful and informative, thank you for reading.
Happy Coding
#55
Posted 13 July 2010 - 08:34 AM
Hi, this is a nice tutorial,
but I'd download the zip file and try to opent it with winZip Pro and i get this error.
End-of-central-directory signature not found. Either this file is not a Zip file, or it constitutes one disk of a multi-part Zip file.
any idea what went wrong?.
but I'd download the zip file and try to opent it with winZip Pro and i get this error.
End-of-central-directory signature not found. Either this file is not a Zip file, or it constitutes one disk of a multi-part Zip file.
any idea what went wrong?.
#56
Posted 13 July 2010 - 08:42 AM
JorgeA when I get time today I'll find the project, rezip it and upload it again. You're not the only one who has had issues with it.
#57 Guest_Reinaldo*
Posted 14 July 2010 - 09:14 PM
Hi
I get th GPS data for my C# application runing in Win CE 5.0, from a Navigation Software's API.
Is there any way I can synchronize my app. to new data in the API?
Is it possible to have a buffer receiving from the API and the use something like ON Comm in VB6?
I get th GPS data for my C# application runing in Win CE 5.0, from a Navigation Software's API.
Is there any way I can synchronize my app. to new data in the API?
Is it possible to have a buffer receiving from the API and the use something like ON Comm in VB6?
#58 Guest_Rob Berry*
Posted 15 July 2010 - 01:33 PM
Hi,
looks great, I just tried to open the file in Visual Studio 2010 and it looks like it was going to open but it failed. Got the following error
C:\dotnetserial\SerialPortCommunication\SerialPortCommunication\SerialPortCommunication.csproj : error : Unable to read the project file 'SerialPortCommunication.csproj'.
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Microsoft.Common.targets(1203,12): The project file could not be loaded. The 'CreateItem' start tag on line 1201 position 10 does not match the end tag of 'Output'. Line 1203, position 12.
Can you please advise what to do? I really want to see your code...
Thanks,
Rob Berry
looks great, I just tried to open the file in Visual Studio 2010 and it looks like it was going to open but it failed. Got the following error
C:\dotnetserial\SerialPortCommunication\SerialPortCommunication\SerialPortCommunication.csproj : error : Unable to read the project file 'SerialPortCommunication.csproj'.
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Microsoft.Common.targets(1203,12): The project file could not be loaded. The 'CreateItem' start tag on line 1201 position 10 does not match the end tag of 'Output'. Line 1203, position 12.
Can you please advise what to do? I really want to see your code...
Thanks,
Rob Berry
#59 Guest_MarcoVecchi*
Posted 03 August 2010 - 04:31 AM
I've downloaded your source code and tryed it.
I've tryed to open the port COM2 of my notebook which is a "HANDHELD BARCODE SCANNER" port (the scanner is connected via USB and i've downloaded the driver to emulate COM port) but when i click on the button OPEN PORT i get the followin error message:"The specified name either doesn't start with COM/com or doesn't resolve in a valid serial port"
Can you help me in finding the reason of this?
Thanks
I've tryed to open the port COM2 of my notebook which is a "HANDHELD BARCODE SCANNER" port (the scanner is connected via USB and i've downloaded the driver to emulate COM port) but when i click on the button OPEN PORT i get the followin error message:"The specified name either doesn't start with COM/com or doesn't resolve in a valid serial port"
Can you help me in finding the reason of this?
Thanks
#60 Guest_congtk88*
Posted 19 August 2010 - 06:23 AM
thank you very much!i have a problem in serial port communcating.i hope that you will post a lot of cirticle about C#
|
|

MultiQuote







|