Reading and Writing to a com port

Posted on 2003-10-22
Last Modified: 2010-04-05
I have a good component that deals with com port data that I found on this website

Trouble is something has happened to my machine that has stopped this component working,

Can anyone suggest a better com port component or a fix that will suggest why this component keeps triggering recieving data?


I am using Delphi 7 and windows 2000.
Question by:ofdan
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
LVL 17

Accepted Solution

Wim ten Brink earned 34 total points
ID: 9599333
LVL 11

Assisted Solution

robert_marquardt earned 33 total points
ID: 9599646
Do not forget to take hardware errors into account.

Assisted Solution

gmayo earned 33 total points
ID: 9600113
Or just write your own:

unit TBall;

// Purpose: Handles trackerball interface via a comm port




procedure TBallDone;
procedure TBallInit(comportid : string);
procedure TBallTenMSTimer;



      CommPort : THandle;                  // Handle for the comm port
      Byte1, Byte2, Byte3 : byte;      // Most recently received bytes
      ByteCount : integer;            // Number of bytes received

Purpose:        Closes the communications port
Inputs:         None
Returns:        Nothing
Preconditions:  None
Postconditions: Comm port closed if open
Actions:        If the handle is non-zero, then close the handle and zero the handle.
procedure TBallDone;
      if CommPort <> 0 then begin
            CommPort := 0;

Purpose:        Initialises the communications port
Inputs:         comportid - Identity (e.g. COM2: ) of the communications port
Returns:        Nothing
Preconditions:  None
Postconditions: Comm port opened or error shown
Actions:        Open the comm port. If an error occurs then show the error. Otherwise, initialise
                the port to the appropriate speed etc.
procedure TBallInit(comportid : string);
      dcb : TDCB;
      t : TCommTimeouts;
      if CommPort <> 0 then TBallDone;
      CommPort := CreateFile(PChar(comportid), GENERIC_READ or GENERIC_WRITE, 0, nil, OPEN_EXISTING, 0, 0);
      if CommPort <> 0 then begin
            SetupComm(CommPort, 256, 256);

            dcb.DCBlength := SizeOf(dcb);
            GetCommState(CommPort, dcb);

            dcb.BaudRate := CBR_1200;
            dcb.Parity := NOPARITY;
            dcb.ByteSize := 8;
            dcb.StopBits := ONESTOPBIT;
            SetCommState(CommPort, dcb);

            t.ReadIntervalTimeout := MAXDWORD;
            t.ReadTotalTimeoutConstant := 0;
            t.ReadTotalTimeoutMultiplier := 0;
            t.WriteTotalTimeoutMultiplier := 0;
            t.WriteTotalTimeoutConstant := 0;
            SetCommTimeouts(CommPort, t);
      end else begin
            ShowMessage('Failed to open hardware port ' + comportid + ' for trackerball. Hardware will not be available in this session.');

Purpose:        Checks the port for activity
Inputs:         None
Returns:        Nothing
Preconditions:  Comm port opened
Postconditions: Mouse cursor moved if necessary
Actions:        Read any bytes from the comm port if open. If any are received, process them. Three
                bytes are received per movement, although not necessarily at the same time. Certain
                bit patterns in the 3 bytes denote the X and Y distance, and whether the byte is the
                first of the 3 (ie to synchronise with a triplet).
procedure TBallTenMSTimer;
      procedure ProcessMouse;
            {lb, rb : boolean;}
            xm, ym, xdiff : integer;
            xc, yc : shortint;
            p : TPoint;
            {lb := (Byte1 and 32) = 32;      // Not used at present
            rb := (Byte1 and 16) = 16;}
            xc := ((Byte1 and 3) shl 6) + (Byte2 and 63);
            yc := ((Byte1 and 12) shl 4) + (Byte3 and 63);
            xm := p.X + xc div 1;
            ym := p.Y - yc div 1;
            if MouseScreenBoundary then DisplayForm.MouseMoveTest(xm, ym, xdiff);
            SetCursorPos(xm, ym);
      buf : byte;
      numread : cardinal;
      if CommPort <> 0 then begin
            numread := 1;
            while (ReadFile(CommPort, buf, 1, numread, nil) = true) and (numread = 1) do begin
                  if (buf and 64) = 64 then begin
                        bytecount := 0;
                        Byte1 := buf;
                  end else if bytecount = 0 then begin
                        bytecount := 1;
                        Byte2 := buf;
                  end else if bytecount = 1 then begin
                        bytecount := 2;
                        Byte3 := buf;

Geoff M.

Author Comment

ID: 9622388
I have now tried writing my own com port component and finding different components.

It usually is infomation is sent to the comport and nothing is recieve or

courrupt data is recieved, which would suggest that there is something wrong with the hardware as it did work.

Thed reason I think it is not hardware is I can manually execute commands in HyperTerminal and everything performs as it should.

What does hyper terminal do that standard com component don't?

Expert Comment

ID: 9622526
It sounds like the buffer you are providing is wrong. Make sure the buffer you pass is in the correct format - see my example above (and below):

     buf : byte;
     numread : cardinal;
    ReadFile(CommPort, buf, 1, numread, nil)

Note that it is buf and not @buf like many Win32 APIs. Don't forget to check the length of data received (which may be 0 depending on how SetCommTimeouts has been set).

Note also that the first time you read from COM ports you DO get one or two rubbish characters. It shouldn't be a problem after that unless you physically unplug and plug in the serial cable, in which case you get more electrical noise and rubbish characters.

Geoff M.

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
This is my first video review of Microsoft Bookings, I will be doing a part two with a bit more information, but wanted to get this out to you folks.
In this video you will find out how to export Office 365 mailboxes using the built in eDiscovery tool. Bear in mind that although this method might be useful in some cases, using PST files as Office 365 backup is troublesome in a long run (more on t…
Suggested Courses
Course of the Month9 days, 15 hours left to enroll

624 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question