langlois
asked on
Serial i/o using Borland C++ Builder
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
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
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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.
ASKER
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
Label8->Caption = buffer;
/////////
CloseHandle(hCom); // handle to object to close
if (!fSuccess)
Label9->Caption = "CloseHandle(): Failed";
else
Label9->Caption = "CloseHandle(): Passed";