Introduction

This article is about controlling the com port in windows. You can't just tell the computer to open the com port like you would with Pascal or C++ in DOS. But there are still some tricks that makes it possible to open and use the com port. The only thing is, you will need to know something about windows - Win2k has a HAL (Hardware Abstraction Layer).

First of all, windows 2000, windows xp and windows 2003 have protected hardware access. This is the HAL. Very useful when it comes to security, but for programmers like me it's a nightmare. I found a solution: Let windows do the job for you.

How did I make this?

I used some basic windows function for my com port controlling functionality:

CreateFile

ReadFile

WriteFile

CloseHandle

BuildCommDCB

SetCommState

You can find these functions in the old VB6 API Viewer program (Or you might take a look in the source of course).

I simply told windows to do the hardware controlling for me. I will trick my program that the com port is a file. This is made possible through the Windows API Functions I use.

The code

The first function of my code is the open function. The function will be trying to make a com port handle. After that I check if the handle is correct. If the handle is ok, I will continue by making a DCB Structure instance ready for use. With this structure we can control all comport settings. (I will only use, speed, parity, stop bits and data bits)

The next function is the Write Function. This function controls the writing to the com port. I choose to write one byte at a time to the com port since I wanted to control a microcontroller with my com port. But you can change this of course to a multi-byte write function or add an extra function for multi-byte.

At last and more important than the open function we have the Close function. This function closes the com port and releases the system handle to it. If we don't do this in NT4/win2k/xp/2003, we get big problems.

Comments and Discussions

Hello! Thanks for the nice project, but I've got a few gripes! This entire project should not used assumed objects! If we are making code public, it is much better to define our types, especially if other coders are using option explicit - it saves folks from having to cypher everything before trying it out. For example, I assume that these constants are all integers?

Also, I get a VS warning for "buffer" below, saying that the variable is used before it is assigned a value. Indeed, we are doing a ReadFile with a length of "buffer" - but it has no length defined. Would it be right to add this? : "buffer = Array.CreateInstance(GetType(Byte), 1)"

i'm trying do somthing I think should be varey simple. I don't no any code at all but simply put all I want to do is chose a key on my keyboard when it is pressed it should activate the rts pin 7 of the com port witch would light up a Optocoupler circuit like the one in the link bellow.

I do have a nice little program that will kinda do what I want. the program is a mores code program called cwtype however I want the option of also adding a sound card interface so I can use my computer for a vocal proccesor over a ham radio.

a more advanced aproch would be to set up two keys one to key the circuit on rts pin 7 and another to dtr on pin 4. this would allow a ptt key and a cw key to be used. and above and beond a key lock down that could be clicked to lock ither of the cicuits in the active ptt mode for long cw transmitions.

if anyone is interested in helping me fumble my way into this code adventure, offer advice, or write some code for me please any help would be great. and bare in mind I've never done any code except html.

i dont know if i am missing something..
i just used this code on my pocket pc in order to open the com7 port for my gps receiver..it didnt work..i even changed the DllImport("kernel32.dll") to DllImport("codedll.dll") to create the file handler and i got an exception.I must be missing something.Please help

Sorry for such a stupid question but I am new with VS 2005. Can you help me with what is needed to put this DLL into a existing application? I added a reference to the .dll and then added "Imports MeinDesign.LPT" to the .vb file. Then in my button I added the following code

'If we can't put the settings in place, we probably can't use the comport
'for our task.
If SetCommState(hPort, dcbPort) = 0 Then
Throw New Exception("kan de compoort niet openen(" & GetLastError().ToString() & ")")
End If

'Check if our comport is open
If Opened = True Then
WriteFile(hPort, dt, dt.Length, written, Nothing)
Else
Throw New Exception("Comport not opened")
End If

Hello FLAVIO,
As i was reading your post on "COM Port Made Simple with VB.NET", i wanted to know how would you go about doing the "Public Sub Read()" function? you have provided the "wirte function", i would be grateful if you can provide me with the "Read" function that helps read strings instead of raw data as soon as possible.

I try to use this lib unter .NET Compact Framework, but it does not work.
Can you provide me some clues to use COM port on PocketPC?

By the way, when I add your lib to my project and try to build it, the compiler give me an error message.
I check the MSDN and it says that the "MarshalAs" attribute can not be used in DllImport.
But when I build your project alone, it perform quietly.

I have no experience with the .NET compact framework, I can't help you in this.

Hmm, that's weird it never gave me that error, that may be because I build it separate from other projects and used only the compiled version in my test projects. If you do it like that, it should work in normal .NET applications.

I wish to open two com ports (for processing a GPS datastream from two recievers) and read from them relatively simultaneously. Is this possible with this code? If so, what kinds of alterations need to be made?

It's possible, create two instances of the RS232 class and use those in separate threads. Than you can read from two comports almost simultaneously (there's a little lag due to the multithreading, this should be veeerrrryy low.. more like nanoseconds).

You will get a so-called 0 terminator byte on the comport, when there's no more data available.
It's very easy, poll the comport until you get a zero as result on a read action. Then you have all the data the connected device send to the computer.
I used this trick to write a complete communication protocol for communication with model-train controlcenter

"Every rule in a world of bits and bytes can be bend or eventually be broken"

That's weird because I had no problems there.
You would need a more advanced comport control to be able to detect the number of bytes available on the comport. Maybe I can find a windows API call for getting the file length.

"Every rule in a world of bits and bytes can be bend or eventually be broken"