In Design Cs Serial

Thu, 11 Feb 2010 23:32:04 +0000





Créez les plus beaux lofts de luxe pour vos Sims Transformez les maisons de vos Sims en lofts élégants et avant-gardistes avec Les Sims 3 Inspiration Loft Kit. Grâce à une série de nouveaux objets pour les pièces principales des maisons de vos Sims, dont des gadgets astucieux pour votre bureau high-tech, une console de jeu de la prochaine génération pour la fantastique salle de jeu, des meubles modernes pour le plus contemporain des salons et bien plus encore, vos Sims peuvent désormais redécorer leurs maisons de manière ultramoderne ! Après avoir modernisé leurs maisons, revoyez leurs garde-robes en y ajoutant des tenues sophistiquées dernier cri. Si vos Sims ou leurs maisons ont besoin de renouveau, Les Sims 3 Inspiration Loft Kit vous permet de propulser vos Sims dans un environnement plus moderne inspiré des lofts !. CARACTERISTIQUES : * Ajoutez des meubles de luxe à la chambre, la salle de divertissement et la terrasse de vos Sims. * Transformez les maisons de vos Sims en espaces avant-gardistes avec des meubles contemporains, des tables basses élégantes et des oeuvres d'art éclectiques. * Offrez à vos Sims des appareils électroniques convoités dont des téléviseurs haute technologie ultraplats, des consoles de jeu, des chaînes hi-fi et bien d'autres objets. * Améliorez la garde-robe de vos Sims avec des tenues audacieuses, des costumes sur mesure et des vêtements d’extérieur sophistiqués. * Des objets supplémentaires d’anniversaire ! Ce kit spécial pour le 10ème anniversaire inclut trois objets populaires des jeux Les Sims et Les Sims 2 : le lit vibrant en forme de coeur, la guitare électrique et l'aquarium.

SerialPort (RS-232 Serial COM Port) in C# .NET
Published 23 March 5 7:28 PM | coad

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.

Way in the Past...

Back in my early (pre C# MVP) days, I had written an article on DevHood titled Serial COM Simply in C#. It became quite popular and is (currently) the top Google search for "serial c#". Now every week I get several e-mails with people asking questions and it is high time for some serious updating.

The article was (originally) written soon after .NET was introduced to the world, and other .NET serial port controls had not yet been written. So at the time, this was an easy solution. Just use the MSComm.ocx control from VS6 which most Devs had at the time. Now however, there are many easier and preferred methods than dealing with the complexities of interoping with an old legacy (non-.NET) ActiveX OCX control.



A Bright Future is Here!

Today, the primary solution is to use the new SerialPort control that is part of .NET 2.0 and is freely available in C# Express on MSDN. It is considerably easier to use and is a true .NET component.

Download Button - Small For loyal fans of the tutorial, I've written a sample code application, SerialPortTerminal.zip, which you can try out to see how the new SerialPort control is used. Requires Visual Studio 2005 & .NET 2.0 or later to compile & run.



Continued Support

Due to the high volume of e-mail I've been receiving on serial port communication in general, I've wrote this post and added an FAQ section to the bottom of the post. Check this first if you have questions. If you post a question as a comment that hasn't been answered in the post, I'll add it to the FAQ section.

For those of you who I've directed to this blog post, please understand that I'm just another guy working away at a full time job (helping manage the release of Team System) who has worked with serial RS-232 ports in the past (moving on to USB now). I like to help people, hence I wrote the original article, this sample code, and the FAQ, but do not have the resources to answer additional serial port communication questions. Please check out the SerialCom FAQ for other .NET COM Port solutions and technical support options.



Get Connected Up

You can obtain USB to Serial adapters (from NewEgg, search using Froogle) and have just about as many ports on your PC as you like. I carry around two adapters with a null modem (what is it?, search Froogle) 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 Parallax BASIC Stamp modules. Parallax has lots of easy accessories (such as LCDs, RF, Sounds, AD & DA, etc) for their modules. After that you could migrate to an Atmel Microcontroller (recommended) or Microchip PIC.



Let's Have the Code

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


Now let's take a look at what it takes to read data in from the communications port. This demonstrates reading text; for an example of reading binary data, see my SerialPortTerminal.zip sample app.

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


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()) System.Diagnostics.Trace.WriteLine(s);


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
------ ------ ------------------------- ------------
Sheild 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


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).

* SerialPort on MSDN
* Search on Google #1, #2, #3
* CFSerialIO
* OpenNETCF Port

Where CF = Compact Framework



The Final Say (aka Conclusion)

The new SerialPort class in .NET 2.0 rocks! It is much easier to use than getting the old MSComm.ocx control going in a .NET app, contains new functionality, is a 'native' .NET control, has docs built into the MSDN Library, and is easy to use.

Frequently Asked Questions (FAQ)

I'm adding this section (as of 8/10/06) to address the common questions I get on this post and through e-mail. Chances are, if you ask a good question in the comments here, I'll post it here for others to see easily.

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.

3. Q: I only have .NET 1.1, what can I do?
A: Upgrade to .NET 2.0. Seriously, it's free. In fact, you can get the great C# and VB Visual Studio Interactive Development Environment (IDE) editors for FREE now with C# Express and VB Express. The .NET 2.0 Software Development Kit (SDK) for command-line development is also free. If you really must stay in .NET 1.1, you can use the technique I talk about in Serial COM Simply in C# or a 3rd party library.

4. Q: I'm sending data to my device, but it is not responding.
A: First make sure the device will respond using a standard app like Hyperterminal. Check the settings (baud rate, data bits, stop bits, etc) and make sure they match with your code. Try sending binary data via binary arrays. Many devices expect a carriage return at the end of a command, so be sure to send 0x0D or \n. String data can be easily converted to a binary array using:
byte[] data = System.Text.ASCIIEncoding.Default.GetBytes("Hello World\n");
com.Write(data, 0, data.Length);
Many devices require several carriage returns first to sync baud rates, so send several, like: com.Output("".PadLeft(9, '\n')); It you're communicating with a modem, make sure Echo Back is turned on. Send "ATE1\n". Other than this, just keep trying and playing around with it. It can be hard because you don't see the response from the device as easily as you would with a terminal app.

5. Q: When I put received data to a text box or rich text box, I get a strange symbols.
A: The default font of text boxes is designed only to show standard characters. Try using "CharMap" (a free tool in WinXP, click "Start", "Run", type "CharMap", enter). "Terminal" is a font designed to show classic ASCII characters and is what most terminal apps (like my sample code and Hyperterminal) use. There are also many ASCII codes that won't display correctly. This is why I choose to show the hex data instead of an ASCII string a lot of the time. System.Convert.ToString(mybyte, 16) will convert a byte to a string hex code, for example: byte b = 13; string s = Convert.ToStrong(b, 16).PadLeft(2, '0'), then s will contain "0D". See the "ByteArrayToHexString" and "HexStringToByteArray" methods in my sample app, SerialPortTerminal.zip.

6. Q: What about USB communications? How can I do USB?
This post isn't about USB. Believe me, I wish the .NET framework supported USB natively, and I'm doing what I can here at Microsoft to see USB get into the framework in the future. For now, you can use a USB to Serial adapter. I use a lot of these. They plug into the USB port, then appear just as a SerialPort to the PC. Microcontroller vendors such as Microchip, Atmel, and TI make chips that do this for projects. There is a lot of info on USB and C# out there too (such as this great article).

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.

