HOME - - - - - - - TUTORIALS INDEX - - - - - - - - - - - - Other material for programmers

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

This tutorial is pretty rough around the edges, but was far enough along that I thought you'd want what's here. I'll try to revisit it, polish it, later.

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.
At the moment, this tutorial tells you about sending data only one way, from PC "A", to PC "B". I doubt that it will be hard to make the communications bi-directional, but the details of that will have to wait until I can revisit this topic.

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.

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 there, from which the heart of all this came.

Use the Object Inspector to make buSendX, buSendY and buCloseConnection enabled.

Declare a global variable...
    hCommFile : THandle;
... by putting the above just after the word "private" in the TDD55F1 class declaration. Then, just after...
    hCommFile : THandle;    
... insert the following forward declaration....
    procedure WriteString(sToSend:string);
... and 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;
  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
  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.)
   Search this site or the web        powered by FreeFind
 
  Site search Web search
Site Map    What's New    Search


Click here if you're feeling kind! (Promotes my site via "Top100Borland")
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
Here is how you can contact this page's author, Tom Boyd.


Valid HTML 4.01 Transitional Page WILL BE 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 .....