The SerialPort class in C# allows you to communicate with a serial port in .NET. This article will demonstrate how to write and receive data from a device connected to a serial port in C# and .NET. We will be writing the received data to a TextBox on a form, so this will also deal with threading.
In the past, to communicate with a Serial Port using .NET 1.1, you had to either use the Windows API or third-party control. With .NET 2.0 and above, Microsoft has added this support with the inclusion of the SerialPort class as part of the System.IO.Ports namespace. Implementation of the SerialPort class is very straightforward. To create an instance of the SerialPort class, you pass the SerialPort options to the class's constructor.
// all of the options for a serial device
// ---- can be sent through the constructor of the SerialPort class
// ---- PortName = "COM1", Baud Rate = 19200, Parity = None,
// ---- Data Bits = 8, Stop Bits = One, Handshake = None
SerialPort _serialPort = new SerialPort("COM1", 19200, Parity.None, 8, StopBits.One);
_serialPort.Handshake = Handshake.None;
To receive data, we will need to create an EventHandler for the "SerialDataReceivedEventHandler":
// "sp_DataReceived" is a custom method that I have created
_serialPort.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived);
You can also set other options, such as the ReadTimeout and WriteTimeout.
// milliseconds _serialPort.ReadTimeout = 500;
_serialPort.WriteTimeout = 500;
Once you are ready to use the Serial Port, you will need to open it:
// Opens serial port
_serialPort.Open();
Now, we are ready to receive the data. However, to write this data to the TextBox on a form, we need to create a delegate. .NET does not allow cross-thread action, so we need to use a delegate. The delegate writes to the UI thread from a non-UI thread.
// delegate is used to write to a UI control from a non-UI thread
private delegate void SetTextDeleg(string text);
We will now create the "sp_DataReceived" method that will be executed when data is received through the serial port,
void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
Thread.Sleep(500);
string data = _serialPort.ReadLine();
// Invokes the delegate on the UI thread, and sends the data that was received to the invoked method.
// ---- The "si_DataReceived" method will be executed on the UI thread, which allows populating the textbox.
this.BeginInvoke(new SetTextDeleg(si_DataReceived), new object[] { data });
}
Now we create our "si_DataReceived" method,
private void si_DataReceived(string data) { textBox1.Text = data.Trim(); }
We can now receive data from a serial port device and display it on a form. Some devices will send data without being prompted. However, some devices need to send certain commands, and it will reply with the data the command calls for. For these devices, you will write data to the serial port and use the previous code to get the data that will be sent back. In my example, I will be communicating with a scale. For this particular scale, sending the command "SI\r\n" will force it to return the weight of whatever is on the scale. This command is specific for this scale. You will need to read the documentation of your serial device to find commands that it will receive. To write to the serial port, I have created a "Start" button on the form. I have added code to its Click_Event:
private void btnStart_Click(object sender, EventArgs e)
{
// Makes sure serial port is open before trying to write
try
{
if(!(_serialPort.IsOpen))
_serialPort.Open();
_serialPort.Write("SI\r\n");
}
catch (Exception ex)
{
MessageBox.Show("Error opening/writing to serial port :: " + ex.Message, "Error!");
}
}
And that is all you need to do. I have attached the Visual Studio 2005 solution.
How to receive data from com port
Here is the complete application on how to receive data from a COM port in C#.
using System;
using System.IO.Ports;
using System.Threading;
public class PortChat
{
static bool _continue;
static SerialPort _serialPort;
public static void Main()
{
string name;
string message;
StringComparer stringComparer = StringComparer.OrdinalIgnoreCase;
Thread readThread = new Thread(Read);
// Create a new SerialPort object with default settings.
_serialPort = new SerialPort();
// Allow the user to set the appropriate properties.
_serialPort.PortName = SetPortName(_serialPort.PortName);
_serialPort.BaudRate = SetPortBaudRate(_serialPort.BaudRate);
_serialPort.Parity = SetPortParity(_serialPort.Parity);
_serialPort.DataBits = SetPortDataBits(_serialPort.DataBits);
_serialPort.StopBits = SetPortStopBits(_serialPort.StopBits);
_serialPort.Handshake = SetPortHandshake(_serialPort.Handshake);
// Set the read/write timeouts
_serialPort.ReadTimeout = 500;
_serialPort.WriteTimeout = 500;
_serialPort.Open();
_continue = true;
readThread.Start();
Console.Write("Name: ");
name = Console.ReadLine();
Console.WriteLine("Type QUIT to exit");
while (_continue)
{
message = Console.ReadLine();
if (stringComparer.Equals("quit", message))
{
_continue = false;
}
else
{
_serialPort.WriteLine(
String.Format("<{0}>: {1}", name, message) );
}
}
readThread.Join();
_serialPort.Close();
}
public static void Read()
{
while (_continue)
{
try
{
string message = _serialPort.ReadLine();
Console.WriteLine(message);
}
catch (TimeoutException) { }
}
}
public static string SetPortName(string defaultPortName)
{
string portName;
Console.WriteLine("Available Ports:");
foreach (string s in SerialPort.GetPortNames())
{
Console.WriteLine(" {0}", s);
}
Console.Write("COM port({0}): ", defaultPortName);
portName = Console.ReadLine();
if (portName == "")
{
portName = defaultPortName;
}
return portName;
}
public static int SetPortBaudRate(int defaultPortBaudRate)
{
string baudRate;
Console.Write("Baud Rate({0}): ", defaultPortBaudRate);
baudRate = Console.ReadLine();
if (baudRate == "")
{
baudRate = defaultPortBaudRate.ToString();
}
return int.Parse(baudRate);
}
public static Parity SetPortParity(Parity defaultPortParity)
{
string parity;
Console.WriteLine("Available Parity options:");
foreach (string s in Enum.GetNames(typeof(Parity)))
{
Console.WriteLine(" {0}", s);
}
Console.Write("Parity({0}):", defaultPortParity.ToString());
parity = Console.ReadLine();
if (parity == "")
{
parity = defaultPortParity.ToString();
}
return (Parity)Enum.Parse(typeof(Parity), parity);
}
public static int SetPortDataBits(int defaultPortDataBits)
{
string dataBits;
Console.Write("Data Bits({0}): ", defaultPortDataBits);
dataBits = Console.ReadLine();
if (dataBits == "")
{
dataBits = defaultPortDataBits.ToString();
}
return int.Parse(dataBits);
}
public static StopBits SetPortStopBits(StopBits defaultPortStopBits)
{
string stopBits;
Console.WriteLine("Available Stop Bits options:");
foreach (string s in Enum.GetNames(typeof(StopBits)))
{
Console.WriteLine(" {0}", s);
}
Console.Write("Stop Bits({0}):", defaultPortStopBits.ToString());
stopBits = Console.ReadLine();
if (stopBits == "")
{
stopBits = defaultPortStopBits.ToString();
}
return (StopBits)Enum.Parse(typeof(StopBits), stopBits);
}
public static Handshake SetPortHandshake(Handshake defaultPortHandshake)
{
string handshake;
Console.WriteLine("Available Handshake options:");
foreach (string s in Enum.GetNames(typeof(Handshake)))
{
Console.WriteLine(" {0}", s);
}
Console.Write("Handshake({0}):", defaultPortHandshake.ToString());
handshake = Console.ReadLine();
if (handshake == "")
{
handshake = defaultPortHandshake.ToString();
}
return (Handshake)Enum.Parse(typeof(Handshake), handshake);
}
}
Summary
This article taught you how to communicate with a COM port in C#. You also learned how to receive data from a COM port using C#.
Omer AYDINKALPosted Oct 17, 2024, 9:53 PM
Thanks for project
Clark SargePosted Oct 26, 2023, 6:46 PM
Very useful, thanks!!
imran alspriPosted Aug 20, 2023, 4:33 PM
Thanks for the example i used port "COM5" but can't run this error System.IO.IOException: 'A device which does not exist was specified.
Kumaresh ALAGAPPAPILLAIPosted Jun 1, 2020, 3:18 AM
How to read multiple port data to each textbox
naschd onePosted Feb 20, 2020, 6:40 AM
Why do you use ThreadSleep(500) in Receive data handler ? Is it OK to use Thread Sleep function ? And Another question is , what if I want to use some buffer and run write thread which gets messages from this buffer and executes write ? another thing is if there are two cycling threads there is high cpu consumtions if there is no thread sleep ..
Gin OhashiPosted Jul 9, 2019, 1:06 AM
Hi, Ryan Alford. I get this message in the 1st reading, why? How to fix it? System.TimeoutException: 'The operation timed out.'
Suryakant SinhaPosted Jun 21, 2018, 4:40 AM
Error 1 The type or namespace name 'SetTextDeleg' could not be found (are you missing a using directive or an assembly reference?) please help me out
Thiruppathi RPosted May 16, 2017, 3:10 PM
Nice article.Thanks for sharing..
Mohamad RamdanPosted Mar 17, 2017, 2:55 AM
Did anyone ever make a C# program that read serial ort from bar code scanner and save to database directly?
spiro bPosted Mar 13, 2017, 10:47 AM
What about if I want to write on a port and at the same time get response from another serial port?
kalu singh raoPosted Jul 9, 2016, 10:33 AM
Nice...
mahendra babuPosted Feb 27, 2016, 4:01 AM
Hi I am working with weigh bridge integration. I am getting some junk data.. ??? symbols in the data. i tried to trim but the output is like 3?19 instead of 3519 etc.. when i tried to replace ? i am loosing data.. any help regarding.
Nitin MPosted Aug 3, 2015, 4:40 AM
Serial port communication for glowing LED - High & Low, also to accept Input switch signal (digital high & low). In this case data received is not working. What is the alternative option?
SharadPosted Jul 17, 2015, 3:43 AM
good one...
Arjun DhilodPosted Jun 26, 2015, 8:16 AM
Hi [email protected] sorry for late reply u check my blog arjunwalmiki i thing you found solution there i am already posted how to read data from comport in console
Kuldip PowarPosted Oct 3, 2014, 7:17 AM
how to read data from multiple com port using single listener and save in data base
siva naidooPosted Jun 8, 2014, 3:28 PM
Hi Arjun. Tank you for the code. One problem I notice if weight changes it does not show change immediately in text box. Can you handle this please? my email address is [email protected]
Arjun DhilodPosted Sep 11, 2013, 1:04 AM
Dear Friend those people are doing hardware programing must be take good hardware cable male and female it is play very important part of data reading
bob sagetPosted Sep 10, 2013, 5:48 PM
Zip file is corrupt.
Arjun DhilodPosted Dec 4, 2012, 3:30 AM
hi Ryan i am using same code change that is _serialPort.Open(); _continue = true; readThread.Start(); _serialPort.DataReceived += new SerialDataReceivedEventHandler(_serialPort_DataReceived); or static void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) { SerialPort _serialPort = (SerialPort)sender; Console.WriteLine(_serialPort.ReadExisting()); } but still not read data from port
maes maesPosted Oct 22, 2012, 7:38 AM
Hi Ryan Alford Thanks for your code.but the program not read all data on serial port." all data on putty it's god " can you help me, please
Priyesh PrasadPosted Jun 28, 2012, 6:03 AM
Hi Ryan Alford Thanks for your code. it helps me lot. Can you tell me just one thing that you have written the code for the windows form,but is it possible to use the same code in case of web page.?? Please suggest
dung traneditedPosted May 17, 2012, 10:19 PMEdited May 17, 2012, 10:22 PM
Sorry. I don't understand why. it can send data to serial port device but it can't receive from serial port device. i use visual C# 2010. can you help me, please
dung tranPosted May 17, 2012, 10:19 PM
Sorry. I don't understand why. it can send data to serial port device but it can't receive form serial port device. i use visual C# 2010. can you help me, please ?
dung tranPosted May 17, 2012, 10:19 PM
Sorry. I don't understand why. it can send data to serial port device but it can't receive form serial port device. i use visual C# 2010. can you help me, please ?
zhaoPosted Jan 8, 2012, 9:58 PM
thank you very much, i hope it can work well
Clyde EisenbeisPosted Oct 12, 2011, 8:54 AM
I want the code to change the SerialPort baud params on request by the user. How do I close / dispose SerialPort so I can re-open with new baud params? Or perhaps the params can be changed some other way.
Dave ChikaPosted Jun 30, 2011, 10:16 PM
i am writing an application in C# which communicates with serial port by sending hex data to the port. how can i convert a textbox.text contents into Hex values of the number displayed on the textbox.text (displays these data after computation). example: my textbox.text may display any of these values like 16,17,24,34,39,49,52,65,68,81,89,99,101 or 129. is there any method to convert the displayed values on the textbox to hexadecimal equivalent of the value on the textbox and write such to the serilport in byte only not hex string. exmple if my textbox.text displays say 50,it should be converted to hex value of 0x32 and sent to the serialport as ox32 and not like this ox31,0x32 in ascii any code/ clue will be welcomed.
nandu nanduPosted Mar 24, 2011, 2:45 AM
i have a PBX device, i want to read data from PBX. how can i, as i don't have knowledge about usage of serial ports.
thoai damPosted Mar 18, 2011, 4:18 AM
good application
ArvindPosted Feb 21, 2011, 10:20 AM
hello, your article mentioned afore was pretty useful.. it gave me a direction.. i am trying to do a memory read operation on an embedded system and i give the address as hex input which is 32 bit.. i want the address to be sent to the embedded system through serial port as my embedded system only supports serial port, and again read the data from that memory location.. eg: memory location = 12345678 can u help me out??
Davis MoshweunyanePosted Jan 31, 2011, 1:17 AM
Hi dude i would like to sent eight bit binary number to the serial port. Can you please help.
altaibaatar otgonbaatarPosted Nov 22, 2010, 4:30 PM
It was Very important article. Tnk u very much!
Massimo ZaninelloPosted Nov 2, 2010, 4:57 AM
I try to use this program, but when i start the debug, i find this error: UnauthorizedAccessExeption - Access to COM1 is denied. I think that there is something to set in the security project's properties, like FileIOPermission or something else, but i don't know what... Can someone help me? Thanks a lot
Xu YangPosted Oct 24, 2010, 3:29 AM
I have a project, which is a sensor based visual game. So, I want to read the data from COM port. I do not want to store the data, I just want to check the data, and make some control due to the data change. Thus, how do I do to achieve this function?
ahmmed dabaanPosted Oct 16, 2010, 7:07 AM
please i need your help friends.i can't read data from sensor board MTS310CB ,please if there are any one know just tell me :)
somasundari sPosted May 4, 2010, 11:55 PM
Great Support, Really it wil help full for system application developer
satwika gPosted Feb 17, 2010, 2:16 PM
Hi, I really appreciate you for sharing this important code online.Its really helpful.I have tried this code in windows application,its working without any issues.But I need to write the same code in asp.net.I have to read the data from serial port and write it into a textbox.I have tried lots of sample codes but ended up with a stack of errors.Could you please help me out? I need sample code like the above one for ASP.NET(C#). Pleae help me...its really urgent.. Thanks in Advance, Manasa
TienPosted Jan 5, 2010, 3:16 PM
To whom it may concern, What is the best practice to avoid any UI hanging when you are trying to periodically communicate to a microcontroller to update the UI control values as well as process any command the user wants (ie read/write to the microcontroller) using the same serial communication port? Thanks! - tvp
hari kunchuPosted Dec 16, 2009, 9:57 PM
im getting an error saying that my port is opened by something else. how do i find which process is using it
harish harishPosted Nov 14, 2009, 12:09 AM
will the code work for gsm modem? i am not getting output when i am sending AT/r/n.I am expecting ok response from modem
Ahmed AlHujaziPosted Sep 16, 2009, 9:25 AM
Hi Ryan, Would you have a minute to describe how this code can be used to access the serial port on the workstation from a web page? I'm trying to create a web app that will print to a printer off the serial port. Thanks. Ahmed
Tad ShupePosted Sep 5, 2009, 4:16 PM
Thanks for the very simple code. It helped me fix my problem quickly. T. Shupe
Tien Nhan MinhPosted May 2, 2009, 6:57 AM
Thank you very much!
NaveeneditedPosted Apr 9, 2009, 12:08 AMEdited Apr 9, 2009, 2:06 AM
Hi All, IM trying to write Hex value to serial port to which microcontroller is connected. It is written in C# (windows application). When i click on "Send" button Hex values has to written to Serial Port, but i need to click on "Send" button 4 - 5 times to see the output on the Oscilloscope(testing purpose) and the values i get are also incorrect. If i send out 45 bytes of data, it read 67 byte. Hex values which im sending to microcontroller are 4E EF 2B A1 3F 2E B2 AF 25 C7 5C 00 00 00 00 00 00 DB Im using the following method to write data to serial port. Here im reading data from a text file using streamreader and looping in through and writing the data. while ((_strValue = _readfile.ReadLine()) != null) { _SerialPort.Write(_strValue); } im trying to write the first Hex value which is "4E" as string. Is this correct?
JasonPosted Feb 7, 2009, 7:58 AM
I have a glucose device that I am using to get readings from. I have been looking online for weeks now for a way to check what device is connected to which port. I was sending commands to every port until I could read from the port. I figured this was bad to send commands to ports like this because of it being unsafe. Is their no way of checking what device is connected to which port? I don't no much about usb but I think devices have some way of telling the OS what it is so that the drivers can be loaded, correct? If so is there a way of checking in C# what port my device is on.
MRK MRKPosted Jan 31, 2009, 10:00 AM
thaks alot
tylos lingerPosted Jan 31, 2009, 8:01 AM
Thanks Ryan for your reply. I was wondering Ryan, can u help me with commands that can enable me communicate with modems connected to a landline and a pc?. Actually, what i want to do is develop an application, that can detect when calls are made and record it and also be able to note the time spent in making that call and also to record missed calls and others. I would really appreciate any help given me. Thanks in advance.
tylos lingerPosted Jan 30, 2009, 7:14 AM
Ryan, is there a generic command that can be used to force a device to send data back to an application like u used the "SI\r\n" to obtain info from the scale?
Tauseef AlamPosted Jan 5, 2009, 5:36 AM
In our Web Based POS we have multiple devices on different ports. Some are attached with USB ports and some are from COM ports. How can we manage all those using C#. What I am thinking to write a C# component and install at Client PC and call methds of the component using JavaScript. Any Help will be appreciated..!!
MarkeditedPosted Dec 30, 2008, 2:15 PMEdited Dec 30, 2008, 2:18 PM
I am trying to access my compass device. It take a 0x11 single byte command. I have modified the write portion to accomodate this: byte[] buffer_2_send = new byte[1]; byte data_2_send = 0x11; buffer_2_send[0] = data_2_send; _serialPort.Write(buffer_2_send, 0, buffer_2_send.Length);//; It gets to the sp_DataReceived buts then errors out at the following line: string data = _serialPort.ReadLine(); It is supposed to reply with the following data but instead errors out 3 times with: Error opening/writing to serial port :: The operation has timed out. reply: 9 bytes 0: degree high (unsigned 16bit) 1: degree low 2: minute (unsigned 8bit) 3: temperature high (status bit + 7bit) 4: temperature low (sign bit + 7bit) 5: inclination Y (sign bit + 7bit abs) 6: inclination X (sign bit + 7bit abs) 7: status 8: checksum Any ideas?? Mark
Guest UserPosted Dec 20, 2008, 2:16 PM
I am new to serial port, USB & hardward type. What is the best way (code wise ) to scan for the serial ports available on a given system. Thank you
Ryan AlfordPosted Dec 15, 2008, 8:46 AM
This code was used to connect to a floor scale. The customer that I wrote the code for would move a pallet onto the scale, and I would send the "SI\r\n" command to the scale so that it would return the weight. I also use this code to receive data from a serial port barcode scanner(without the "Write" method). When a barcode scanner scans, it sends the data through the serial port, and my application will display the scanned information on the textbox.
suhail ahmedPosted Dec 15, 2008, 1:10 AM
Hi dude, As i dont have knowledge about usage of serial ports , can I know the scenario where to use such serial ports as you mentioned here that reading data from serial ports?