Professional Documents
Culture Documents
Serial Port rs232
Serial Port rs232
Serial Port rs232
C# .NET
Posted Wed, Mar 23 2005 19:28 by coad
.NET has a great class called SerialPort (MSDN reference) part of .NET 2.0 and is freely available
in C# Express on MSDN. It is easy to use. Here’s how…
BTW, this article is about communicating through the PC's Serial COM RS-232 port using
Microsoft .NET 2.0 or later by using the System.IO.Ports.SerialPort class. If you're looking for USB
info, see here.
To start off, here is sample code in a terminal application which you can try out to see how the
SerialPort class is used. This requires Visual Studio 2010 to compile, which can be obtained free
viaC# Express. It is just a simple little application with basic support for text or binary (hex)
modes to send and receive data. A nice feature or two is auto-detection of installed COM ports
that update at runtime if you plugin or remove USB-to-Serial adapters, also you can change the
DTR and RTS levels and monitor the CTS, DSR, and CD lines.
Build Note: You will receive an error that Visual Studio isn't able to find NoahCode.pfx. This is
expected as it is the click-once certificate for publishing and is NOT NEEDED for normal code use.
Just go to Project Properties > Signing > Click on Create Test Certificate. that’s it
Get Connected
You can obtain USB to Serial adapters and have just about as many ports on your PC as you like. I
carry around two adapters with a null modem (wikipedia) between them so I can create a
loopback to send & receive through to separate ports on most any computer. I'd recommend doing
the same for when writing code for the serial port.
If you'd like to quickly and easily create your own external devices to communicate with the PC, I
recommend starting with the Arduino, NetDuino (like an Arduino but programmed in C#),
or Parallax BASIC Stamp modules. All three have many accessories and sensors available (such as
LCDs, RF, Sounds, AD & DA, etc). sparkfun.com is a great place to look. After that you could
migrate to anAtmel Microcontroller (recommended) or Microchip PIC.
// Write a string
port.Write("Hello World");
1. Create a new "Console Application" and replace all the default class code with this code
2. Add a reference to "System.Windows.Forms" to the project
5. Use another app, the code above, or the SerialPortTerminal.zip example to send data and
watch it come in with this code
namespace SerialPortExample
{
class SerialPortProgram
{
// Create the serial port with basic settings
private SerialPort port = new SerialPort("COM1",
9600, Parity.None, 8, StopBits.One);
[STAThread]
static void Main(string[] args)
{
// Instatiate this class
new SerialPortProgram();
}
private SerialPortProgram()
{
Console.WriteLine("Incoming Data:");
// Begin communications
port.Open();
Sending Files
Here are two helpful little methods for sending files through the serial port. Of course, these are
the bare essentials and as always, you should check to make sure the port is open first
(port.IsOpen) and use try/catch around trying to open a file, but you get the gist with this code.
The binary sending routine is limited to about 2GB (the size of an int), but this should be okay for
most uses.
using System.IO;
- RTS & DTR are binary outputs that can be manually set and held
- DCD, DSR, CTS, and RI are binary inputs that can be read
- RX & TX can not be set manually and are controlled by the UART
- maximum voltages are between -15 volts and +15 volts
- binary outputs are between +5 to +15 volts and -5 to -15 volts
- binary inputs are between +3 to +15 volts and -3 to -15 volts
- input voltages between -3 to +3 are undefined while output voltages
between -5 and +5 are undefined
- positive voltages indicate ON or SPACE, negative voltages indicate
OFF or MARK
Protocol Development
If you are making your own serial interface/protocol, you really must have a good standard in
place. Serial data flows into the com port byte by byte and must be buffered and parsed correctly.
Think of it this way, if a terminal sent your computer "Hello World" it may come in as four
OnComm triggers: "H", "ello", " Wo", and "rld"
The best protocols are usually a mix of these methods. Here are three simple protocol techniques:
Other Resources
Here are some additional sites, libraries, tutorials, etc. These are links that I just found around the
net and am providing for convenience (they are not endorsed).
RS-232 on Wikipedia
SerialPort on MSDN
o Search on Google #1, #2, #3
1. Q: When updating a control (like a text box) while in the DataRecieved event, I
get an error.
A: The SerialPort class raises events on a separate thread than the main form was create
on. Windows Forms controls must be modified only on their original thread. Thankfully
there is an easy way to do this. Each Windows control has a "Invoke" method which will
run code on the control's original thread. So to put the recently received data into a text
box (txtLog), this would do it: txtLog.Invoke(new EventHandler(delegate { txtLog.Text
+= comport.ReadExisting(); }); You can see this more in action in the "Log" event of
"Terminal.cs" my sample code project, SerialPortTerminal.zip.
2. Q: I can't find the System.IO.Ports namespace.
A: Using Visual Studio 2003? The new namespace, and SerialPort class, is part of .NET 2.0
and Visual Studio 2005. It is not included in .NET 1.x (and Visual Studio 2003). Even if
you have .NET 2.0 or Visual Studio 2005 installed, you can not access the class from
within Visual Studio 2003.
For simple USB-to-Serial bridges that allow your device to communicate via RS-232 but
connect via USB to the PC, check out the section below on USB-to-Serial Bridge Chipsets
7. Q: Can I use the sample code here in my own projects (commercial or not)?
Yes! All sample code on my blog is free public domain material. I'm not a legal guy so I
don't know the exact words to use, but I'll try... I'm not responsible for any problems!
Use at your own rick etc. However, have at it, if it helps you out, fantastic, that's what it's
here for.
o The port may already be open by another program, only one app can use a port at
a time.
o The port may not exist on the computer (this happens a lot). Verify the port
you're trying to open is listed in the Device Manager (FAQ #9).
Lines marked ‘Output’ in the table can be set by the serial port to a high or low state (True
or False) and the ‘Input’ lines can be read as high or low. You can use
the PinChanged event to be notified when one of the input pins changes.
The Handshake property can be set to use RTS/CTS (uses hardware control lines) or
XON/XOFF (uses software) or both.
comport.PinChanged
+= newSerialPinChangedEventHandler(comport_PinChanged);
void comport_PinChanged(object sender, SerialPinChangedEventArgs e)
{
if (e.EventType == SerialPinChange.Ring) RingDetected();
}
14. Q: What pins can I use for powering devices, a high signal, or for boolean input &
output?
The TX & RX pins carry the standard serial signal, but the other pins can be used as
high/low input/output pins. The output pins (4 DTR or 8 CTS), supply 5 to 15 volts (15v is
proper RS-232 standard, 5v is what you’ll usually get) when high and low is 0 to -15
volts. They only supply flea current (very little current) so they're not meant to be used
for powering any devices (like USB is designed for). However, they can be used as a
reference voltage or for switching to one of the input pins for a high or low signal. The
input pins (1 DCD, 6 DSR, 8 CTS, and 9 RI) can be used to detect a high or low signal.
Proper RS-232 signal levels are -15v for a low and +15v for a high (compared to ground,
pin 5). A MAX232 or similar chip takes a TTL 0-5v input and produces the -15v to +15v
levels. However, most PC RS-232 COM ports will accept a 0v for low and 5v for high, but
it is not guaranteed and alters from PC to PC. If you want a simple "toggle high", just hold
pin 4 DTR high, and switch it to pin 1 DCD. The .NET SerialPort class has easy to use
properties for switching the output pins high or low and for detecting the current level of
the input pins. I have been able to use pin 4 DTR for a very low current (20ma max) PIC
processors, but not reliably. I prefer to always supply external power and use pin 4 as a
signal to turn on or off my device. I'll attach pin 4 to a transistor that switches my power
source to my PIC to turn it on or off.
15. Q: What about ‘packets’? Does RS-232 support any commands or data
segregation? OR Data comes in at seemingly random times?
Serial data flow through RS-232 has nothing to do with ‘packets’. It’s just a stream of
bytes in and out. There is no guarantee that data arrives together.
Packet Protocols
Any notion of data compartmentalization (packets) would have to be coded by you for your
unique use. Much of my time working with serial has been spent on defining useful packet
like protocols, that usually include some type of header, command structure, and CRC
check. For example, the first two bytes are the packet length, the next two bytes is the
command, next two bytes are parameters, and the last byte is a CRC. Then my apps
would buffer incoming data and look in the buffer for valid packets. Of course it differs
depending on the device you’re working with and your specific needs. USB does have
specific communications protocol defined, one of them being command based, like the little
packet just mentioned. But with USB, you’re able to get the whole command and
parameter together at once, with serial you have to create the protocol yourself, buffer,
and parse the data.
using System;
using System.IO.Ports;
using System.Collections.Generic;
namespace SerialComBuffering
{
class Program
{
SerialPort com = new SerialPort(SerialPort.GetPortNames()[0],
9600, Parity.None, 8, StopBits.One);
List<byte> bBuffer = new List<byte>();
string sBuffer = String.Empty;
static void Main(string[] args)
{ new Program(); }
Program()
{
com.DataReceived +=
new SerialDataReceivedEventHandler(com_DataReceived);
com.Open();
Console.WriteLine("Waiting for incoming data...");
Console.ReadKey();
}
void com_DataReceived(object sender,
SerialDataReceivedEventArgs e)
{
// Use either the binary OR the string technique (but not both)
// Buffer and process binary data
while (com.BytesToRead > 0)
bBuffer.Add((byte)com.ReadByte());
ProcessBuffer(bBuffer);
// Buffer string data
sBuffer += com.ReadExisting();
ProcessBuffer(sBuffer);
}
private void ProcessBuffer(string sBuffer)
{
// Look in the string for useful information
// then remove the useful data from the buffer
}
private void ProcessBuffer(List<byte> bBuffer)
{
// Look in the byte array for useful information
// then remove the useful data from the buffer
}
}
}
1. There are a number of companies that create USB chipsets that emulates an RS-
232 port. Some are much more compatible with PCs and Macs than others. For
example, the Prolific and FTDI chipset are used in the most compatible adapters
(unlike Ark Micro, or others). Those companies produce WHQL (Windows
Hardware Quality Labs) certified drivers and the drivers are built into most
Windows and Mac systems already. So when shopping for a cable, be sure to
check the chipset manufacture. Here are some handy links to drivers in case you
need them.
2. Standard RS-232 signals range from 3 to 15 volts (plus or minus), 0 is not a valid
signal. The USB-to-Serial interface chips used in these cables produce 0 to 5 volts,
standard TTL level logic. While this works for some PCs, and certainly most
microcontrollers, it is not 100% compatible. The ‘correct’ USB-to-Serial cables
incorporate an additional line level driver, like the MAX232, that take the 0 to 5
volts and convert it to an appropriate +/- 12 volts for RS-232. The problem is that
many low-quality cables exist out there without this line level driver chip.
1. FTDI FT232RL
The FTDI chips are most popular in electronics projects and used by companies like
Parallax and the Arduino Duemilanove. They also have the best support in terms
of evaluation modules, well written datasheet, and product availability. product
info,evaluation modules, buy from Mouser, drivers
2. Prolific PL-2303HX
These are the chips used in the most popular USB-to-Serial cables. They are
slightly less costly than the FTDI chips in bulk, but are not quite as well supported
in the US market. product info
3. TI TUSB3410
Another option from Texas Instruments. I haven’t used this chip. Product Info
p.s. For trying it out and prototyping, I personally recommend this particular FTDI
evaluation board, the UM232R since it plugs into typical solderless protoytpe
breadboards and has most of the pins easily accessible. Last priced it was $20 from
Mouser.
You can try leaving a comment below. Perhaps someone knows the answer
Try doing a search and look for other content. SerialPort C#, Serial Com C#, serial
port .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 use a
third-party control. With .Net 2.0, Microsoft 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 straight-forward. To
create an instance of the SerialPort class, you simply pass the SerialPort options to the constructor of the class:
You can also set other options, such as the ReadTimeout and WriteTimeout:
_serialPort.WriteTimeout = 500;
Once you are ready to use the Serial Port, you will need to open it:
Now we are ready to receive 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 is used to write
to the UI thread from a non-UI thread.
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.
Article Extensions
Contents added by Mahesh Chand on Aug 03, 2010
Here is complete code sample from MSDN.
using System;
using System.IO.Ports;
using System.Threading;
_serialPort.Open();
_continue = true;
readThread.Start();
Console.Write("Name: ");
name = Console.ReadLine();
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();
}
Console.WriteLine("Available Ports:");
foreach (string s in SerialPort.GetPortNames())
{
Console.WriteLine(" {0}", s);
}
if (baudRate == "")
{
baudRate = defaultPortBaudRate.ToString();
}
return int.Parse(baudRate);
}
Console.Write("Parity({0}):", defaultPortParity.ToString());
parity = Console.ReadLine();
if (parity == "")
{
parity = defaultPortParity.ToString();
}
if (dataBits == "")
{
dataBits = defaultPortDataBits.ToString();
}
return int.Parse(dataBits);
}
if (stopBits == "")
{
stopBits = defaultPortStopBits.ToString();
}
Console.Write("Handshake({0}):", defaultPortHandshake.ToString());
handshake = Console.ReadLine();
if (handshake == "")
{
handshake = defaultPortHandshake.ToString();
}
Each MSComm control you use corresponds to one serial port. If you need to access more
than one serial port in your application, you must use more than one MSComm control. The
port address and interrupt address can be changed from the Windows Control Panel.
Although the MSComm control has many important properties, there are a few that you
should be familiar with first.
Properties Description
OnComm Event
The OnComm event is generated whenever the value of the CommEvent property changes, indicating that
either a communication event or an error occurred.
Syntax
Private Sub object_OnComm ()
The OnComm event syntax has these parts:
Part Description
CommPort Property
Sets and returns the communications port number.
Syntax
object.CommPort[ = value ]
The CommPort property syntax has these parts:
Part Description
Remarks
You can set value to any number between 1 and 16 at design time (the default is 1).
However, the MSComm control generates error 68 (Device unavailable) if the port
does not exist when you attempt to open it with the PortOpen property.
Warning You must set the CommPort property before opening the port.
Data Type
Integer
Handshaking Property
Sets and returns the hardware handshaking protocol.
Syntax
object.Handshaking [ = value ]
The Handshaking property syntax has these parts:
Part Description
Remarks
Handshaking refers to the internal communications protocol by which data is
transferred from the hardware port to the receive buffer. When a character of data
arrives at the serial port, the communications device has to move it into the receive
buffer so that your program can read it. If there is no receive buffer and your program is
expected to read every character directly from the hardware, you will probably lose data
because the characters can arrive very quickly.
A handshaking protocol insures data is not lost due to a buffer overrun, where data
arrives at the port too quickly for the communications device to move the data into the
receive buffer.
Data Type
Integer
RThreshold Property
Sets and returns the number of characters to receive before the MSComm control sets theCommEvent property
to comEvReceive and generates the OnComm event.
Syntax
object.Rthreshold [ = value ]
The Rthreshold property syntax has these parts:
Part Description
Settings Property
Sets and returns the baud rate, parity, data bit, and stop bit parameters.
Syntax
object.Settings [ = value ]
The Settings property syntax has these parts:
Part Description
Remarks
If value is not valid when the port is opened, the MSComm control generates error 380
(Invalid property value).
Value is composed of four settings and has the following format:
"BBBB,P,D,S"
Where BBBB is the baud rate, P is the parity, D is the number of data bits, and S is the
number of stop bits. The default value of value is:
"9600,N,8,1"
The following table lists the valid baud rates.
Setting
110
300
600
1200
2400
9600 (Default)
14400
19200
28800
38400
56000
128000
256000
Setting Description
E Even
M Mark
N (Default) None
O Odd
S Space
8 (Default)
The following table lists the valid stop bit values.
Setting
1 (Default)
1.5
2
Data Type
String
InputLen Property
Sets and returns the number of characters the Input property reads from the receive buffer.
Syntax
object.InputLen [ = value ]
The InputLen property syntax has these parts:
Part Description
Remarks
The default value for the InputLen property is 0. Setting InputLen to 0 causes
theMSComm control to read the entire contents of the receive buffer when Input is
used.
If InputLen characters are not available in the receive buffer, the Input property
returns a zero-length string (""). The user can optionally check
the InBufferCount property to determine if the required number of characters are
present before using Input.
This property is useful when reading data from a machine whose output is formatted in
fixed-length blocks of data.
Data Type
Integer
Input Property
Returns and removes a stream of data from the receive buffer. This property is not available at design time and
is read-only at run time.
Syntax
object.Input
The Input property syntax has these parts:
Part Description
Remarks
The InputLen property determines the number of characters that are read by
the Inputproperty. Setting InputLen to 0 causes the Input property to read the entire
contents of the receive buffer.
The InputMode property determines the type of data that is retrieved with
the Inputproperty. If InputMode is set to comInputModeText then
the Input property returns text data in a Variant.
If InputMode is comInputModeBinary then the Input property returns binary data in
an array of bytes in a Variant.
Data Type
Variant
PortOpen Property
Sets and returns the state of the communications port (open or closed). Not available at design time.
Syntax
object.PortOpen [ = value ]
The PortOpen property syntax has these parts:
Part Description
Settings
The settings for value are:
Setting Description
True Port is opened
Remarks
Setting the PortOpen property to True opens the port. Setting it to False closes the
port and clears the receive and transmit buffers. The MSComm control automatically
closes the serial port when your application is terminated.
Make sure the CommPort property is set to a valid port number before opening the
port. If the CommPort property is set to an invalid port number when you try to open
the port, theMSComm control generates error 68 (Device unavailable).
In addition, your serial port device must support the current values in
the Settings property. If the Settings property contains communications settings that
your hardware does not support, your hardware may not work correctly.
If either the DTREnable or the RTSEnable properties is set to True before the port is
opened, the properties are set to False when the port is closed. Otherwise, the DTR and
RTS lines remain in their previous state.
Data Type
Boolean
DTREnable Property
Determines whether to enable the Data Terminal Ready (DTR) line during communications. Typically, the Data
Terminal Ready signal is sent by a computer to its modem to indicate that the computer is ready to accept
incoming transmission.
Syntax
object.DTREnable[ = value ]
The DTREnable property syntax has these parts:
Part Description
Settings
The settings for value are:
Setting Description
RTSEnable Property
Determines whether to enable the Request To Send (RTS) line. Typically, the Request To Send signal that
requests permission to transmit data is sent from a computer to its attached modem.
Syntax
object.RTSEnable[ = value ]
The RTSEnable property syntax has these parts:
Part Description
Settings
The settings for value are:
Setting Description
Remarks
When RTSEnable is set to True, the Request To Send line is set to high (on) when the
port is opened, and low (off) when the port is closed.
The Request To Send line is used in RTS/CTS hardware handshaking.
The RTSEnableproperty allows you to manually poll the Request To Send line if you
need to determine its state.
For more information on handshaking protocols, see the Handshaking property.
Data Type
Boolean
CommEvent Property
Returns the most recent communication event or error. This property is not available at design time and is read-
only at run time.
Syntax
object.CommEvent
The CommEvent property syntax has these parts:
Part Description
Remarks
Although the OnComm event is generated whenever a communication error or event
occurs, the CommEvent property holds the numeric code for that error or event. To
determine the actual error or event that caused the OnComm event, you must
reference theCommEvent property.
The CommEvent property returns one of the following values for communication errors
or events. These constants can also be found in the Object Library for this control.
Communication errors include the following settings:
Data Type
Integer
Output Property
Writes a stream of data to the transmit buffer. This property is not available at design time and is write-only at
run time.
Syntax
object.Output [ = value ]
The Output property syntax has these parts:
Part Description
Remarks
The Output property can transmit text data or binary data. To send text data using
theOutput property, you must specify a Variant that contains a string. To send binary
data, you must pass a Variant which contains a byte array to the Output property.
Normally, if you are sending an ANSI string to an application, you can send it as text
data. If you have data that contains embedded control characters, Null characters, etc.,
then you will want to pass it as binary data.
Data Type
Variant
Serial Port atau lebih popular dengan nama RS232 adalah protocol/interface yang paling banyak
digunakan dan popular terutamanya di kalangan pelajar. Rs232 protocol mudah digunakan,
incorporated in PC(mostly old PCs), some microcontroller dan tidak memerlukan hardware yg
expensive. But today,USB lebih popular kerana mudah, plug n play, and offer higher transfer rates
compared to RS232.
I have been using Serial Port for quite some time in a lot of projects. Contohnya, interfacing a robot
with external device such as zigbee or bluetooth module. So, i think it's good to write article about
serial port/RS232. My objective here is to show the way to write codes to access PC serial port
using mscomm32.ocx
.NET object
I prefer the 2nd method because lebih mudah digunakan and i use C#(.NET) a lot. I have written a
script in VBA to access serial port from Microsft Excel(using mscomm32.ocx). VBA stand for Visual
Basic for Application which is exists in Excel(you probably know it if you're familiar with Excel
macro)
If you're familiar with C# or C++ or VB.NET, then it's better jika anda menggunakan .NET
component. I will show an example of source code written in C# in this post. First of all, you need to
'define' the component in the project file by a 'using' statement on top of the file.
using System.IO.Ports;
The above statement will allow you to access serial port component.
class SerialPortCustom
{
SerialPort SP = new SerialPort();
public SerialPortCustom()
{
SP.BaudRate = 57600;
SP.Handshake = Handshake.None;
SP.Parity = Parity.None;
SP.PortName = " ";
SP.StopBits = System.IO.Ports.StopBits.One;
SP.DataBits = 8;
}
Next, you must have functions or methods to read data from receive buffer or to write data to transmit
buffer. Therefore, you can instantiate event handler for every data received as shown below. However,
you can use polling method if your application know the exact time of incoming data/packet.
// "write" method
public void WR_byte(byte byte_data)
{
argv[0] = byte_data; // argv[] used to
hold the data
SP.Write(argv, 0, 1); // transmit 1 byte
through serial port (com port)
}
In conclusion, it is easy to use/work with serial port (RS232) using .NET framework. If you are not
familiar with C#, you can write in VB and also C++. I wrote the script in VB.NET once for my final
year project purpose. The syntax are different but the concept is just the same. Now, let's move on to
the next section.
MSCOMM32.OCX - VBA
Selain menggunakan C#/.NET, it is possible to access serial port directly in Microsoft Excel. What you
need is just MSCOMM32.ocx and basic knowledge in VBA. However, several steps required before
you can start programming.
You need to register the file first so that your VB editor could recognize the components. Place the file
in system32 folder and then click start -> run and paste the command below.
Regsvr32 "C:\Windows\System32\mscomm32.ocx"
After you completed the lst step, run Microsoft Excel and open VB editor. Same as C#, 2 methods shall
be implemented, either event-based or polling method. Polling method is suitable if you know exact
time of incoming data.
With SerCom
.CommPort = com_number
.Settings = "57600,M,8,1"
.Handshaking = comNone
.InputLen = 8
.InBufferSize = 8
.NullDiscard = True
.InputMode = comInputModeText
.RThreshold = 1
End With
Next, you can use buttons to enable/disable serial port operation.
SerCom.InputLen = 0
' Setting InputLen to 0 causes the MSComm control
to read the entire
contents of the receive buffer
chdata = Replace(SerCom.Input, vbCrLf, "")
' get a stream of data from the receive buffer
' the codes also remove carriage return and line
feed