HOME - - - - - - - TUTORIALS INDEX - - - - - - - - - - - - Other material for programmers
Delicious  Bookmark this on Delicious    Recommend to StumbleUpon

Delphi: How to connect via the serial port. How to use API calls

This tutorial is a little rough around the edges, but it is far enough along that I thought you'd want what's here.

Despite its sins, it has been tested... early in April 2010, using Windows XP and Delphi 4, and everything was fine down to "...WriteString is, of course capable of sending more...". (It is probably fine past there, too... but my energy for testing ran out at that point!)


I revisited the program in the course of working with serial comms with the marvelous Arduino microprocessor. There are a number of articles about serial comms with Arduinos at my Arduino "How To" site... probably still in the "Level 4" section, but I make no promises! The best is probably the Delphi tutorial about bi-directional serial comms. That is built upon the work done in the tutorial you are currently reading. Unless you have some expertise, you might want to finish this one before attempting the more advanced tutorial. Things you can learn here will make it easier for you to understand it.

Maybe you, like me, wanted to hook a microprocessor up to your "big" computer, for instance an Arduino?

While I was doing the April 2010 testing, I created a zip file you can download with the sourcecode and even the compiled .exe which you are welcome to use.

It shows you how to send messages from one PC to another via the serial port. It does not require anything more than Delphi 2 and Win98. I think it will work with higher versions of Delphi and Windows.

For a different approach to accessing not only the COM ports, but other ports too, see my tutorial about the free DLL InpOut. For more about using the serial port, see my serial port tutorial. I also offer a page about using a COM port to communicate between microprocessors and Windows PCs. Although it is couched in Arduino terms, much of the information is applicable to other contexts. Don't forget: There are inexpensive USB devices which provide a Windows PC with a virtual COM port. (Sadly, the USB to parallel port printer devices seem less well suited to connecting things other than printers.)
At the moment, this tutorial tells you about sending data only one way, from PC "A", to PC "B". For bi-directional serial communications, you have to work harder. I would suggest that you finish the page you are reading first, as everything here is part of the bidirectional answer. I have done a further tutorial on how to accomplish bi-directional serial comms with Windows, when you are ready for it.

This will not give you an all singing, all dancing application!

What it will do, I hope, is give you a starting point, useful in its own limited way, and perhaps also useful if you want to go further.

Along the way, the tutorial illustrates the general skill of using Windows API calls directly, instead of with the help of Delphi wrappers. The latter is preferable... where possible... but the latter is an alternative you should know about.

Before you try to do anything yourself with the serial port, make sure that your hardware is working properly.

I make many references to Hyperterminal in what follows. That used to come with Windows, but doesn't now, and isn't always installed on older machines. You can use any simple serial terminal software. I've been using PuTTY, but haven't used it much yet. It is free, and runs on Windows an Linux. For what we're doing here, you only need to download putty.exe, and that's the program... not a setup package.

Connect two PCs with a null modem cable. Start Hyperterminal on each of them. Win 98: It is in Programs|Accessories|Communications.... if it has been installed. It is one of the free things which come with Windows, but it isn't always installed. To install: Settings | Control Panel | Add/Remove Programs, The Windows Setup tab.

Once your computers have Hyperterminal, start it up... Your start menu will probably have been given a link to the Hyperterminal folder. You need to double-click on "Hypertrm.exe". (The entries with .ht extensions can be deleted).

When you first start Hyperterminal, you'll probably get the New Connection Wizard. If you want your machines to be consistent with what I say in this tutorial, create a connection called DD55HTC (Delphi Demo 55, HyperTerminal Connection). It doesn't matter what you put in the phone number fields. Just "Connect Using..." one of your Com ports. Of course it has to be the right Com port. Oh goodie... the fun has started already. (I really hate serial comms).

A detour: On one of my machines, a laptop, the port has a little sticker I put on it saying it is Com5, but Hyperterminal didn't offer a Com5. Com1 gave rise to "Could not open."... and the wizard closed. File | Properties is what you need to try again. The Configure button "worked" for Com3, but that didn't seem right either. Next I right clicked "My Computer", clicked "Properties", went into Device Manager, Infra Red Devices. I said "Disable in this profile". Rebooted... At last I COULD "talk" from one computer to the other over the null modem, using Com4. Bah.

I then went to the second machine, started Hyperterminal, started a new connection. Called it DD55HTC, too. (No need for different names... but you could have them, if you wished.)

Thence to the Configure dialog for each machine's Com port. Most of the settings don't matter much in this application... but they must be the same in both machines. Try:

Bits per second: 9600
Data bits:8
Parity: None
Stop bits: 1
Flow: Hardware or none.

One more thing to do... Call | Call via the menus, or just click on the "Call" button (a little telephone). You should see "Connnected" in the status bar, window's lower left. Now, all being well (it is quite possible that it won't be!), when you type on one of the computers, what you typed will appear on the other. And vice versa. Without "local echo", you won't see what you type on the machine you are on. Get that much working!!! Good luck. Serial comms... yuck. (Did I say that?)

If you want, you can turn on a local echo... not very important to what is to follow, but if you want it: File | Properties | Settings... and there you'll find a box to tick.

When you leave Hyperterminal, you are asked "Do you want to save session?" Saying yes preserves any settings you may have made.


Shut down Hyperterminal on the machine you have Delphi on.

