Solved

Serial i/o using Borland C++ Builder

Posted on 1997-06-22
3
2,008 Views
Last Modified: 2008-03-17
I'm trying to write a simple serial instrument controller using Builder.

There doesn't appear to be a specific object for the serial port. I need to select a port, set the parameters (speed, parity, etc.) and then read & write control records. I'll need to log and act on the read data continuously while the user accesses other menus too. Surely a common enough requirement? But since I'm new to Windows and Builder programming, I'd appreciate a fairly detailed answer...

Many thanks in advance.

John
0
Comment
Question by:langlois
[X]
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
  • 2
3 Comments
 
LVL 4

Accepted Solution

by:
md041797 earned 100 total points
ID: 1164035
Use the CreateFile API to get r/w access to your port:

HANDLE port = CreateFile ("\\\\.\\COM1", GENERIC_READ |
  GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL);

Then use ReadFile / WriteFile to r/w.  The system buffers the io so you don't have to worry about multi-threading.

Use BuildCommDCB() to set the port (similar to MODE command).

Use SetupComm() to make the port sane.

If you need more help, just tell me where you are having problems.


0
 

Author Comment

by:langlois
ID: 1164036
Okay MD,

I've at least established communication which is encouraging. But I'm not exactly able to set up my instrument controller yet. When I do a ReadFile(), I get to hang and wait until the requested number of chars have arrived. Makes it kinda hard to handle variable length records which may not even arrive! So how do I read data _if_ it's there but return regardless? For the record, here's the relevant snip from my kludgy test code as it stands:

DCB            dcb;
HANDLE      hCom;
DWORD      dwNumberOfBytesWritten, dwNumberOfBytesRead;
BOOL      fSuccess;
char      buffer[1024];

//////////
hCom = CreateFile("\\\\.\\COM2",
    GENERIC_READ | GENERIC_WRITE,
    0,                                  // comm devices must be opened w/exclusive-access
    NULL,                               // no security attrs
    OPEN_EXISTING,                  // comm devices must use OPEN_EXISTING
    FILE_ATTRIBUTE_NORMAL,      // not overlapped I/O
    NULL                                // hTemplate must be NULL for comm devices
    );

if (hCom == INVALID_HANDLE_VALUE)
      Label1->Caption = "CreateFile(): Failed";
else
      Label1->Caption = "CreateFile(): Passed";

///////////
fSuccess = SetupComm(
    hCom,      // handle of communications device
    1024,      // size of input buffer
    1024      // size of output buffer
   );      

if (!fSuccess)
      Label2->Caption = "SetupComm(): Failed";
else
      Label2->Caption = "SetupComm(): Passed";

///////////
fSuccess = GetCommState(hCom, &dcb);

if (!fSuccess)
      Label3->Caption = "GetCommState(): Failed";
else
      Label3->Caption = "GetCommState(): Passed";

//////////
fSuccess = BuildCommDCB(
    "baud=9600 parity=N data=8 stop=1",      // pointer to device-control string
    &dcb                                                // pointer to device-control block
   );      
 
if (!fSuccess)
      Label4->Caption = "BuildCommDCB(): Failed";
else
      Label4->Caption = "BuildCommDCB(): Passed";

///////////
fSuccess = SetCommState(hCom, &dcb);

if (!fSuccess)
      Label5->Caption = "SetCommState(): Failed";
else
      Label5->Caption = "SetCommState(): Passed";

//////////
fSuccess = WriteFile(
    hCom,                                    // handle to file to write to
    "echo fred\r",                        // pointer to data to write to file
    10,                                          // number of bytes to write
    &dwNumberOfBytesWritten,      // pointer to number of bytes written
    NULL                                     // pointer to structure needed for overlapped I/O
   );      

if (!fSuccess)
      Label6->Caption = "WriteFile(): Failed";
else
      Label6->Caption = "WriteFile(): Passed";

//////////
fSuccess = ReadFile(
    hCom,                              // handle of file to read
    buffer,                              // address of buffer that receives data
    16,                                    // number of bytes to read
    &dwNumberOfBytesRead,      // address of number of bytes read
    NULL                               // address of structure for data
   );      

if (!fSuccess)
      Label7->Caption = "ReadFile(): Failed";
else
      Label7->Caption = "ReadFile(): Passed";

buffer[dwNumberOfBytesRead]='\0';
Label8->Caption = buffer;

/////////
CloseHandle(hCom);                         // handle to object to close

if (!fSuccess)
      Label9->Caption = "CloseHandle(): Failed";
else
      Label9->Caption = "CloseHandle(): Passed";

0
 
LVL 4

Expert Comment

by:md041797
ID: 1164037
Use the overlapped feature.  This will read as many chars as have arrived, return immediately, and it will report the count.  You can then assemble your records in a queue and pull them out when they are complete.
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone 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

Suggested Solutions

Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

735 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