8. Q: When using SerialPort.Open() (or SerialPort.PortOpen = true) I get the exception "UnauthorizedAccessException" or the error "An unhandled exception of type 'System.Runtime.InteropServices.COMException' occurred in axinterop.mscommlib.dll"
It may be one of a few factors:
* It may require Administrative privileges to use the port.
* The port may already be open by another program, only one app can use a port at a time.
* 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).
* The name being provided is not exactly correct.
Use the full name of the port when opening, like "COM1" (not "1")
9. Q: How do I know what COM ports are on my PC?
Use the Device Manager ("Start", "Run", "devmgmt.msc") and look for the "Ports" node (see below). If you don't see a Ports node, it's because there are not Serial or Parallel ports installed in the PC. Many laptops these day's don't have a serial port. You can get more serial ports very easily today with USB to Serial adapters.



10. Q: How do I communicate with my specific device? Modem, Mobile Phone, LED/LCD Display, Scanner, etc
This post is specific to general, device independent, serial port communications. You will need to find information about the protocol used for your specific device elsewhere. Comments that ask about specific devices will be deleted (to reduce spam). I'd recommend looking on the manufacture's website, writing/calling the manufacture, or searching online for your specific device, like "Motorola Razor Serial Protocol".

11. 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) when high and 0 to -15 volts when low. They only supply flea 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.

12. Q: What about ‘packets’? Does RS-232 support any commands or data segregation?
No. Serial data flow through RS-232 has nothing to do with ‘packets’. It’s just a stream of bytes in and out. 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. My previous serial post has more info under the header “Protocol Development”.

13. Q: How do you detect when a device is connected or disconnected?
Simply put, the device usually start or stop sending data. There is no built in events on a connect or disconnect. But there are a few tricks you can do, if you’re creating the serial device you have more options. I’ve had my devices (and PC apps) send a constant “are you there” set of bytes, like 00 00 11 11 00 00 hex (I’d use a ‘are you there’ custom ‘packet’ as in Q12 above) till a device on the other end responds. You could also use hardware, that’s what some of the other signals lines are for (CDC, DSR, RTS, CTS, RI), you can tie one of these high and then catch an event when the line goes high you know there’s a device there, when it goes low the device is gone.

14. Q: How can I get more support? What are my support options?
* Read this FAQ section! :)
* 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"
* Post a question in the .NET Base Class Library in MSDN Forums

Filed under: C#
Comments

# coad said on March 27, 2005 5:28 PM:

Nice!
And for devs searching for rs232 for the Compact Framework feel free to come here:
http://www.danielmoth.com/Blog/2004/09/serial-rs232-communications-in-net.html
# coad said on April 24, 2005 10:29 PM:

Cool stuff.
# coad said on May 4, 2005 1:30 AM:

hey

i cant find the name space
using System.IO.Ports
there is nothing like Ports.
i'm using Visual Studio.net 2003
Please help me urgently
my email ID is arun5_appu@yahoo.com
# coad said on May 5, 2005 8:54 AM:

>I cant find the name space

Check this phrase near the start of this posting:

"the new SerialPort control that is part of .NET 2.0 (currently in Beta)"
# coad said on June 6, 2005 12:45 AM:

Hi,

I really thank you for being the only mangaed .Net source of seial comm.:)
I have .Net 2.0 Beta installed. And can compile your hello world! example. But when it tries to Open the port. Exception says there is no COM1 port.

Any Comments !
# coad said on June 6, 2005 12:57 AM:

You may not have a COM1 installed on your system, or it may already be in use.
# coad said on June 8, 2005 3:07 PM:

Nice Article..quite informative
# coad said on June 8, 2005 3:13 PM:

if I set the port.ReceivedBytesThreshold to 5 would the following event
port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
be called after there is 5 bytes in the buffer...

Also can you show how to use port.Read(buff,0,5) where buff is defined as

byte buff = new byte[5];

I am calling the port.Read function after the event is called 5 times to make sure there are 5 bytes in the buffer but still it doesn't work.
# coad said on June 8, 2005 11:09 PM:

The method's parameters are port.Read(byte[], int, int), so the first parameter is a byte array (byte[]). Try: byte[] buf = new byte[5];

But I don't recommend reading a fixed # of bytes if possible since it is very easy to get one or two bytes off in the incoming buffer and hence not receive the data when expected or get unexpected results.

This is much preferred since it handles any amount of incoming data. Just process what ends up in the PortBuffer and remember to clean it out from time to time to prevent memory creep.

private List PortBuffer = new List();

private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort port = (SerialPort)sender;

byte[] data = new byte[port.BytesToRead];

port.Read(data, 0, data.Length);

PortBuffer.AddRange(data);

ProcessIncomingData(PortBuffer);
}

private void ProcessIncomingData(List PortBuffer)
{
// Search through the bytes to find the data you want
// then remove the data from the list. It is good to
// clean up unused bytes (usually everything before
// what you're looking for)
}
# coad said on June 9, 2005 9:55 AM:

Thanks for your help man....

One question.... I have data coming through bus in sets of 5 bytes at a time at very high speeds...about 1.5ms delay. Is there anyway I can force the program to call SerialDataReceivedEventHandler after it gets 5 bytes of data.... by setting port.ReceivedBytesThreshold to 5 do it????
# coad said on June 9, 2005 1:51 PM:

I'd suppose so, have you tried it? I use the technique above so I've never tried triggering the event on x # of bytes. The purpose of changing the ReceivedBytesThreshold is not to capture little 'packets' like that, but to reduce the # of times the method is called if large amounts of data are streaming in.
# coad said on June 10, 2005 4:53 AM:

i cant find the name space
"System.IO.Ports"
i'm using Visual Studio.net 2003
Please help me, its urgent
my email ID is kapildvyas@yahoo.co.in
# coad said on June 10, 2005 11:51 AM:

thanks Noah... I'll try it if doesn't work i'll try the othe way ...

Kapil system.io.ports comes with visual studio 2005 beta version.
# coad said on June 11, 2005 6:24 PM:

I guess any client applications will need to upgrade to .net2.0 ? I am skeptical about this as .net is still in .net.

Can any one share any experience about this.

Seshagiri
# coad said on June 14, 2005 2:55 PM:

What I was thinking was would client applications need to install .net 2.0 if I used the new feature in my application. If it is so, in that case is it recommendable as .net 2.0 is still in beta stage and there could be compatibility issues with the final release.

Seshagiri
# coad said on June 14, 2005 5:50 PM:

Seshagiri: Yes, clients must be running .NET 2.0. The deployment version from Beta2 will be different than that for RTM. VS05 Beta2 is not for public release yet, that's for when the product is finalized and released to market the second week of November. In the mean time, it is for testing and deployment to select targets (w/ a Go Live licence, see MSDN).
# coad said on June 21, 2005 10:31 AM:

Hi Noah!

I'm trying to send a simple "ati4" command to a modem and receive its response, but all I get back is whatever ati command I send.

If I Send: ati4

I Expect To Get Back:
USRobotics Sportster 28800 V.34 Fax Settings...

B0 E1 F1 M1 Q0 V1 X4 Y0
BAUD=38400 PARITY=N WORDLEN=8
DIAL=PULSE ON HOOK, etc..

But Instead I Get Back: ati4

I've tried both my own test application as well as the one you created. Any ideas? Thanks so much!
# coad said on June 22, 2005 9:34 AM:

Update
------
Hi Noah!

