Visual Studio Serial Port Example

Serial port communication in Visual Studio C#. Ask Question Asked 6 years ago. See MSDN example if you want to try something is supposed to work. Be sure that the serial port is not alerady open by another program and you have selected the good COM PORT. Otherwise the code looks good. I have to write a program in Visual C 2010 to communicate via Serial Port (RS232) in Windows 7 32 bit. Can Someone help me to find correct example?

12 Nov 2016CPOL

Introduction

Serial Communication between PCs is always seen as the starting point. My first piece of serial comms code was a University assignment getting two PC’s, then three, then… you get the idea talking on (what I now know to be) an RS422 with its pair of cables using Borland's Turbo C++ for DOS. Time passed I graduated (somehow!) and I got to be a Design Engineer in the ‘real’ world. Not looking busy enough got me lumbered with the famous “Glenn you aren’t that busy, have a look at this”. The ‘this’ was taking on a project that had been half done and then the guilty party ran. So to make it work the way it was wanted, out came the software (VB6) and there goes any social life I had.

Please Note: If you try to run the executable on a machine with no comms port in the Device Manager it will crash, I will when I have chance correct this!, to get around this please ensure a Communication Port available in Device Manager.

  1. Arduino & Visual Studio - Serial Communication: The reason for this project is to show you, how to manage Serial connections in Visual Studio 2015 with VisualBasic as the main programming language.A few days ago, I copyed a project from VisualBasic 2010 to Visual Studio inside a VisualBasic pro.
  2. Apr 06, 2012  This is a sample example to read data from the serial port and display on the Windows Forms TextBox control. Using the code. To begin, let's create a C# Windows Forms application in Visual Studio 2008 (hope it will work in VS 2005/2010 also, though not tested by myself). Add a textbox, a button control and a SerialPort control on to the form.

Background

RS-232 is the best know method of PC Communications, the characteristics of RS232 is a logic 1 (true) is can range from -3v to -25v a logic 0 (false) +3v to +25v. The area of -3v to 0 to +3v is taken as not valid to allow for noise and interference on the line. If the port is idle the port is at high level (or -12v), which is why if you look at circuit diagrams of peripherals there is always to a lot of invertors. RS-485 detailed at the end, RS-422 & RS-449 and on to allow very long cable runs and high speeds all follow the same basic path.

VB6 used MSComm32.ocx; this was a 32 bit version of MSComm16.ocx both of these components worked fairly well. I say fairly as the interrupt handler of the control CommEvents never worked as quickly or as well as I was expecting it to. I found the only sure fire way was to poll it with a loop or timer (and possibly lock the system, bless DoEvents!) another point worth noting was the limit of 16 Serial Ports (I have used 9 on a test rig using MSComm and was getting a bit worried in case there was another set of devices!) Thankfully the Net Serial Class lifted it 255. This all changed with the release of .NET1 serial comms were over looked (for reasons that were not clear, I presume it was something to do with security). This gave two ways around it this gave the option of using Dos to create and print to a (virtual) device or import the OCX (this was in the height of .NET-COM war). I did do a program for communicating to a high definition video screen using MScomm in Borland C++ Builder (I got it working in the end Cliff! Ha!!) this led to a large executable so not suitable for most applications. Once .NET 2.0 was released I gave a sigh of relief as this came with a serial port class native to the frame work. I started to use C# as well as VB then dropped VB6 all together.

Serial Ports have now adopted (and in some cases dropped) the 9 way D-type, though I have come across older kit (notably high precision colorimeter cameras from Samsung) use the older 25 D-type.

A common test to see if a cable or port is correct is to use a Terminal Emulator and short pins 2 & 3 to see if you get keyboard presses for characters.

Using the code

Setting Up

Being a hardware guy primarily (I have a selection of burns and scars that cause US immigration fun every time!) I learnt C and Assembly. I didn’t do any of this Windows malarkey until I got to the real world so forgive any stumbles I might make. An important step is to open device manager, You can find this this extremely useful tool buried in Windows Ten in the Windows Administraitive Tools, Select Computer Managment, This pops up the Computer Management Window shown below:

Select the Device manager option shown below:

This Will open the Device manager shown below:

As can be see on this image the PC I am typing this update on only has one virtual comm port. As always a red cross or yellow triangle mean somethings up with the install of the hardware.

Before you can use the software methods below it's always best to have a comm port installed. I looked at updating the software the with a try catch to prevent it exploding when run on a system with out comm ports this while stopping the software from virtually exploding in too small pieces can lead to confusion (thank you Dell!). So my two pennys worth is this is a better than a piece of software thats sits there and will do nothing.

I always treat the using section like I would the #include section of a C program.

System.IO.Ports is the class to use with out resulting to low level hacking. This covers all the serial ports that appear on the machine.

This will create an object called ComPort. This will create a serial port object with the following parameters as default 9600bps, no parity, one stop bit and no flow control.

Shown below is the form:

I have created a standard Windows Forms Application via File menu. To this I have added the button (name Ports) and a Rich Text Box.

The button I have called btnGetSerialPorts and the Rich Text Box I have called rtbIncomingData (the name will become apparent later).

I tend to use the rich text box as it is more flexible than the ordinary text box. Its uses for sorting and aligning text are considerably more than the straight textbox. Adobe acrobat pro 9 serial.

To the button's click routine I have added the following code:

This shows all the devices that appear as com ports, a mistake to make is thinking that a device if plugged into the USB will appear as a COM Port. For instance, Com5 and Com6 are in my phone and below is shown the Device Manager screen with the Ports COM and LPT option expanded:

Devices will appear here there manufactures (RIM, Intel etc.).

COM1 if your machine happens to have one, these days in Net books, Laptops other machines that are transportable the COM1 as a 9way D –type male is getting less common once there was a Com 1 and some times a Com2 fitted (My first Pentium, Windows 95 had two!). As can be seen the ports are not in sequential order these can be ordered. I tend to use Combo Boxes for loading the data into (I think it looks more professional and harder for users to get wrong) and sorting as below:

If you notice the changes that have been made to the click routine a standard Combo Box now accepts the array rather than the Rich Text Box, also the Array.Sort(ArrayComPortsNames).

Sort to get first COM port into the combo box (I have called Ports) these changes now give the below:

The baud rate is the amount of possible events that can happen in a second. It is displays usually as a number of bit per second, the possible number that can be used are 300, 600, 1200, 2400, 9600, 14400, 19200, 38400, 57600, and 115200 (these come from the UAR 8250 chip is used, if a 16650 the additional rates of 230400, 460800 and 921600) .

These are supported by the <st1:place w:st='on'><st1:placename w:st='on'>Serial <st1:placetype w:st='on'>Port class and come from the teletype machines of old. Non-standard baud rates are a no-no however if you can find it MHComm32.ocx from a company called Elltech did provide a means of creating ‘custom’ baud rates.

I used it in a application once to give a rate of 9550 when the third party board wouldn’t take 9600 without some errors occurring. The standard baud rate for connections is 9600 (the default for the serial port class) the lower baud rates 600 & 300 are for connecting to embedded processors & microcontrollers. Sometimes to limit board complexity and size (and of course cost!) the device has to act as the UART (Universal Asynchronous Receiver & Transmitter). The UART chip handles the bulk of the serial communications for instance the 16550 used in PCs has eight pins for data and various pins for status and control the average embedded system does not have the available pins to control this chip. So to get around this fact the processor is programmed to emulate a UART as the processor could well be busy with other tasks and serial comms is a low priority the slower baud rates were came to be used. Below is the code for the application’s Baud Rate called cboBaudRate.

When the button is clicked will give all of the baud rates in the combo box with 300 the lowest in the text of the box.

