NAVEEN CHOUDHARY | "Every person is a New door to a Different world."


SerialPort (RS-232 Serial COM Port) in C# .NET

+ No comment yet
Recently i am working on a project in which i have to fetch data from serial port for the identity card authentication. In that i have to store the data in the database after reading it from serial port and after processing it the result will be retrieved.

To refer Microsoft website for this : http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.aspx

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 via C# 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

go to Project Properties > Signing > Click on Create Test Certificate.  that’s it
SerialPort Terminal 01

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 an Atmel Microcontroller (recommended) or Microchip PIC.



Write Data Out Here is an example of how easy it is to use the new SerialPort control.  Very simply, here is how you can send a bit of data out the port.

// This is a new namespace in .NET 2.0
// that contains the SerialPort class using System.IO.Ports; private static void SendSampleData() { // Instantiate the communications
// port with some basic settings SerialPort port = new SerialPort(
"COM1", 9600, Parity.None, 8, StopBits.One); // Open the port for communications port.Open(); // Write a string port.Write("Hello World"); // Write a set of bytes port.Write(new byte[] {0x0A, 0xE2, 0xFF}, 0, 3); // Close the port port.Close(); }


Read Data From Port
Now let's take a look at what it takes to read data in from the communications port. This demonstrates reading text.
  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
  3. Run w/ F5, to exit the app, press Ctrl-Break.
  4. Get Connected with two USB to Serial adapters and a null modem
  5. Use another app, the code above, or the SerialPortTerminal.zip example to send data and watch it come in with this code

#region Namespace Inclusions using System; using System.IO.Ports; using System.Windows.Forms; #endregion 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:"); // Attach a method to be called when there
// is data waiting in the port's buffer port.DataReceived += new
SerialDataReceivedEventHandler(port_DataReceived); // Begin communications port.Open(); // Enter an application loop to keep this thread alive Application.Run(); } private void port_DataReceived(object sender,
SerialDataReceivedEventArgs e) { // Show all the incoming data in the port's buffer Console.WriteLine(port.ReadExisting()); } } }


Listing Available Ports
One of the (several) new methods that is supported, and one I'm very glad is finally here, is the ability to obtain a list of the COM ports installed on the computer (ex: COM1, COM2, COM4). This is definately helpful when you want to present the list of ports avalible for the user to select from (as in the SerialPortTerminal.zip Win App example).

foreach (string s in SerialPort.GetPortNames()) Console.WriteLine(s);


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; private static void SendTextFile(
SerialPort port, string FileName) { port.Write(File.OpenText(FileName).ReadToEnd()); } private static void SendBinaryFile(
SerialPort port, string FileName) { using (FileStream fs = File.OpenRead(FileName)) port.Write((new BinaryReader(fs)).ReadBytes(
(int)fs.Length), 0, (int)fs.Length); }

RS-232 Project Photos Each of these involve RS-232 serial port communications.

Just what's needed to get started with microcontrollers,
a Basic Stamp, mini LCD display, power, and RS-232 port.


Two USB to Serial adapters with a null modem
to loopback and test your serial software.


The brains to a mini automated radio station that let me
control my PC & home using my HAM radio from around town.


Port Wiring Notes
DB9 Male (Pin Side)                   DB9 Female (Pin Side)
DB9 Female (Solder Side)              DB9 Male (Solder Side)
    -------------                          -------------
    \ 1 2 3 4 5 /                          \ 5 4 3 2 1 /
     \ 6 7 8 9 /                            \ 9 8 7 6 /
      ---------                              ---------

DB9 Female to DB9 Female Null-Modem Wiring
 2 |  3 |  7 |  8 | 6&1|  5 |  4
---- ---- ---- ---- ---- ---- ---- 
 3 |  2 |  8 |  7 |  4 |  5 | 6&1

9-pin   25-pin  Assignment                 From PC
------  ------  -------------------------  ------------
Shield  1       Case Ground                Gnd
1       8       DCD (Data Carrier Detect)  Input
2       3       RX  (Receive Data)         Input
3       2       TX  (Transmit Data)        Output
4       20      DTR (Data Terminal Ready)  Output
5       7       GND (Signal Ground)        Gnd
6       6       DSR (Data Set Ready)       Input
7       4       RTS (Request To Send)      Output
8       5       CTS (Clear To Send)        Input
9       22      RI  (Ring Indicator)       Input

- 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:
  1. Beginning and Ending ("Start" & "Stop") Codes This is good for sending text as it lets everybody know when text starts and ends. You simply tack on a non-normal byte at the beginning and end of the text. For example, you'd use '---' to signify the start of the string and '===' to signify the end. So you would use: com.Output = "---Hello World===";
     
  2. Fixed Length Codes Used for specific commands. You can create your own codes to send and specify what they mean. Say I want to control the lighting in a house, I'd setup a protocol of commands like this:
    1st byte = House Code, 2nd byte = Light Code, 3rd byte = On or Off (0 for off, 1 for on)
    So to turn on the 11th light in my house (house code #3) I'd use:
    com.Output = new byte[] {3, 11, 0};
  3. Prefixed Data Packet This is probably the most common and flexible but requires the most coding. Just prefix your data packet with the length of the data. The prefix must be a fixed size, such as two bytes which would allow a data packet of up to 65,535 bytes. Then the receiver knows how much data is in the packet because it always takes the first two bytes and uses the rest as the data packet.
    Example: com.Output = ((char) 00) + ((char) 11) + "Hello World";