My problem is that I have try and check with different port_name like 7 or 14 or 25. It's not opening or process the serial data the handle simply matching with the if condition and it is closing the handle. Is there any problem with the code?
void command_handler::start()
{
char port_name[] = "COM7:"; /* Name of the serial port */
serial_port = CreateFile(port_name, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
/* Make sure port was opened */
if (serial_port == INVALID_HANDLE_VALUE)
{
fprintf(stderr, "Error opening port\n");
printf("I'm here");
CloseHandle(serial_port);
exit(0);
}
set_up_serial_port(serial_port, baud_rate);
process_serial_data = false;
}
Did you tried below naming:
char port_name[] = "\\\\.\\COM7";
The second issue maybe is difference of CHAR and WCHAR. I think you should send a WCHAR string to the API.
Related
(Edit: I didn't exclude any code except the headers and the main() function's brackets. Nothing is written between lines of code listed here.)
.
I used the ReadFile function to read this COM3 port (which returned no INVALID_HANDLE_VALUE or ERROR_FILE_NOT_FOUND):
LPCTSTR portName = "COM3" ;
HANDLE hSerial;
hSerial = CreateFile(portName,
GENERIC_READ | GENERIC_WRITE,
0, // exclusive access
NULL, // default security attributes
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL);
And the ReadFile function in question uses following parameters:
DWORD n = 512 ;
char szBuff[n] = {0};
DWORD dwBytesRead = 0;
if(!ReadFile(hSerial, szBuff, n, &dwBytesRead, NULL))
{
cout << "ReadFile error. Error code: " << GetLastError() << endl ;
cin.get() ;
return 0 ;
}
What changes should I introduce to cause the read to succeed?
(I searched through the function's documentation and other StackOverflow questions, tested lots of things, but couldn't find an answer.)
In ReadFile documentation you can read:
lpOverlapped [in, out, optional]
A pointer to an OVERLAPPED structure is required if the hFile parameter was opened with FILE_FLAG_OVERLAPPED, otherwise it can be NULL.
so since you specified FILE_FLAG_OVERLAPPED in CreateFile you should provide OVERLAPPED in ReadFile.
In CreateFile you can read on parameters for Communications Resources:
... and the handle can be opened for overlapped I/O.
so you can skip FILE_FLAG_OVERLAPPED in CreateFile
Marcin Jędrzejewski's answer is correct about the mismatch between the overlapped IO Flag and the ReadFile function, but I will leave this up just to be helpful.
You are missing a lot of initialisation which may be helpful to you when operating a COM port.
This code is used to open, configure, and read from a COM port on windows using C++.
FOR REFERENCE
READ_BUFFER_SIZE = 1024;
WRITE_BUFFER_SIZE = 1024;
COM_READ_BUFFER_SIZE = 1024;
COM_WRITE_BUFFER_SIZE = 1024;
READ_TIMEOUT = 50;
WRITE_TIMEOUT = 100;
port = "\\.\COM6"
portFormat = "9600,N,8,1" /* for information on this, google the MODE command for windows. */
HANDLE hComPort;
DCB dcbComConfig;
OPENING COM PORT
DWORD dwStoredFlags = EV_BREAK | EV_ERR | EV_RXCHAR;
COMMTIMEOUTS timeouts;
FillMemory(&dcbComConfig, sizeof(dcbComConfig), 0);
dcbComConfig.DCBlength = sizeof(dcbComConfig);
/* assign a COM format to the COM Port. */
if(!BuildCommDCB(portFormat, &dcbComConfig))
{
printf("Failed to build comm format data %s\n", portFormat);
}
/* Open the COM port with overlapped IO. */
hComPort = CreateFile(port, GENERIC_READ | GENERIC_WRITE, 0, 0,
OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
if (hComPort == INVALID_HANDLE_VALUE)
{
printf("Error opening port %s\n", port);
}
/* Set the COM Ports internal Read and Write buffer sizes. */
if(!SetupComm(hComPort, COM_READ_BUFFER_SIZE, COM_WRITE_BUFFER_SIZE))
{
printf("Could not set COM buffers\n");
}
/* assign the previously created COM Format to the COM Port. */
if(!SetCommState(hComPort, &dcbComConfig))
{
printf("Error setting com to format data.\n");
}
/* Mask what events you want to look for in the COM Port. */
if (!SetCommMask(hComPort, dwStoredFlags))
{
printf("Error setting communications mask\n");
}
/*-- Read Timeouts set like this so we can use the event based reading. --*/
timeouts.ReadIntervalTimeout = MAXDWORD;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.ReadTotalTimeoutConstant = 0;
timeouts.WriteTotalTimeoutMultiplier = 10;
timeouts.WriteTotalTimeoutConstant = 100;
if (!SetCommTimeouts(hComPort, &timeouts))
{
printf("Error setting time-outs.\n");
}
READING COM PORT
DWORD dwRead = 0;
DWORD dwComEvent = EV_RXCHAR;
DWORD lpErrors = 0;
char readBuffer[READ_BUFFER_SIZE];
/* Create the Overlapped IO Read Event. */
OVERLAPPED osRead = {0};
osRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
/* Used to monitor the COM Port State. */
COMSTAT ComStatus;
/* Loop at 20Hz to read the COM Port until a Kill event has been set. */
while(WaitForSingleObject(hKillEvent, 50) == WAIT_TIMEOUT)
{
/* Wait for a COM Event to occur ( Read Event in this Case ). */
if (WaitCommEvent(hComPort, &dwComEvent , NULL))
{
/* If the COM Port had an error Clear it. */
ClearCommError(hComPort, &lpErrors, &ComStatus);
/*-- Reset read operation's OVERLAPPED structure's hEvent --*/
ResetEvent(osRead.hEvent);
if (ReadFile(hComPort, readBuffer, ComStatus.cbInQue, &dwRead, &osRead))
{
/*-- bytes have been read; process it --*/
USE_DATA(readBuffer, dwRead);
}
else
{
/*-- An error occurred in the ReadFile call --*/
printf("ReadFile encountered an error.\n");
break;
}
}
else
{
/*-- Error in WaitCommEvent --*/
printf("WaitCommEvent encountered an error.\n");
break;
}
}
/* Close the Overlapped IO Read Event. */
CloseHandle(osRead.hEvent);
The top answer is correct. In this case, opening with FILE_FLAG_OVERLAPPED, ReadFile expects an OVERLAPPED structure as last argument.
Would like to add that you can also get 'parameter is incorrect' error if you do supply an OVERLAPPED struct, but forget to ZeroMemory it.
From the documentation:
Any unused members of this structure should always be initialized to zero before the structure is used in a function call. Otherwise, the function may fail and return ERROR_INVALID_PARAMETER.
So don't forget to:
OVERLAPPED ovl;
ZeroMemory(&ovl, sizeof(ovl));
...
ReadFile(hSerial, szBuff, n, &dwBytesRead, &ovl);
I have the following code as part of another module that sends messages to the client. This was for IPC. Two dll's are loaded by the exe and these two need to communicate
In DLL-1 I have the following line of code as the server named pipe.
pipe = CreateNamedPipe("\\\\.\\pipe\\S2D8",PIPE_ACCESS_OUTBOUND | FILE_FLAG_OVERLAPPED /**1-way, send only with overlapped IO*/,
PIPE_TYPE_MESSAGE,1,0,0, 0, NULL);
if( INVALID_HANDLE_VALUE != pipe )
{
log("Created Named Pipe as Serverl\n");
}
else
{
log("Cannot create Named Pipe as Server\n");
}
And somewhere else in the DLL-1 I have the following for the server
bool result = ConnectNamedPipe(pipe, NULL);
if (!result)
{
CloseHandle(pipe); // close the pipe
}
else
{
DWORD numWritten;
WriteFile(pipe,KeyBoardBuffer,strlen(KeyBoardBuffer) * sizeof(char),&numWritten,0);
log("Bytes writtern to pipe:%d\n",numWritten);
}
When I look at the logs, I can see the that named pipe. Good so far.
While in DLL-2 I have the following as the client part
log("Connecting to named pipe at client\n");
if(pipe2 == NULL || pipe2 == INVALID_HANDLE_VALUE)
{
pipe2 = CreateFile("\\\\.\\pipe\\S2D8", GENERIC_READ ,
FILE_SHARE_READ | FILE_SHARE_WRITE,NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,NULL);
if (pipe2 == INVALID_HANDLE_VALUE)
{
log("Cannot connect to named pipe at client%x\n", GetLastError());
CloseHandle(pipe2);
}
else
{
log("Connected to named pipe at client! Going to read!!!\n");
char buffer[256] = {'\0'};
DWORD numBytesRead = 0;
BOOL result = ReadFile(
pipe2,
buffer, // the data from the pipe will be put here
sizeof(buffer) * sizeof(char), // number of bytes allocated
&numBytesRead, // this will store number of bytes actually read
NULL // not using overlapped IO
);
if (result)
{
kbBuffer[numBytesRead / sizeof(char)] = '\0'; // null terminate the string
log( "Number of bytes read: %d\n",numBytesRead);
log(kbBuffer );
}
else
{
log("Failed to read data from the pipe.\n");
}
}
}
And in my logs, I can see the line "Connecting to named pipe at client" and then "Connected to named pipe at client! Going to read!!!", after that there is nothing in the log, everything seems stuck.
Is the naming convention of pipe correct? Or is there any security settings I have to define?
I am using VS2010, Win7 x64.
Any guidance is much appreciated.
You're calling the wrong method. The pipe is supposed to pre-exist, so you should be calling OpenFile(), not CreateFile().
Ah, I found the answer to the hang, I had to do a PeekNamedPipe(pipe2, NULL, 0, NULL, &bytesAvailable, NULL); and then check for the bytesAvailable to be greater than zero before I did a ReadFile()
I am using a Windows 8.1 Pro machine. OK and I am trying to open a COM port connection of my serial device. My code is as follows:
#include<stdio.h>
#include<windows.h>
int main(void)
{
HANDLE hcomm;
char *comPort = "COM6";
hcomm = CreateFile(comPort, GENERIC_READ | GENERIC_WRITE, 0, 0,
OPEN_EXISTING, 0, NULL);
if(hcomm = INVALID_HANDLE_VALUE)
{
printf("Connection Failed...\n");
}
else
printf("Connection Succeded....\n");
//return hcomm;
}
}
But this code didn't work for me. Please give some suggestion where I am getting it wrong.
Check the value of GetLastError(). GetLastError() == 0 is success.
Also your if condition is re-initializing hcomm to an invalid handle. Note the change from assignment to comparison operator in the if condition. Please change your code to below and see if it resolves your problem:
if(hcomm == INVALID_HANDLE_VALUE) {
printf("Handle creation failed with error %d", GetLastError());
}
else {
printf("Handle creation successful");
}
I'm having problems with opening a serial port in C++ on Windows 7. I'd like to send serial data from my computer to another one through a USB cable. The code I've found from various online sources is as follows:
#include <windows.h>
#include <stdio.h>
int main()
{
// Define the five bytes to send ("hello")
char bytes_to_send[5];
bytes_to_send[0] = 104;
bytes_to_send[1] = 101;
bytes_to_send[2] = 108;
bytes_to_send[3] = 108;
bytes_to_send[4] = 111;
// Declare variables and structures
HANDLE hSerial;
DCB dcbSerialParams = {0};
COMMTIMEOUTS timeouts = {0};
// Open the highest available serial port number
fprintf(stderr, "Opening serial port...");
hSerial = CreateFile(
"COM8", GENERIC_READ|GENERIC_WRITE, 0, 0,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 );
if (hSerial == INVALID_HANDLE_VALUE)
{
fprintf(stderr, "Error\n");
printf ("CreateFile failed with error %d.\n", GetLastError());
return 1;
}
else fprintf(stderr, "OK\n");
The programme never gets past this point, and the error which it throws is "Error 2". From what I've read I think this corresponds to "System cannot find the file specified". However it won't open for whatever COM port I try to use. I've also tried "\\.\COM8" but to no avail. Does anyone know some common problems that could be causing this issue? Are there any hardware specific issues to look out for?
I am writing an activex control that will access the parallel port and write the bytes to it. I am able to open the port succesfully but when i write it hangs at WriteFile function. Did i miss anything here? I am using Windows 7
HANDLE portHwd = CreateFile( _T("\\\\.\\LPT1" ),
GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL);
if (portHwd)
{
char outBuffer[] = _T("This is a test\r\n");
int sz_buffer = strlen(outBuffer);
DWORD bytes_written;
if (!WriteFile( portHwd,
outBuffer,
sz_buffer ,
&bytes_written,
NULL))
{
CloseHandle(portHwd);
GetLastError();
return 1;
}
CloseHandle(portHwd);
}
If the port's output buffer is full then WriteFile will hang until there is room to complete your request. Is there something attached to the port and reading from it?