After further debugging, I observe that the port_DataReceived function in your SerialPort Terminal example is never being called. I see the function being added as an EventHandler earlier:

comport.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);

I can't figure for the life of me why it's never reaching the function though. All I know is this is why, for example, I only receive an echo of my "at" command and not the actual "ok" response I'm expecting. I didnt change any of the code, so why would this be happening?

Cheers!
# coad said on July 7, 2005 11:30 PM:

This is a reply to 'Nathan Ie' question about the ATI4 question.

I had the same problem and found out, that if you use WriteLine() method to write the "ATI4" string it will echo the sting back.

You have to use the Write() method and specify the file feed "\r". If you call method Write("ATI4\r") you will get the expected result. You can also change the SerialPort.NewLine Property from "\r\n" to "\r" to make it work.

Hope that helped
# coad said on July 8, 2005 5:23 PM:

when i do "port.Open()", it says

UnauthorizedAccessException was unhandled.
Access to the port "COM1" is denied.
Make sure you have sufficient privileges to access this resource

I just put your code segment into a button1_Click handler. What should I do to make it work?
# coad said on July 8, 2005 5:44 PM:

Actually nevermind my previous post, i solved the problem. But i have a new question :)

How can I manually send bit signals to RTS & DTR?

I need to send something like "0110000011010000" to RTS and at the same time (synchronized) send its logic inverses to DTR.

I am a student from university of toronto and very new to serial programming. please help me!!
# coad said on July 12, 2005 2:05 PM:

I run your program on my desktop (Windows XP Professional with SP2 and Visual Studio.NET 2005 Beta 2), the port can't be opened. The IDE said that "Access to the port 'COM1' is denied." It is UnauthorizedAccessException. Please tell me how to solve the problem? Thank you very much!
# coad said on July 12, 2005 2:49 PM:

The port may not exist on your computer or may be in use by another application (like for a modem). Change "COM1" in the code to another port, like "COM2" and try that. You can also check to see what ports are avalible on your machine through the Device Manager (press Windows-Break, "Hardware" tab, "Device Manager" button, "Ports (COM & LPT)" node).
# coad said on July 14, 2005 11:34 AM:

You are right. I install ActiveSyn 4.0 which uses COM1. After I delete it, the program works very well. I have another question. I modify you program in DataReceive event handler:



void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
int intBytes = serialPort.BytesToRead;
byte[] bytes = new byte[intBytes];
serialPort.Read(bytes, 0, intBytes);

tbReceive.Text += intBytes.ToString() + ";";
}
The tbReceive is a TextBox control. When the program excutes at the last line,

tbReceive.Text += intBytes.ToString() + ";";

there is an exception, System.InvalidOperationException was unhandled. The error message is "Cross-thread operation not valid: Control 'tbReceive' accessed from a thread other than the thread it was created on." Please tell me what's reason and how to solve it. Thanks!

# coad said on July 16, 2005 9:40 AM:

Hi Charlie!

int intBytes;
void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
intBytes = serialPort.BytesToRead;
byte[] bytes = new byte[intBytes];
serialPort.Read(bytes, 0, intBytes);

this.Invoke(new EventHandler(SetText));


}
void SetText()
{
tbReceive.Text += intBytes.ToString() + ";";
}
# coad said on July 25, 2005 5:40 PM:

Hi Noah,

I read your article on System.IO.Ports.SerialPort class of new
C# Express. I tried to achieve a basic communication between my pc and the lab instrument with the following code:

After the usual port initialization,

if (com.IsOpen) com.Close();
com.Open();

// send char 34,14,192,51,0,0
com.Write(new string(new char[] { (char)34, (char)14, (char)192, (char)51, (char)0, (char)0 }, 0, 6));

// for testing purposes I connected TX and RX pins of the port...

// receive routine:
private void com_DataReceived(object sender, SerialDataReceivedEventArgs e)
{

// This method will be called when there is data waiting in the port's buffer

// Obtain the number of bytes waiting in the port's buffer
bytes = com.BytesToRead;

// Create a byte array buffer to hold the incoming data
buffer = new char[bytes];

// Read the data from the port and store it in our buffer
com.Read(buffer, 0, bytes);

}

After I activate the send routine, 6 bytes of data is received by pc but with some difference to the originally sent data.

I receive : 34,14,63,51,0,0 everytime instead of 34,14,192,51,0,0

I tried to transmit 34,14,127,51,0,0 and received the same data sequence...

As I try to tranmit anything bigger than 127 I receive 63 instead of the original data...

Do you have any idea why this is happening consistently?

Regards,
Haluk Gokmen
# coad said on July 25, 2005 10:47 PM:

Haluk: Have you tried using a byte array instead of a character array?
byte[] buffer = new byte[com.BytesToRead];
# coad said on July 25, 2005 10:53 PM:

Green,
Thanks for the update to charlie's post. The reason for this is that WinForms controls' properties must be modified on the same thread that they were created on. By using this.Invoke (where "this" is the form the control is on), it asks the form to run another method on the same thread the form is on. serialPort_DataReceived could be triggered at anytime (not just when the form is avalible) since the SerialPort control runs outside of the form's thread. This is a big advantage in that it will always be responsive to incoming serial data even if the form is busy with an intensive redraw or update.
# coad said on July 26, 2005 2:44 AM:

Dear Noah,
I tried byte array on the receiving side without a difference on the result.

I was succeding on a similar operation in VS.NET by utilizing MSComm OCX as suggested in your article at www.devhood.com/tutorials/ tutorial_details.aspx?tutorial_id=320
The following is the code:

private byte[] recdata = new byte[40]; //received data array


public void InitComPort()
{

// Set the com port to be 1
com.CommPort = 1;

// This port is already open, close it to reset it.
if (com.PortOpen) com.PortOpen = false;

// Trigger the OnComm event whenever data is received
// Loop based receieve activated...
com.RThreshold = 0;

// Set the port to 9600 baud, no parity bit, 8 data bits, 1 stop bit (all standard)
com.Settings = "9600,n,8,1";

// Force the DTR line high, used sometimes to hang up modems
com.DTREnable = true;

// No handshaking is used
com.Handshaking = MSCommLib.HandshakeConstants.comNone;

// Don't mess with byte arrays, only works with simple data (characters A-Z and numbers)
com.InputMode = MSCommLib.InputModeConstants.comInputModeBinary;

// Use this line instead for byte array input, best for most communications
//com.InputMode = MSCommLib.InputModeConstants.comInputModeText;

// Read the entire waiting data when com.Input is used
com.InputLen = 0;

// Don't discard nulls, 0x00 is a useful byte
com.NullDiscard = false;

// Open the com port
com.PortOpen = true;
}

private void cmdRead_Start_Click(object sender, System.EventArgs e)
{
long TimeStamp = DateTime.Now.Ticks; // Time Stamp for Time-out
bool ElapsedTime;

com.Output = new string(new char[]{(char) 34, (char) 14, (char) 192, (char) 51, (char) 0, (char) 0});

// collect data during the first one second period...
do
{
// Dont lock up the entire application
// release control to process other messages.
System.Windows.Forms.Application.DoEvents();

// If there is data waiting, buffer it in our own byte array...
if (com.InBufferCount >= 34) recdata = (byte[])com.Input;

// Look for the Elapsed Time
ElapsedTime = DateTime.Now.Ticks - TimeStamp > TimeSpan.TicksPerSecond * 1;

// Keep waiting for 1 second before processing incoming data stream...
}
while (!ElapsedTime);

Global.samplescounter = recdata[27] * 100 + recdata[26];
lblRead_RecordNo.Text = Global.samplescounter.ToString();
.
.
.
}