Start a new Delphi application. Put five buttons on it. Name them....

buOpenConnection
buSendX
buSendY
buCloseConnection
buQuit

... and make the labels the obvious things.

Name the main form DD55f1. Save the project in a folder called DD55. Call the unit DD55u1, the project DD55. Make buQuit's OnClick
application.terminate;
Before I go any further... my thanks to the good people at Borland (Inprise) for the good information that used to be at http://community.borland.com/article/0,1410,16400,00.html, from which the heart of all this came.

Use the Object Inspector to set to false the "enabled" property of buSendX, buSendY and buCloseConnection.

Declare a global variable...
    hCommFile : THandle;
... by putting the above just after the comment "{Private declarations}" in the TDD55F1 class declaration. Then, just after...
    hCommFile : THandle;    
... insert the following forward declaration....
    procedure WriteString(sToSend:string);
Then, just before the unit's terminal "end.", insert....
procedure TDD55F1.WriteString(sToSend:string);
var NumberWritten : dWord;
  {N.B.: I saw the following in a newsgroup post:
  "Warning: There is an error in the FAQ - NumberWritten must be
  dword not LongInt"}
begin
if WriteFile(hCommFile,
               PChar(sToSend)^,
               Length(sToSend),
               NumberWritten,
               nil)=false then
      showmessage('Unable to send');
end;
(We'll see what this is good for in a moment!)

Make buOpenConnection's OnClick....
procedure TDD55F1.buOpenConnectionClick(Sender: TObject);
var
  CommPort : string;
begin
  CommPort := 'COM1';
  hCommFile := CreateFile(PChar(CommPort),
                          GENERIC_WRITE,
                          0,
                          nil,
                          OPEN_EXISTING,
                          FILE_ATTRIBUTE_NORMAL,
                          0);
  if hCommFile=INVALID_HANDLE_VALUE then begin
      ShowMessage('Unable to open '+ CommPort);
      end // no ; here
      else begin
      buSendX.enabled:=true;
      buSendY.enabled:=true;
      buCloseConnection.enabled:=true;
      buOpenConnection.enabled:=false;
      end; //else
end;
Note: If when you connected via Hyperterminal, you were using a Com port other than 1, then you will need to modify the COM1 above accordingly.

Now make buSendX's OnClick....
procedure TDD55F1.buSendXClick(Sender: TObject);
begin
WriteString('X');
end;
Run the program. Click on the "Open connection" button. Click the "Send X" button. You should see an "X" appear on the other computer! You should click on the "Close Connection" button before exiting the program, though Windows may clean up after you if you fail to do so. A "proper" application would need to monitor whether the connection was open or closed, close it when the program is closed, if not closed.

Add the following for buSendY's OnClick....
procedure TDD55F1.buSendYClick(Sender: TObject);
begin
WriteString('Y');
end;
Now you can send "X" or "Y" to the other computer (Useful, when you've sent a bunch of Xs, and it is a little hard to see if another is arriving!

The procedure WriteString is, of course capable of sending more than a single byte. Set up a button called buHelloWorld, make it's OnClick...
procedure TDD55F1.buHelloWorldClick(Sender: TObject);
begin
WriteString('Hello World ');
end;
... and then you can send "Hello World" to the destination computer. Ta! Da!


You can send numbers to the other computer... but the receiving program will have to be expecting them. If Hyperterminal receives a 65, it will display the character "A". There are numbers Hyperterminal will respond badly to.

If you want "65" (i.e. the two digits 6 and 5) to appear on the destination computer, use WriteString('65'). If you want the number 65 sent to the other computer, change the line of code in buSendX's OnClick to....
WriteString(chr(65));
SendX will now send 65 to the other computer. If it is running Hyperterminal, it will display an "A". There is nothing to stop you from creating a system which will dispense 65 marbles if it is sent 65... but that's a story for another time! (Or visit my site about sensing and control.)

I have done a further tutorial on how to accomplish bi-directional serial comms with Windows, when you are ready for it.

Lastly, if you want to work through an earlier tutorial that was a "stage along the way" to what you saw above, my "Delphi Serial Comms" tutorial is still online. Looking at that might help you with something that wasn't clear above, or merely be useful to consolidate what you learned above.
            powered by FreeFind
  Site search Web search
Site Map    What's New    Search This search merely looks for the words you enter. It won't answer "Where can I download InpOut32?"

Click here if you're feeling kind! (Promotes my site via "Top100Borland")


If you visit 1&1's site from here, it helps me. They host my website, and I wouldn't put this link up for them if I wasn't happy with their service. They offer things for the beginner and the corporation.www.1and1.com icon

Ad from page's editor: Yes.. I do enjoy compiling these things for you... hope they are helpful. However.. this doesn't pay my bills!!! If you find this stuff useful, (and you run an MS-DOS or Windows pc) please visit my freeware and shareware page, download something, and circulate it for me? Links on your page to this page would also be appreciated!
Click here to visit editor's freeware, shareware page.

Link to Tutorials main page
How to email or write this page's editor, Tom Boyd


Valid HTML 4.01 Transitional Page tested for compliance with INDUSTRY (not MS-only) standards, using the free, publicly accessible validator at validator.w3.org


If this page causes a script to run, why? Because of things like Google panels, and the code for the search button. Why do I mention scripts? Be sure you know all you need to about spyware.

....... P a g e . . . E n d s .....