The next box is the number of Data bits, these represent the total number of transitions of the data transmission (or Tx line) 8 is the standard ( 8 is useful for reading certain embedded application as it gives two nibbles (4 bit sequences).

The inclusion of 7 bits tends to be used in some RS485 where the extra bit is used for a global message. With the above mods the form represents.

The next several commands require a bit more explanation in my opinion. They are the Stop bit, Parity and Handshaking.

The Handshaking property is used when a full set of connections are used (such as the grey 9 way D-types that litter my desk). It was used originally to ensure both ends lined up with each other and the data was sent and received properly. A common handshake was required between both sender and receiver. Below is the code for the combo box:

I think now would be a suitable time to give a bit more detail on what each property does and how it works. RS-232 is intended to be a standard, but as is the way “rules are for the abeyance of fools and the guidance of the wise”. The transmission of data requires the Handshaking property to be set to one of the settings above. To allow this to work the CTS clear to send (pin 8 of the 9-way), RTS request (ready) to send (pin 7 of the 9 way) which is directly controllable from software, DTR data terminal ready (pin 4 of the 9-way) again this is directly controllable from software and DSR data set ready is similar to the CTS pin but is activate by other end of the connection.

Handshaking can be none (which is the most common these days) the handshaking was originally used when the speeds were lower and it would cost more time to resend the data, it is used also if a large amount of data is to be sent to ensure it has been correctly received. Detailed above are the available settings from the serial port class. The diagram below shows how to connect up two 9 way D-types for full duplex communication.

If the Handshake property is set to None the DTR and RTS pins are then freed up for the common use of Power, the PC on which this is being typed gives +10.99 volts on the DTR pin & +10.99 volts again on the RTS pin if set to true. If set to false it gives -9.95 volts on the DTR, -9.94 volts on the RTS. These values are between +3 to +25 and -3 to -25 volts this give a dead zone to allow for noise immunity.

This switching can be achieved by using the below:

If the true property is replaced with false the switch over of the voltages can be seen.

These values were measured on the PC being used to write this article using a mulitmeter set to volts mode and Pin 5 of the 9 way as ground. I found when I was learning software communications too much time was spent explaining the theory not enough was doing. The program below shows some modifications to the code I am developing here, four labels called: lblBreakStatus, lblCTSStatus, lblDTRStatus, and lblRIStatus.

lblCTSStatus and lblDTRStatus show the states of the CTS line (which in the above diagram is connected to RTS line) and DTR line (connected to the DTR line in full duplex comms).

A button called btnTest is created and the click routine is as follows (this code is included in the listing and example project but commented out uncomment to use!):

I always, as a habit, prevent the user from clicking on the open button again which will cause an exception (generally I change the text and check which it is Open / Closed…) . The RS232 connection has a wire from the DTR or RTS pin and makes contact with the pins (shorting them) it causes the labels back grounds to change like so:

This gives a quick demo of how the pins work. Below is the code:

To get this functionality the following lines should be added below the SerialPort declaration:

This will create the objects needed the line below should be added to the form declaration below InitializeComponents();:

This declares the delegate PinChanged. In the button click:

Add:

And attach the delegate as so

This now causes the program when either DTR or RTS is connected to the pins to change the labels back colour. I have found it easiest to run this program with a female socket of the end of a 9 way cable. A piece of wire can then be stroked over the pin solder buckets (casing the labels to change colour from Green to Red and back), this will give some feeling that you achieving something. It should be noted at this point the PC will try to open the default serial port which is default is 9600 Baud, No Parity, One Stop bit and No flow control, the number is decided by the lowest number serial available Com1 if fitted.

To get the simplest means of comms between two units the below is used:

All this does is connect Pin 2 of one RS-232 port to Pin 3 of another, and the Pin 2 to Pin 3 of the other end, while this is all that is needed a connection between the shield grounds is recommended to prevent errors.

The simplest of all connections is below:

Pins 2 and 3 are directly connected (tip: the pin spacing on a standard 9-way D type is just right to all a jumper from the back of an old CD-Rom to be used!)

This type of connection is used often to see if the program receives and sends data.

To get the demo codes to do this add a button to the form called PortState and add the code below:

The code once the button is clicked changes the text of the button to “Open” and then sets the various attributes of the com port individually, I set all my Com ports in this way as it saves staring at the code trying to work out was is happening.

A very good practice to get into is to use the IsOpen property to check to see if the port can be opened. The main use for this I have found is with USB com ports which can be added and removed at will (and not always placed back in the same socket) an example of this is below:

Hp 5940 printer. Easy Driver Pro makes getting the Official HP Deskjet 5940 Printers Drivers For Windows 10 a snap. Easy Driver Pro will scan your computer for missing, corrupt, and outdated Drivers. Easy Driver Pro will scan your computer for missing, corrupt, and outdated Drivers. I follow the standard Windows built-in device driver installation for my printer (HP DeskJet 5940 throught USB), but Windows doesn't have any available driver for such printer. As stated here (https. HP DeskJet 5940 USB not recognized by Windows 10 64 bit ‎ 02:10 AM.

This if will check the COM port to see if it is open, the not operator is to check if it is closed another useful trick is to use a try…catch as below:

This will cause the software to produce a message when a fault is found and not blow up in the users face! Also another thing the Serial Port Class provides is the Timeout Property, to prevent the software sitting waiting in a loop you can do the below:

The above sets a time limit on actions to the serial port by default these are set to infinity but can be set. I have used the Read time out with some radio boards to check they are still in range (if the command to get the serial number of board X times out X is not in range).

To received data there are two methods, interrupt using the DataRecieved Event and polling with a timer (not recommend) but using a stop watch timer from the tool box with a interval property of 1000 or 1 second (see below for code)…

To start the timer use the line:

to stop it use:

Generally this method while it works for a single serial port that does not change quickly it works, however I have been bitten by this with a test rig someone (I think I know who!!) altered the values in the software of the intervals to make it run quicker and it went very badly wrong (who got the blame!) as the timer component in can be over taken and ignored by Windows.

These are both valid methods however the DataReceived event is acted upon an interrupt basis using a delegate. To get this function to work add the below:

The code creates a delegate SetTextCallback and an empty string called InputData.

Next the event handler is added to the code

The SetText which is called by the SetTextCallback.

A button is created on the form called Hello, the click routine is shown below

With the above button we can send the famous (or infamous!) message Hello World.

This is done with use of the .Write() function it can write a byte array, a character array or subarray or a string. A relation of this is the WriteLine() which will send a string and a new line (or n to C programmers) and the WriteByte which sends a Byte out. These methods are ‘blocking’ in that while they are sending they cannot receive.

The reading method is ReadExisting() method this will read text out of the receive buffer until it is empty. This method does not block the port until it gets some data or a timeout is expired.

As above related commands are Read(), ReadByte(), ReadChar(), ReadLine(), and ReadTo(). Often I have found that devices tend to reply with text (some can have the rn or carriage return & line feed settings altered) of all of them I have found ReadExisting() and ReadLine() the most use. ReadTo() can be used if checking for a specific character such as “n” in incoming data the problem with this is if the data is large some times the character can be included by accident such as the “n”, I have used the ReadExisting() method for talking to devices that I know will only send a fixed amount and the ReadLine() for a situation where the data is quite large as it will read up to a new line (discarding the new line) as follows:

Placed in the interrupt handler for the port.

Below is the application as it stands:

This achieved by clicking the Ports button to fill the combo boxes and then Open button to open the port chosen with the combo boxes the speed of 300 is slow enough to see the message get caught between read cycles of the port.

The next thing to try once you have the above working is to add another rich text box called rtbOutgoing add the below code to project:

Once a rich text box and the code above is added the KeyPress event must be ‘wired’ to it by clicking the Event selection (looks like a thunder bolt) going to the KeyPress event and clicking the down arrow and selecting the rtbOutgoing_KeyPress this will attach the event.

This will then allow for typing in the outgoing text box to be picked up by the short between pins 2 & 3 from earlier. This will allow text to be sent as a key pressed just like Hyperterminal (no longer comes on Vista up, guessing Microsoft though it wasn’t needed…). Hyperterminal for many years was seen as the basis for most serial comms and many devices are expecting Hyperterminal style commands. I can’t say this is the proper way of doing this, however it’s ugly but it does work, for this example the text is loaded into a text box called txtCommand.

All this does in reality is to take the text in txtCommand (this could be “RZ04” for example), Length an integer is set to the length of the string, a for loop then counts from 0 to Length each time CommandSent is equal to the substring of Command1 at j for one character.

If this is added to the application as a button a textbox names txtCommand the form resembles the below:

This example uses the interrupt to handle the data separate from the write, for some applications I have found that this is not really affective. I have found that a method of having one function that you can call and send the data and then it remains in the function while waiting for a response can be useful in debugging hardware (to cure the is that Windows or the hardware frown!).

By use of the enum Reply integer, Reply can have three possible values a No, a Yes, and a Timeout. The NO_REPLY is for waiting for a reply the timer will stop it waiting for infinity. The YES_REPLY is the device at the end has seen the data and has

Acknowledge it, the TIMEOUT_REPLY is for the event when the timer expirers and there has been no reply.

Below is an example of a Write / Read routine I wrote and used in some Automatic Test Equipment (hence ATE being used!)

This also an example of when and how to use ReadTo() in it I use ReadTo(“rn”); or read to the carriage return, line feed the device from memory used to spit out “n” for a reason (which I can’t think of at the moment!) and the only way of getting a reliable message was to use “rn”. Time and shipping meant the error section was not used as the unit would return Exx, xx being 00 to 99, E99 for instance was “Command not recognized” there were other codes but these were not required.

The timer code is below:

The Data received handler is below:

This approach should only be used when and if the unit ends commands with a set string (like this unit did “rn”) and the program is not required to ‘do’ any thing else, or some of the data expected is being lost i.e. “Hello World!!” becomes “llo World!”.

This method should be called with the following:

This will send “Hello World!” out of Com 1, this method was originally developed for an Automatic Test Equipment that was being difficult (to use a polite word!) in that some of the devices sent data at a high rate others sent data a low rate and the interrupt method could be called and possibly block the port before it was done sending the command (hence the Enum array and there being no reading done in the interrupt handler).

I have focused on R-232 in the examples; however this should be equally applicable to other serial networks such as the RS-422 and RS-485.

RS-485 does not come as a standard on the PC a third party device such as those by the company Amplicon (http://www.amplicon.com/), the settings are dictated by the devices connected together on the bus the PC listens in via the device attached to the comm. port, to open the port follow the products data sheet and open the port. The commands and formatting of them should all be detailed in the documentation.

Below is a full version of the code:

Points of Interest

Visual Basic Serial Port Connection

I did find a lack of information about emulating HyperTerminal so I came up with my own version which appears to work as I said it's not pretty but.. For further clarification of anything detailed here the book Serial Port Complete (Second Edition) by Jan Axelson (LVR). Also my first submission to CodeProject, so be nice!

History

  • 0.1 First primordial upload for submission
  • 1.0 Added some details as to why the App will crash.
In this article, we are going to connect an Arduino Pro Mini to a PC and communicate with it using a C# Windows application.

Connecting your hardware to a PC can be very beneficial, not least because you can send commands and monitor status. You can also debug your code in real-time. Checking the variables is particularly beneficial when you are struggling with a module and you want to know the module responses and track your state machine.

A Note on the Arduino Pro Mini and C#

First of all, I want to describe my reasons for choosing the Arduino Pro Mini. In my opinion, the small form factor is an advantage in today’s designs. Nowadays, with the increasing popularity of portable IoT devices, the need to be small is getting more important—and Arduino Pro Mini is nothing if not very small.

The Arduino Pro Mini is optimized for small spaces (when you need your circuit as small as possible), but it's surprisingly robust when it comes to building projects. Another benefit is it doesn’t have soldered headers, which take up a lot of vertical space. You can simply access the desired pin by soldering the wire to the pin. Because of its small size, it doesn’t have built-in USB components, so you'll need to use an extra component for that functionality. There are many serial-to-USB converters on the market but, personally, I prefer to choose a converter that gives me all the handshake pins, not just Rx and a Tx.

That’s why I designed a simple interface board based on the FT232R. I used all of the serial signals available on the chip. You can see the circuit that I took from the datasheet in Figure 1.

Secondly, I'd like to address why I chose C#. There are numerous programming languages and many visual programs that make programming a visual application for Windows much simpler. Every one of them has advantages and disadvantages. But, for me, using visual studio can do a lot of my work for me. It gives access to many pre-compiled libraries and tools that help us build our application efficiently. It also allows us to work in the C# language, which is very powerful. So we are using C# in this article because it's convenient and I'm familiar with it.

Figure 1. FT232R datasheet. Image courtesy of FTDI Chip (PDF)

BOM

Hardware

  • A breadboard for LED
  • Wire for connecting the headers to the FT232R board and pin 3 to an LED

Software

Setup

I used my own FT232R board for programming and communicating with the Arduino Pro Mini 5V. Arduino PM has six pin headers for programming labeled “BLK”, “GND”, “VCC”, “RXI”, “TXO”, and “GRN” as can be seen in Figure 2.

Figure 2. The pins for the Arduino Pro Mini. Image courtesy of SparkFun.
Figure 3. The Arduino Pro Mini schematic. Image courtesy of Arduino. Click to enlarge.

In the six pin headers for programming shown in Figure 3, the first pin, BLK, is grounded. GND and VCC obviously need to get connected to VCC and GND of the FT232R board. In this way, the Arduino will be supplied with USB power and won't need an extra supply.

The thing that we should consider is the current limitation of a USB port. If our circuit draws more than 500mA, we should add an external power supply. RXI should get connected to TX of FT232, TXO to RX of FT232, and GRN to the DTR of FT232—which will give the FT232 the power to reset the board whenever it wants.

After wiring, your circuit should look like Figure 4. Now we're ready to program the Arduino Pro Mini.

Figure 4. Setup

Uploading a Sketch

Visual Studio Serial Port Example Free

For test purposes, we'll write a simple code to read serial inputs and set the pin 3 status accordingly:


All we need to do is set our board to Arduino Pro or Pro Mini (see Figure 5) and then upload our sketch.

Figure 5. Arduino IDE

Writing the C# Application

For writing the C# application we should create a simple windows form in Visual Studio. Next, from the toolbox section, we need to drag and drop the “Serial port” tool. All the settings can be configured in the properties section of the tool. Set the port name to the port name of your FT232. And set the Baud Rate to 115200. The handshake setting is 'None.' We also need to add a button to toggle LED status and a textbox to show received data. We can simply add these from the toolbox. The settings should be as shown in Figure 6.

Figure 6. The main form and the serial port configurations

After doing the visual work, we are ready to do some coding. First of all, for using the serial port we need to open it, and then we can write or read from the serial buffer. We have access to serial interrupts in the code. Interrupts in serial communication provide better response because we handle data as it becomes available. The C# serial port also has an event that will be triggered when data comes to the buffer. We can use this event by going to the events tab in the properties section and double-clicking on DataReceived (see Figure 7). Visual studio will create the event automatically.

Figure 7. We will use the DataReceived interrupt

Before we send or receive data, we need to open the serial port:


And then we can read or write data.

The code will look like this:

Vb Serial Port Example


Code description

The sample code communicates via ASCII characters. This approach is convenient and extensible.

In the C# code, we need to read the status of the pin from the Arduino Pro Mini so that we send the “STATE” command to the Arduino board. The Arduino will answer us through the serial port with the answer of “state=0” or “state=1”. After the Arduino sends us the state, we will update the button text accordingly.

Events run in separate threads from the main form thread, so they have different speeds. For example, in our case, when we receive a text from the serial port, we may want to show it in the text box. However, the main Windows thread controller which created all control handlers from the beginning, may have some undone job with the desired controller, which can be a richtextbox or a button; under these conditions, if we call a text box from another thread separated from the main handler, the program will crash because of a multiple-thread situation. The textbox controller can have two different properties at a time, so we should wait until its job is done.

That’s why we can’t change textbox text from another thread, such as the serial receive thread. To avoid that, we can use an Invoke method. Each controller has an Invoke method that gives us the ability to change its properties from another thread; an Invoke method can execute a certain delegate from another thread. Delegates are like method pointers in C++, which means that they refer to a certain method and execute it safely. Therefore, at first, we need to define a delegate that changes the controller properties, which in the code is named “myDelegate,” and then refer it to the Invoke method. As can be seen in the code, with the use of an Invoke function, we can make thread-safe calls.

The rest of the code is straightforward. We simply write the “ON” or “OFF” command to the serial port whenever the user pushes the button.

Conclusion

In this article, we learned how to write a C# program that interacts with an Arduino Pro Mini. We used a simple ASCII command/response protocol that can be easily adapted for use in a wide variety of applications.