My instrumentation which is target to this communication action is responding to data sent in char format. It doesnt respond to byte arrays.
This previous code is still working but I cant get the new one working.
Regards..
# coad said on July 27, 2005 7:50 AM:

Briefly, I would like to transmit Unicode 192 (u\192) from the serial port and read it back again. How can I do this in C# 2005 Express?
# coad said on July 28, 2005 9:52 PM:

You're right.. it's much easier!

but i have a little problem

I get this from the serial port:

U001W1 N 1,852 kg
U001W1 N 1,852 kg
U001W1 N 1,852 kg
U001W1 N 1,852 kg
U001W1 N 1,852 kg

How can i fix it, that i just geht the "1,852" from it?

thanxx
# coad said on July 29, 2005 4:59 PM:

Hello Noah and every visitor. Thanks for the great introduction to the SerialPort.
I have written a simple code, and to test i have used a cross over cable from COM1 to COM2. If I run 2 instances of the code on the 2 ports it works (send and receive) perfectly. But if I use Hyper Terminal on one end (say for example Hyper terminal on COM2 and my code on COM1) my code can send and hyper terminal receives it but if hyper terminal sends my code do not see anything. The same thing happended when i used your sample code. But of course when i test two instances of hyper terminal can eailty talk to each other.
What am I missing here?
# coad said on August 1, 2005 2:59 AM:

How do you set serial port encoding?
# coad said on August 1, 2005 9:46 AM:

Haluk,
Try using the SerialPort.Encoding property. For example: port.Encoding = System.Text.Encoding.UTF8;
# coad said on August 4, 2005 6:52 AM:

Great intro maan.

I tried reading from COM1 using VB.NET (2005 beta 2). I am not able to get the DataReceived event to get triggered. The data from a connected scale transmits whenever its weight is stable.

I coded this in a form. Does it have to be a console application instead ?
I am using ReadExisting(). Do you need to use ReadByte() ? If yes, does that code need to be in a thread to avoid sync/no-timeout ?

Thanks for any advice.
# coad said on September 1, 2005 7:42 AM:

I have written a program that sends commands to and receives the responses from a serial device. This work normaly. However the device is also outputing data every .x seconds. I am having a very difficult time receiving this data and getting it onto my form. Your suggestions and advice are greatly appreciated.


Private Sub Write_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Write.Click

Dim gxTXDBuffer As String
Dim sInput As String

Dim lTimeout As Long
Dim Time As Long

'clear input buffer counter
AxMSComm1.InBufferCount = 0

'setup command to send
gxTXDBuffer = sendtext.Text & Chr(10)

'send command
AxMSComm1.Output = gxTXDBuffer

'-----------------------------------------------------------------------
'not sure how to get data when counting
'
'While sendtext.Text = "C"
' Microsoft.VisualBasic.Timer > lTimeout
'
'read in response
'sInput = AxMSComm1.Input
' receivetext.Text = sInput
' End While
'-----------------------------------------------------------

'wait for response or timeout
lTimeout = Microsoft.VisualBasic.Timer + 5

Do
Application.DoEvents()

Loop Until AxMSComm1.InBufferCount >= 8 Or Microsoft.VisualBasic.Timer > lTimeout
'
'read in response
sInput = AxMSComm1.Input
receivetext.Text = sInput

End Sub
'another attempt at reading counts when com event
'
' Private Sub AxMSComm1_OnComm()
' Dim sInput As String
' commevent 2 = Received RThreshold number of characters. This event is generated continuously
' until you use the Input property to remove the data from the receive buffer.
' If AxMSComm1.CommEvent() = 2 And AxMSComm1.InBufferCount > 0 Then
' sInput = AxMSComm1.Input
' ' receivetext.Text = sInput
' End If
'' End Sub
# coad said on September 1, 2005 10:23 PM:

How do you program the Basic Stamp to output a string that you sent from your PC?

Anyone can help?

Thanks!!!
# coad said on September 5, 2005 10:59 PM:

I am using VS.Net 2003, Actually i ve to do hardware interface in which i need to recieve data and plot it as graph and save it in database. Can anyone help me out...
Thanks
# coad said on September 8, 2005 3:55 PM:

Hi All,

I have the following problem:

After sending a Write command to a device, directly followed by a Read command it seems that the data on the device is not yet available.

It seems that the write/read part is too fast for the device to 'generate' the data.

The baudrate is 9600 and cannot be higher. Also i would not like to add a pause.

Does anyone have a solution here ?

Thanx,

Jan
# coad said on September 14, 2005 12:59 AM:

What about the Timer in windows forms, for data arriving at any time and various durations?
does firing an event during reading current event would cause problems?

thanks for your efforts

thanks,

elwolv
# TrackBack said on September 25, 2005 1:55 AM:

# coad said on September 26, 2005 6:26 AM:

Hi All,

Noha - a great article!

For some reason I'm not reaching the 'port_DataReceived' function. Any ideas why?
I'm running the 'SerialPortTerminal' application on my computer with the 'Portmon' application monitoring all data at the serial port so nothing is physically connected to the COM. May this be the reason?

Thanks for your help.


Elad
# coad said on October 12, 2005 3:27 AM:

Hi there,

Your article is awesome and the information is so great and very useful.

However, I have a problem when I tried to write a software to communicate to bluetooth ports(COM4 and COM7) in PDA. The .NET 2.0 does not provide a platform for mobile device.

Suggestions please.

Thanks a lot,
Ikkyusan ;)
# coad said on October 17, 2005 8:53 PM:

Ikkyusan:
The .NET Compact Framework does not have built in support for serial communications. There are many third-party controls available. Try a Google search like:
http://www.google.com/search?hl=en&q=serial+com+compact+framework
# coad said on October 28, 2005 3:07 PM:

This is an awesome and extremely useful article! My one suggestion is that you add some minor clarifications on the DtrEnable property. I'm connecting to an Ultra 5 Sun box and was having a lot of troubles with my commands just getting echoed back to me. Setting the DtrEnable = true solved that problem. My understanding is that it tells the serial port that you're talking from one data transmitter to another data transmitter.
# coad said on November 12, 2005 10:21 AM:

Im trying to contact my sony wavehawk scanner with.
port = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
port.Encoding = System.Text.Encoding.Default;
port.NewLine = "\r";
port.ReceivedBytesThreshold = 1;

port.DtrEnable = true;


It reacts, but I dont get the "ok." that I'm expecting... Any ideas?

I use Serial monitor so that I see what goes in and out.

//J
# coad said on November 13, 2005 8:29 PM:

I am try to get exactly Method that line the Hexa Method using for sending data throught RS232, that I want is the function fo sendding binary. How can I slove this problem, thank for helping!
# TrackBack said on November 19, 2005 4:53 PM:

# coad said on November 25, 2005 2:14 PM:

Jimmy:
Don't forget to attach a delegate to the DataReceived event, open the port (.Open), and send data (.Write). Beyond that, it may be something specific to your scanner device.
# coad said on November 28, 2005 10:42 AM:

The .NET 2.0 class library does not seem to support devices powered by the serial port.

I have a couple different magstripe readers here at work which will work correctly after making a connection with HyperTerminal or opening the port in a similar .NET 1.1 library, but the device will not function after SerialPort.Open() on .NET 2.0, whether I write a driver program from scratch or try something like Noah's Serial Terminal. No exception is thrown and SerialPort.PortOpen return True so I know at least, the class library thinks it is funnctional. The light on the device, however, is off, so I know it's not getting power.

Does anyone have a serial port powered device working?
# coad said on November 28, 2005 11:19 AM:

Great tutorial. I really want to read data from the com port using managed c++ rather than C#. Can't find a sample anywhere, Heeellllp!!!
# coad said on December 8, 2005 7:15 AM:

I am trying to open a connection to COM3 on my machine. I have a USB device attached to the computer and its drivers emulate a serial port on COM3.

SerialPort.GetPortNames() returns "COM1" and "COM3" and if i connect to the port using TeraTerm its fully functional and i can see the data.

When i invoke open on the port after having set the port name to "COM3" i get an argument exception that the name doesn't start with COM or that there is no such port. The name DOES start with COM and as i said, GetPortNames() includes COM3.

Anyone experienced this? Solutions?

I am using VS 2005 Final on Win XP SP2.

/// Isak
# TJ said on December 13, 2005 5:10 PM:

Does anyone know how to send a special character over the serial connection? Specifically I'm trying to send a ctrl+c.

Thanks!
# TJ said on December 23, 2005 11:09 AM:

How would I send a ctrl+c (break) via serial?

Thanks!
# Daniel said on January 5, 2006 6:43 PM:

Ive written a Serial Port monitoring app that reads data from the COM port real time and displays it to a Rich Text Box (along with any special characters such as Carridge Returns, Line Feeds etc). This program works perfectly on Windows XP however when I transfer it to my Server running Windows Server 2003 Standard Edition, it doesnt work. I have installed the NET.Framework 2 on the Server.

Further troubleshooting I redesigned the program to write a line of text to a text file when the method is called for Data waiting at the Serial Port Buffer. That line of code is :-

port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);

So it appears to me that the method is never being called. The text file also logs when the Serial port is opened and close and when any exceptions are thrown.

I know the device attached to the serial port is working as I fire up a 3rd Party Serial Port Monitor &/or Hyperterminal and I see the data continuously coming through.

Can anyone offer any assistance with this problem?

Thanks,
Daniel.
# Kintesh Patel said on January 13, 2006 4:30 PM:

Those who are using Serial to USB convertor, Please check article "USB-to-RS232 Hurdle Race" published in elektor electronics Sept. 2005.

It describe behind the scene effect and it's reason.
# Ashley said on January 17, 2006 6:16 AM:

Hi guys,

Many terminal programs that are available (Hyperterminal being one of them) do not implement handshaking correctly.

A normal 232 connection will most likely require DTR enabled as well as RTS as well.

For you apps try setting your serialport with

port.Handshake = System.IO.Ports.Handshake.RequestToSend;

This is what most terminal programs call hardware flow control. It will enable RTS/CTS flow control which most devices rely on for transmission timing.

You may have played with the handshaking in HyperTerminal but if you use a 232 hardware analyser you will notice that it does not change any lines on your port. Changing these setting with a .net v2 app certainly will

Setting DTR to enabled and handshaking to hardware should power the pin that manufacturers use for power robbing as well.

Hope that made sense and is of some use

Ashley



# Gan esh said on January 18, 2006 3:41 AM:

Hi, I am using Visual Studio .NET 2005 which has serial port class built with it.
I am developing a Web Application in which i require to do serial communication. and i just wanted to know how exactly to include the SerialDataReceivedEventHandler Event in my web application, please help me out.

Thanks in advance
gan esh
# Mark said on February 1, 2006 2:31 AM:

Thanks for the article Noah! I've run the sample as it is and have been unable to get a response from the Wavecom GSM Modem that I am trying to talk to - the port_DataReceived() event is never fired.

This is driving me nuts! Any ideas? I'm running this on a Windows 2003 Server using VC# Express 2005.

Regards,
Mark.
# Tim Nguyen said on February 3, 2006 7:46 PM:

If you are having trouble with this, remember to send a "\r\n" command. It works perfectly if you do this.
# LarsPetter said on February 4, 2006 11:21 AM:

I have connected my PC to a BS2 sitting on a Board of Education(using an USB to Serial adapter). When i write something to the BS2, it gets there, but it also ends up in the input buffer. Why does this happen, and how can i prevent it from happening?
# Glenn said on February 13, 2006 5:18 PM:

Using your code:
-----------------------------------------------
private List PortBuffer = new List();

private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort port = (SerialPort)sender;

byte[] data = new byte[port.BytesToRead];

port.Read(data, 0, data.Length);

PortBuffer.AddRange(data);

ProcessIncomingData(PortBuffer);
}

private void ProcessIncomingData(List PortBuffer)
{
// Search through the bytes to find the data you want
// then remove the data from the list. It is good to
// clean up unused bytes (usually everything before
// what you're looking for)
}
-------------------------------------------------
I need to find a two byte sequence (E0 80) in the data. I can find one byte or the other with something like this:
----------------------------------------------
int found = PortBuffer.FindIndex(delegate(byte i)
{return i==0xE0;}
);

Console.WriteLine(found);
----------------------------------------------
But how can I find the index of a exact sequence? Thanks.
# Mark Holt said on February 14, 2006 11:36 AM:

The SerialPort Terminal worked fine for me...that is if I was communicating with another SerialPort Terminal app.
When I tried to communicate with HyperTerminal I had to change the handshaking.

After:
comport.PortName = cmbPortName.Text;

Add:
comport.Handshake = Handshake.RequestToSend;

Or:
comport.Handshake = Handshake.RequestToSendXOnXOff;

I used SysInternals' Portmon to compare how HyperTerminal connects to the COM port vs. the .Net 2.0 SerialPort class and noticed quite a few differences that I cannot control via the SerialPort class such as:

IOCTL_SERIAL_SET_HANDFLOW has a different XonLimit and XoffLimit (1024 instead of 80 and 1024 instead of 200, respectively)

IOCTL_SERIAL_SET_TIMEOUTS has a different RI, RM, RC and WC (-1 instead of 10, -1 instead of 0, -2 instead of 0 and 0 instead of 5000, respectively)

IOCTL_SERIAL_SET_WAIT_MASK checks for RLSD and ERR (like HyperT) but also checks for RXCHAR, RXFLAG, CTS, DSR, BRK, and RING.

IOCTL_SERIAL_SET_QUEUE_SIZE has an InSize of 4096 (instead of 8192) and OutSize of 2048 (instead of 8192).
# Leslie Viljoen said on March 16, 2006 8:54 AM:

You probably have something else using that com port and it's locked. Make sure your terminal program is closed.
# Vincent Collin said on March 30, 2006 2:35 PM:

Thanks alot Noah,

Great tutorial, was very very useful in my project.

Framework 2.0 is pretty useful when you need to use those good old serial port.
# Carlos said on April 11, 2006 12:33 PM:

Hi, I am trying to read the data on COM7 (USB) on my machine.
When add the event handler to the progam i get an JIT debugging error: Class not registered.

Anyone expirienced this?

I'm using Visual C# Express ed. on Win XP SP2
# rachel said on May 11, 2006 1:15 AM:

port = new SerialPort("COM5", 9600, Parity.None, 8, StopBits.One);
port.Open();


USB Cable Off - > CPU 100%

Help me
# EP said on May 29, 2006 10:50 AM:

what is the source codes for RS232 connection in framework 1.0 ? please help me!!!!!
# Srikanta said on June 9, 2006 6:56 AM:

Thanks for this article.i am new to .net development.i am fresher in development.
i want to learn more deep in serial programming.
i have connected to com1.
i am able to check whether bonus card is present or not,but i want to raed data from card from a particular byte to n byte.
so which method i have to use and how to use.plz reply me with syntax and code
# hassan said on June 19, 2006 10:35 AM:

thinks for these information ,i want do this ,but in Visual Studio2003 . I mean open Port COM3 and have a communication with a modem and call from My Pocket PC
# hitesh said on June 20, 2006 1:24 AM:

hello,i want to require vb.net code for reading stream of data asynchronously from serial port using multithreading as a background thread,so that is required,if more than one RFID tag read by serial port at a time.so how i can store all the tag read by serial port.
# Ahmet Vehbi said on June 26, 2006 3:23 AM:

Dear All ;
Would you please send me the tha samples data's to compile in my own pc.
Because i couldn't achive to make the form in the appropriate shape,size or position.
Thanks to whom it may concern..
# Punx said on June 29, 2006 1:35 PM:

Why does my timer dont start when I use timer1.Enable=true inside the DataReceived event handler?
# TheRunningBoard said on June 29, 2006 8:14 PM:

Great work!
# Zak said on July 3, 2006 6:07 AM:

hi
I'm using Visual Studio.net 2003
I have installed the .NET 2.0 (not the beta version)
and I cant find the name space
System.IO.Ports
any idea why
please help me
# coad said on July 7, 2006 7:40 PM:

Zak:

Visual Studio 2003 is only for writing code against the .NET 1.1 framework. Even if you have .NET 2.0 installed, you won't see it in VS 2003. You need VS 2005. You can write the code with a plain text editor and compile it through the .NET 2.0 command line compiler.
# David Briggs said on July 9, 2006 8:41 PM:

I am doing some serial communication to a divice using .NET 2.0. The device has a set of simple commands, each command and responce is a fix size. Each command will generate a responce and a new command can not be sent until the responce from the previous command has been recived. I have set the DataReceived event handler to a method that will read the responce data. That part works OK. There is a flag in the event handler that I set when I read the response. I poll for that flag to see when I can sent the next command. My question is is there any way I can know when it is OK to send the next command without polling? The DataReceived event is raised on a secondary thread. If there was some way to get the thread Id of the event handler I could do a thread Join to tell when the data reading is done.
# De IT y cosas peores » Java vs .NET: Puerto Serie (Parte II) said on July 10, 2006 2:14 PM:

PingBack from http://cesarolea.com/index.php/archives/157
# shinoy said on July 20, 2006 11:49 PM:

it is good. But if some one could explain about if someone need to get data from an epbx, wat method can be used.
# silibug said on July 23, 2006 1:43 AM:

Hi... nice article :)

btw..

How can we communicate with our serials port on LAN environment.?.
any idea how to convert rs232 output for tcp/ip input?

PC LAN/switch Microcontroller Rs232 devices

thanks:)
# Noah Coad [MS] said on July 24, 2006 11:33 AM:

silibug,
There are devices that let you control RS232 ports remotely over an ethernet network. For example, the $99 LS100 by Aaxeon at http://www.aaxeon.com/products/Productdetail.aspx?cate=2&modelno=LS100 A Google search on "ethernet rs232" (without quotes) shows some more such devices.
# SR said on July 27, 2006 12:48 AM:

Thanks for creating this, it has helped me greatly. This is my first day using visual C# express and tutorials like this are making progress possible. Hopefully I can contribute in the future.

One note: In order to build, I had to comment the line //File.WriteAll(TempFile, html); out as I got an error "'System.IO.File' does not contain a definition for 'WriteAll'. Not sure if I am an isolated case, but it doesn't seem to affect the program.
# Allan said on August 9, 2006 8:53 AM:

I'm sending commands ATs for modem port, and the modem do not receive the commands. I use (SerialPort Terminal) .... HELP me


thanks
# Noah Coad [MS] said on August 10, 2006 12:22 PM:

Allan,
There isn't enough info in your comment to figure out what's going on. Try [ENTER] [ENTER] [ENTER] ATE1 [ENTER] The first set of [ENTER] commands is for the modem to detect the baud rate. ATE1 turns on echoing back commands so you can see if the modem is responding. Good luck.
# Noah Coad [MS] said on August 10, 2006 12:22 PM:

SR,
Thanks for the pointer! :)
# Julio Silva said on August 10, 2006 3:15 PM:

Hello,

I'm a begginer, and I'm tring to do a simple terminal (receive only) for my
pocket pc, built in C#, with CF.Net 2.0.

I have 2 bottons, one for serialport.open, other serialport.close.
And works fine, since it's for a GPS connection, and I see it
connecting/disconnecting.

I have a label, that if I do a label1.text=serialport.readexisting(); it
displays all.
but if I do it in serialport.datareceived event, it get's an runtime
error...
If I do anything like label1.text=serialport.readchar(); it get's the same
error.
What I'm doing wrong?
I only have some programming experience in Delphi and C++...

Thanks for your help,

jS
# Noah Coad [MS] said on August 10, 2006 7:24 PM:

jS,
I've answered your question in the (new) FAQ section:
http://msmvps.com/blogs/coad/archive/2005/03/23/39466.aspx#FAQ
# Julio Silva said on August 11, 2006 6:41 AM:

Sorry I missed it.
The problem it's now solved, thanks.

BTW there is an link error in SerialPort Terminal, the filename has a space, SerialPort Terminal.zip, and the link doesnt, so it say's it's not found...

Thanks again for the help,

jS
# coad said on August 14, 2006 5:39 PM:

Julio,
I agree the file name is confusing with the space (and has been for a long time). I've removed the space from all the links in the post and the filename.
# Seng said on August 16, 2006 8:46 PM:

Hi All

I try to use this example to send a ATDT6129 command to dial an extension number. I got an error message from my Modem. If I try to use Microsoft Hyper termanal it works. Any ideas?

Thanks
# Sheng Zhou said on August 16, 2006 9:33 PM:

Hi Coad

This example is very good, but atd or atdt command doesn't work. I have try other commands such as 'at', 'ati4' etc. they works. I don't know how to send a atd or atdt command to my modem. At moment, when I send atd or atdt command to my modem it got 'error' message back. Any ideas?

Thanks
# NAFF said on August 17, 2006 9:08 AM:

I am looking to setup serialport in VC++.NET V2. Do you have an example. All I wnt is to be able to read data from a microcontroller. I an new to VC++ and cant understand the c# example.

many thanks
# Bill - WV7G said on August 18, 2006 2:06 PM:

I've been searching for the simplest way of coding the deligate to send received text to a textbox. I should have known it would be a fellow HAM who had the answer!
Great stuff and very well done!
# Todor’s Weblog » Serial Communication said on August 22, 2006 2:53 PM:

PingBack from http://todor.be/blog/?p=45
# prem said on August 23, 2006 12:23 AM:

hi,
iam using visual studio3.0 and framework version is 1.1
Now ia want to access the serial prot using c#.

in this version SerialPort namespace can't use

how can i use API to access the serial port in C#(version1.1)
or
any method top access the SerialPort namespace in this version

plz help me
i want this very urgent
plz send
my email.id is
gpremkamal@yahoo.co.in
# coad said on August 29, 2006 5:44 PM:

Hey prem, I just wrote an answer to your question in the FAQ portion of this post as question #3. See: http://msmvps.com/blogs/coad/archive/2005/03/23/39466.aspx#FAQ
# Tsahi said on September 3, 2006 3:20 PM:

hi, regarding .net 2.0 being free, well, the sdk is free, but who wants to code in notepad? you will have to pay for visual studio 2005 lot's of dollars, and my understanding is that the "express" editions are only free until november 2006. but there's a free open souce alternative called SharpDevelop, at http://www.icsharpcode.net/OpenSource/SD/Default.aspx . i tried their version 1.1 a while back and it was not bad, except for a few bugs. i hope their version 2.0 (for .net 2.0) is better, but i didn't try.
# rajnish said on September 4, 2006 10:44 PM:

Dear Coad, I am an MCA student and need your help in , in Bi Directional interfacing an instrument, wherein I have to send some Delimited String to the instrument with certain commands Like ACK NAK STX etc. and Take the Data Instrument sends, So far I have been able to receive the data from the instrument, but while sending the data I don't get any reply, and nothing reaches to the instrument, where as the cable I have made is correct, and I know there is something wrong with the code it self please help me I am posting the details below please guide me how I can send the string to the Instrument i am using c# 2005 Please guide me Thanking you in anticipation Rajnish
# SilentDawn said on September 5, 2006 7:10 AM:

.net 2.0串å£é€šä¿¡æ–°æŽ§ä»¶--(serialPort)
# Gaurav said on September 11, 2006 6:18 AM:

Hello Sir, The code you have provided is very appreciable to me coz almost all my problems have been solved. But only one problem is there i m explaining you: I m using a RichTextBox to display all the data that is in Buffer, But while displaying that data that is coming to textbox is some symbols not the actual text data. Like as if we use HYPERTERMINAL a windows program where it will display all the calls,duration,Number etc. I want to display the same data in RichTextBox. Only the textual data. Plz Help????? Urgent??????????
# Noah Coad [MS] said on September 11, 2006 12:32 PM:

rajnish,
I just wrote an answer to your question in the FAQ portion of this post as question #4.
See: http://msmvps.com/blogs/coad/archive/2005/03/23/39466.aspx#FAQ
# Pockey said on September 13, 2006 8:56 PM:

Hi, thanks for your article!

I have a problem. In your demo program, after I click the "Close Port" when there are still data sending from the Serial Port, the application will die. And I have to use "Ctrl + Shift + Delete" to end it. Any method to solve this? With "comport.close()" and data still in process, where all the data will be sent to?
# coad said on September 22, 2006 12:23 AM:

Pockey,

In a case like this, you can do something like when the user clicks "close", in the form's closing event handler, make a loop that check's the comport's sending buffer, when it is 0, then allow the close to contine. I'd also set the cursor to a wait hourglass and add a timeout (in case it takes too long).
# Huy Tran said on October 4, 2006 12:03 AM:

hi Coad,

I am using serialport in framework 2.0 to make a connection to another port.I have some problem, some attribute in serialport are not has like AxInterop.MSCommLib.dll's attribute, such as : in AxInterop.MSCommLib.dll, there are have EOF enable, Sthreshold, Inputlen, InputMode. But in serialport, there is no these attributes.

One more question : Is serialport just suppose for Smart device (POCKET PC, WINDOWN CE)?

I am writing a app to connect another machine to send/receive data.

Please give me some advice!!

Thanx for reading.
# Jon said on October 16, 2006 9:08 AM:

Coad, thanks for the excellet article.

I have tried to implement it in C++.NET 2 and below is some of the code in question which I am having problems with, when I run this it gives me exception which says BUFFER CAN NOT BE NULL.

Any help would be greatly appreciated. I am working on a PIC MCU, I will make my work public on your blog once it works hopefully.

void SendRs232Data()

{

// Instantiate the communications port - this is done in //the form properties of serialPort control from the toolbox

// Open the port for communications

serialPort->Open();

// Write a string

serialPort->Write("Hello World");

int offset = 1;//The offset in the buffer array to begin //writing.

int count = 1; //The number of bytes to read.

array^ buffer ;//The buffer array to write //the input to.

serialPort->Read(buffer, offset, count);

serialPort->Close();

}
# Mach said on October 17, 2006 2:23 AM:

hi,

I want to have local resources (COM1, COM2) available to a terminal server.

I made my local serial port available in a session in Remote Desktop Connection window.

On terminal server I can see my serial port mapped to some TS033 and TS034 ports.

How can I open/use/connect these ports?

private SerialPort port = new SerialPort("TS033", 9600, Parity.None, 8, StopBits.One); deasn't work.

On WinServer2003 it says: The given port name does not start with COM/com or does not resolve to a valid serial port.

Thanks for any help.
# coad said on October 17, 2006 11:14 AM:

Jon,

You've defined the variable for the buffer, but you need to create an array as well. In C#, it would look like this:

byte[] buffer = new byte[10];
# coad said on October 17, 2006 11:15 AM:

Mach,

Usually ports are mapped to COMx, sometimes as high as COM32. Please see if you can map them to a COM number like this.
# coad said on October 17, 2006 11:17 AM:

Huy Tran,

The .NET 2.0 SerialPort class is not for devices, only full PCs. There are 3rd party serial classes for mobile devices. The .NET classes are wrappers around the Win32 APIs, so some of the members are renamed and they may not all be avalible.
# jon said on October 18, 2006 8:46 AM:

coed,

thanks for pointing me in the right direction. as you said buffer was not defined as an array correctly.

the program sort of works but does no print hello world, it prints the numbber 5, which is the byte size i am looking to print. i expected hello to print. any ideas as to where i am going wrong? many thanks.

void SendRs232Data()

{

serialPort->Open();

serialPort->Write("Hello World");

int offset = 0;//The offset in the buffer array to begin writing.

int count = 5; //The number of bytes to read.

array^ buffer = gcnew array (10);//The buffer array to write the input to.

serialPort->Read(buffer, offset, count);

lblSerial->Text= (serialPort->Read(buffer, offset, count)).ToString();

serialPort->Close();

}
# Dejan said on October 20, 2006 6:44 AM:

My project requires external GPRS modem attached to serial port to send and receive SMS messages.

In addition to original Noah's code at the start of the blog, I've laso added and changed some things according to hints in the blog (thanx, guys); following i s a short summary of my add-ons to make the modem work:

1. Set modem handshake, like:

serialPort1.Handshake = Handshake.RequestToSend;

2. Prior to send first command, try to synchronize modem by sending "\r\n" after port.Open(), like:

serialPort1.Write("\r\n"); // sync purpose only

3. Always use "\r\n" at the end of the command, like:

serialPort1.Write("AT+CMGF=1\r\n");

(just in the case of sending SMS message itself, I use something like:

serialPort1.Write(textBox1.Text + "\u000D\u000A\u001A\n");

)

4. As described in FAQ (Q1), use Invoke and event delegation, like:

private void MyLog(string msg)

{

listBox1.Invoke(new EventHandler(delegate

{

listBox1.Items.Add(msg);

}));

}

private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)

{

// Read data

string data = serialPort1.ReadExisting();

// Display the text to the user in the terminal

MyLog(data);

}

And this is it. After a couple of hours of being frustrated because of simplicity of using SerialPort class in .NET 2.0, but no result, it finally works.
# Yonas said on October 23, 2006 9:08 AM:

RE: Test,

you dont say what programe you are using, but if you are sending and receiving data from the same port for a test, i suggest you wire up a NULL MODEM cable with one end connected to your COM2 port and at the other end connect PIN2 and PIN 3 using a wire. This will send what ever is in the Tx line to Rx line and you should be able to send TEST and read TEST on you monitor. A quick test to verify your cable is wired right would be to use hyperterminal. I hope I understood what you are trying to do correctly.
# Matthias said on October 31, 2006 3:59 AM:

I need to send/recieve data to/from a uC using rs485 as protocol. I use a transducer to get the PC's rs232 and the uC's rs485 connected and therefore I need to have the RTS signal set at the start of writing data and unset it after all bytes have been written.

Unforutnately the given Handshakes set the RTS line but don't unset them after write.

Manually setting and unsetting RTS causes the RTS to be unset before all data have been written (although while loop until writebuffer is empty)

P.S.:

I can get it working if I run the obsolete c++ program, that was used for the same purpose, and send a command to the uC once. After that the RTS handling with the c# prog works fine. But there has to be a way to get it working directly from c#.

Regards

Matthias
# pegah said on November 8, 2006 1:12 AM:

how can i access to pin ??? i want set CTS or ...???
# Vinay said on November 8, 2006 6:32 AM:

Hi...

Your demo project is very good.

In my application i want to read text recieived on PC comport upto a string and after that i've to transmit some data on my port. So can you tell me how i can do this.

(e.g. I want to set the date & for that i have to wait until i receive text "Set Date :". )

Thanks,

Vinay
# Jack said on November 21, 2006 2:07 PM:

ClosePort() is also sending a byte '00' to receiver, how avoid it? I can't set DiscardNull=true because I am using rs232 for binary data communication.

Thanks!
# bidi said on November 27, 2006 11:04 AM:

i have a problem when i use GetPortName , i take port name for Com like this Com4, and i use the following code

--------------

foreach (string s in SerialPort.GetPortNames())

{

cmbCom.Items.Add(s);

}

------------------------

the com4 is bluetooth . is anyonethat have any ideea about this?

thks bidi
# zanis said on November 28, 2006 10:54 AM:

Hello,

I have a zebra printer connected to the com1 port, i use

the serial port class to send command to the printer but an exception is thrown on the Open method

"The given port name does not start with COM/com or does not resolve to a valid serial port"

Can someone help me please!!!
# Onur Gorgulu said on November 30, 2006 12:12 PM:

Hi friends;

In my program I am calculating a number in Int16 type between 0 and 255, and then I want to send this number to my microcontroller via serial port in 1 byte. for example 139 = 10001011. But the command comport.write(string s) only accepts string format to send. if I convert byte = 139 to string type and then send, the ascii codes of 1 3 and 9 are going separetly. I want to send the byte as a whole- the Hex equivalent of 139 in one byte. How can I do that? please explain me with useful commands. I am very newbie in this subject but I have a little time to do this project. Please response ASAP. Thanks alot for your help.

Best Regards

Onur
# seval said on December 12, 2006 12:40 PM:

if DataReceived event dos not trigger

try

port.Handshake = System.IO.Ports.Handshake.RequestToSend;

it solved my problem

good luck
# trichloramine said on December 13, 2006 1:25 AM:

My bad. It works.
# zxf92183 said on December 13, 2006 1:41 AM:

hello,

I just use the sample program from SerialPortTerminal to get data from a machine, it can received data at first time, but if the machine make a new test, and the program can't receive the data any more, after i restart the PC, the program can receive the data again. can someone help me.

thank you.
# Reddie said on December 13, 2006 5:12 PM:

I have the same problem as Matthias, some body already got a solution?
# Reddie said on December 15, 2006 4:19 AM:

@satya_chaitanya pleaze RTFM.

@Matthias on http://www.gotdotnet.com/ there is a serial port project which contains a sendI() function who direct sends a byte to the device. I've try'ed it and it works fine for our purpose.
# Sergey said on December 15, 2006 10:02 AM:

Need send to com1 command "{$04A$03$46}". If send this commant on Terminal - all work. If send command in c# - dont work. Please Help me !
# Reddie said on December 15, 2006 12:01 PM:

@Sergey: something like

byte[] b = {0x4a, 0x03, 0x46};

Serialport.Write(b,0,b.Length);

Is there a possibility to reach the Serialport handle???
# zxf92183 said on December 18, 2006 11:28 PM:

hello,

I just use the sample program from SerialPortTerminal to get data from a machine, it can received data at first time, but if the machine make a new test, and the program can't receive the data any more, after i restart the PC, the program can receive the data again. can someone help me.

thank you.
# Sergey said on December 19, 2006 1:37 AM:

May be motheboard or servise havs the "Time out" for you port or connect.
# Mark said on December 23, 2006 3:03 AM:

Thank you!! After trying to make sense of MSDN tutorials, I landed here, and let me tell you this is much better. But the SerialCom FAQ.zip can't be accesses... Can you help? Or for the others that were able to access it before, please send it to ltl_piggies@yahoo.com. Thanks much!
# tesha said on January 5, 2007 12:24 AM:

when i do "port.Open()", it says

UnauthorizedAccessException was unhandled.

Access to the port "COM1" is denied.

Make sure you have sufficient privileges to access this resource
# Muhammad Sajid said on January 10, 2007 10:55 AM:

Hi

Your Project is Excellent in every aspect

I want to use some part of ur code in my industrial project i request for a permission please !!!!!!!!!!!!!
# Ravichandran said on January 11, 2007 9:37 AM:

hi everyone,

i don't know how to connect usb port in c# 2003,

i can't able to use 2005 because my projects are already developed in 1.1 ,any can help me

thanks
# helpstudent said on January 17, 2007 8:29 AM:

does anyone know how to set StopBits to None ????

I always get a runtime error!

thanks in advance
# coad said on January 19, 2007 11:32 AM:

Ravichandran, This isn't about USB, it's about SerialPort. You can get a USB to Serial adapter:

http://www.google.com/search?hl=en&q=USB+Serial+Adapter

If you have to use .NET 1.1, you can use info from my old post:

http://www.devhood.com/tutorials/tutorial_details.aspx?tutorial_id=320
# coad said on January 19, 2007 11:34 AM:

Muhammad Sajid,

Sure! Feel free to use any code you find on my blog for any project. This goes for any and everyone here.
# coad said on January 19, 2007 12:31 PM:

Muhammad Sajid, Ravichandran, tesha, Mark, and others,

I've updated the FAQ section of the post to answer many of your questions, as well as added more support options. Hope it helps!

FAQ Section: http://msmvps.com/blogs/coad/archive/2005/03/23/39466.aspx#faq
# Noah Coad said on January 20, 2007 8:50 PM:

Onur Gorgulu,

Try: com.Write(new byte[] { (byte)(new Random().Next(0, 255)) }, 0, 1);
# Traverer said on January 23, 2007 8:52 AM:

Thanks for such resourceful material on c# serial tutorial!

I am just a beginner to c# and serial port programming, after download the SerialPortTerminal.zip and try with TC35i terminal, I discover the reason that causing "my modem not responce to my at command".

It seem to me that the comport.Write method does not send the "\r\n" I type in txtSendData textbox. Thus i add the "\r\n" string to the SendData() function as shown below and it works !!

==================================

private void SendData()

{

if (CurrentDataMode == DataMode.Text)

{

// Send the user's text straight out the port

comport.Write(txtSendData.Text + "\r\n"); //

  • Posted in Precision Designed Product