I want to access serial port by visual c++
I get the program from internet but when I run the program, it seems the port can not open
here my program serialClass.cpp
#ifndef SERIALCLASS_H_INCLUDED
#define SERIALCLASS_H_INCLUDED
#define ARDUINO_WAIT_TIME 2000
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
class Serial
{
private:
HANDLE hSerial;
bool connected;
COMSTAT status;
DWORD errors;
public:
Serial(char *portName);
//Serial();
~Serial();
int ReadData(char *buffer, unsigned int nbChar);
bool WriteData(char *buffer, unsigned int nbChar);
bool IsConnected();
};
#endif // SERIALCLASS_H_INCLUDED
and my Serial.cpp
#include "SerialClass.h"
Serial::Serial(char *portName)
//Serial::Serial()
{
//We're not yet connected
this->connected = false;
//Try to connect to the given port throuh CreateFile
this->hSerial = CreateFile((LPCWSTR) portName,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
//Check if the connection was successfull
if(this->hSerial==INVALID_HANDLE_VALUE)
{
//If not success full display an Error
if(GetLastError()==ERROR_FILE_NOT_FOUND){
printf("ERROR: Handle was not attached. Reason: COM1 not available.\n");
}
else
{
printf("ERROR!!!");
}
}
else
{
//If connected we try to set the comm parameters
DCB dcbSerialParams = {0};
//Try to get the current
if (!GetCommState(this->hSerial, &dcbSerialParams))
{
//If impossible, show an error
printf("failed to get current serial parameters!");
}
else
{
//Define serial connection parameters for the arduino board
dcbSerialParams.BaudRate=CBR_19200;
dcbSerialParams.ByteSize=8;
dcbSerialParams.StopBits=ONESTOPBIT;
dcbSerialParams.Parity=NOPARITY;
dcbSerialParams.fOutX=TRUE;
dcbSerialParams.fInX=TRUE;
//Set the parameters and check for their proper application
if(!SetCommState(hSerial, &dcbSerialParams))
{
printf("ALERT: Could not set Serial Port parameters");
}
else
{
//If everything went fine we're connected
this->connected = true;
//We wait 2s as the arduino board will be reseting
//Sleep(ARDUINO_WAIT_TIME);
printf("Current Settings\n Baud Rate %d\n Parity %d\n Byte Size %d\n Stop Bits %d", dcbSerialParams.BaudRate,
dcbSerialParams.Parity, dcbSerialParams.ByteSize, dcbSerialParams.StopBits);
}
}
}
}
Serial::~Serial()
{
//Check if we are connected before trying to disconnect
if(this->connected)
{
//We're no longer connected
this->connected = false;
//Close the serial handler
CloseHandle(this->hSerial);
}
}
int Serial::ReadData(char *buffer, unsigned int nbChar)
{
//Number of bytes we'll have read
DWORD bytesRead;
//Number of bytes we'll really ask to read
unsigned int toRead;
//Use the ClearCommError function to get status info on the Serial port
ClearCommError(this->hSerial, &this->errors, &this->status);
//Check if there is something to read
if(this->status.cbInQue>0)
{
//If there is we check if there is enough data to read the required number
//of characters, if not we'll read only the available characters to prevent
//locking of the application.
if(this->status.cbInQue>nbChar)
{
toRead = nbChar;
}
else
{
toRead = this->status.cbInQue;
}
//Try to read the require number of chars, and return the number of read bytes on success
if(ReadFile(this->hSerial, buffer, toRead, &bytesRead, NULL) && bytesRead != 0)
{
return bytesRead;
}
}
//If nothing has been read, or that an error was detected return -1
return -1;
}
bool Serial::WriteData(char *buffer, unsigned int nbChar)
{
DWORD bytesSend;
//Try to write the buffer on the Serial port
if(!WriteFile(this->hSerial, (void *)buffer, nbChar, &bytesSend, 0))
{
//In case it don't work get comm error and return false
ClearCommError(this->hSerial, &this->errors, &this->status);
return false;
}
else
return true;
}
bool Serial::IsConnected()
{
//Simply return the connection status
return this->connected;
}
The result is always
ERROR: Handle was not attached. Reason: COM1 not available.
any body can help?
The problem is with casting to a wide string instead of converting, I replaced that part of the code opening the port with the following and it worked:
wchar_t wcPort[64];
size_t convertedChars = 0;
mbstowcs_s(&convertedChars, wcPort, strlen(portName), portName, _TRUNCATE);
this->hSerial = CreateFile(wcPort,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
Or as Ben Voigt has pointed out in a comment you could also call the CreateFileA variant so that Windows performs the conversion for you.
Related
I am trying to write data to the tap adapter(a virtual network interface) through its file descriptor. I opened the file by calling the "CreateFile" API and I am able to write the data. I am writing some 100 bytes of data to the file which is sometimes taking more time to complete which I could not figure out what is causing that issue.
I am not getting any error codes and the call is getting success. The only problem is, it is taking more time to complete. I am writing the data 100 times in a loop and only some say 10 iterations "WriteFile" calls are taking more time to complete which is causing some delay in further processing of the packets.
#include <stdio.h>
#include <pcap.h>
#include <sys/types.h>
#include <ntddndis.h>
#define LINE_LEN 16
#define ETHER_MAX_LEN 65535
#ifdef WIN32
#include <tchar.h>
BOOL LoadNpcapDlls()
{
_TCHAR npcap_dir[512];
UINT len;
len = GetSystemDirectory(npcap_dir, 480);
if (!len) {
fprintf(stderr, "Error in GetSystemDirectory: %x", GetLastError());
return FALSE;
}
_tcscat_s(npcap_dir, 512, _T("\\Npcap"));
if (SetDllDirectory(npcap_dir) == 0) {
fprintf(stderr, "Error in SetDllDirectory: %x", GetLastError());
return FALSE;
}
return TRUE;
}
#endif
void physical_dispatcher_handler(u_char *, const struct pcap_pkthdr *, const u_char *);
HANDLE hTapAdapter;
pcap_t *port_a;
DWORD WINAPI DataReceiveHandlerThread(LPVOID lpParam)
{
pcap_loop(port_a, 0, physical_dispatcher_handler, NULL);
return 0;
}
#define BUFFERSIZE 65535
CRITICAL_SECTION m_cs;
int main(int argc, char **argv)
{
BOOL bErrorFlag = FALSE;
//Initilize the critical section
InitializeCriticalSection(&m_cs);
printf("\n");
/*if (argc != 2)
{
printf("Usage Error:\tIncorrect number of arguments\n\n");
_tprintf(TEXT("%s <file_name>\n"), argv[0]);
return;
}*/
hTapAdapter = CreateFile("\\\\.\\Global\\{A2AC038D-EBC1-48F9-B507-BB822AE1C393}.tap", // name of the write
GENERIC_READ | GENERIC_WRITE, // open for writing
0, // do not share
NULL, // default security
OPEN_EXISTING, // create new file only
FILE_ATTRIBUTE_NORMAL, // normal file
NULL); // no attr. template
if (hTapAdapter == INVALID_HANDLE_VALUE)
{
//DisplayError(TEXT("CreateFile"));
_tprintf(TEXT("Terminal failure: Unable to open file \"%s\" for write.\n"), argv[1]);
return;
}
DWORD threadIdentifier = 0;
HANDLE threadHandle = CreateThread(
NULL, // default security attributes
0, // use default stack size
DataReceiveHandlerThread, // thread function name
NULL, // argument to thread function
0, // use default creation flags
&threadIdentifier); // returns the thread identifier
// Check the return value for success.
// If CreateThread fails, terminate execution.
// This will automatically clean up threads and memory.
if (threadHandle == NULL)
{
//ErrorHandler(TEXT("CreateThread"));
ExitProcess(3);
}
WaitForSingleObject(threadHandle, INFINITE);
CloseHandle(threadHandle);
return;
}
void physical_dispatcher_handler(u_char *temp1,
const struct pcap_pkthdr *header,
const u_char *pkt_data)
{
u_int i = 0;
/*
* unused variable
*/
(VOID*)temp1;
DWORD dwBytesWritten = 0;
time_t my_time = time(NULL);
// ctime() used to give the present time
printf("Data received in port A - %s", ctime(&my_time));
// Lock the Critical section
EnterCriticalSection(&m_cs);
BOOL bErrorFlag = WriteFile(
hTapAdapter, // open file handle
pkt_data, // start of data to write
header->len, // number of bytes to write
&dwBytesWritten, // number of bytes that were written
NULL); // no overlapped structure
if (FALSE == bErrorFlag)
{
//DisplayError(TEXT("WriteFile"));
printf("Terminal failure: Unable to write to file.\n");
}
else
{
if (dwBytesWritten != header->len)
{
// This is an error because a synchronous write that results in
// success (WriteFile returns TRUE) should write all data as
// requested. This would not necessarily be the case for
// asynchronous writes.
printf("Error: dwBytesWritten != dwBytesToWrite\n");
}
else
{
time_t my_time = time(NULL);
// ctime() used to give the present time
printf("Data written to tap - %s", ctime(&my_time));
_tprintf(TEXT("Wrote %d bytes to successfully.\n"), dwBytesWritten);
}
}
//Release the Critical section
LeaveCriticalSection(&m_cs);
return;
}
I have a measurment device and want to make a series of measurments and store them to a file.
For this I need to read out the com port properly. All I get back with this code is some weird signs.
#include <windows.h>
#include <process.h>
#include <stdio.h>
#include <iostream>
#include <string>
using namespace std;
int main() {
// opening the serial port
HANDLE hSerial;
fprintf(stderr, "Opening serial port...");
hSerial = CreateFile("\\\\.\\COM2",
GENERIC_READ | GENERIC_WRITE, 0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hSerial == INVALID_HANDLE_VALUE) {
fprintf(stderr, "Error\n");
CloseHandle(hSerial);
return 1;
} else
fprintf(stderr, "OK\n");
// settings to communicate with device
DCB dcbSerialParams;
ZeroMemory(&dcbSerialParams, sizeof(dcbSerialParams));
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
if (!GetCommState(hSerial, &dcbSerialParams)) {
//error getting state
fprintf(stderr,"error getting state ... ");
}
dcbSerialParams.BaudRate = 9600;
dcbSerialParams.ByteSize = 8;
dcbSerialParams.StopBits = ONESTOPBIT;
dcbSerialParams.Parity = NOPARITY;
if (!SetCommState(hSerial, &dcbSerialParams)) {
//error setting state
fprintf(stderr,"error setting state ...");
}
char out_message[] = "fetch?"; // request for the device to send voltage and
current
char in_message[32];
DWORD BytesToWrite = sizeof(out_message);
DWORD BytesWritten;
DWORD BytesToRead = sizeof(in_message);
DWORD BytesRead;
WriteFile(hSerial, out_message, BytesToWrite, &BytesWritten, NULL);
ReadFile(hSerial, &in_message, BytesToRead, &BytesRead, NULL);
string buffer;
for (unsigned int i = 0; i < sizeof(in_message); i++) {
buffer += in_message[i];
}
buffer[sizeof(in_message) - 1] = '\0';
// try outs of different outputs
cout << buffer << "\n";
const char*c = buffer.c_str();
printf("%s\n",c);
CloseHandle(hSerial);
return 0;
}
I guess I cannot write to com an read out immediately?
Or is there a mistake in the conversion in_message to buffer?
I am working on a project that has a serial communication between a Windows PC and an Arduino Uno card.
In the C++ code I have a SerialClass.h and a Serial.cpp
My problem is that I get a compiler fault: identifier "SP" undefined
in the function
void Serial::SendtoArd(int val, int var)
{
if (SP->IsConnected())
{
bool writeData = false;
writeData = SP->WriteData("test",4);
}
I know if I define the SP in this function I get rid of this fault, but
I do not want to activate the Serial port in that function . I want to activate the serial port in this function
bool Serial::OpenPtoArd()
{
Serial* SP = new Serial("\\\\.\\COM3"); // adjust as needed
if (SP->IsConnected())
{
bool status = true;
}
}
and keep it active as long as my app is running.
Can anyone help me out here?
Here is the SerialClass.h
#ifndef SERIALCLASS_H_INCLUDED
#define SERIALCLASS_H_INCLUDED
#define ARDUINO_WAIT_TIME 2000
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
class Serial
{
private:
//Serial comm handler
HANDLE hSerial;
//Connection status
bool connected;
//Get various information about the connection
COMSTAT status;
//Keep track of last error
DWORD errors;
public:
//Initialize Serial communication with the given COM port
Serial(char *portName);
//Close the connection
~Serial();
//Read data in a buffer, if nbChar is greater than the
//maximum number of bytes available, it will return only the
//bytes available. The function return -1 when nothing could
//be read, the number of bytes actually read.
int ReadData(char *buffer, unsigned int nbChar);
//Writes data from a buffer through the Serial connection
//return true on success.
bool WriteData(char *buffer, unsigned int nbChar);
//Check if we are actually connected
bool IsConnected();
bool OpenPtoArd();
void SendtoArd(int val, int var);
};
Here is the Serial.cpp
#endif // SERIALCLASS_H_INCLUDED
#include "stdafx.h"
#include "SerialClass.h"
#define LEN 1
bool status = false;
Serial::Serial(char *portName)
{
//We're not yet connected
this->connected = false;
//Try to connect to the given port throuh CreateFile
this->hSerial = CreateFile(portName,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
//Check if the connection was successfull
if (this->hSerial == INVALID_HANDLE_VALUE)
{
//If not success full display an Error
if (GetLastError() == ERROR_FILE_NOT_FOUND) {
//Print Error if neccessary
printf("ERROR: Handle was not attached. Reason: %s not available.\n", portName);
}
else
{
printf("ERROR!!!");
}
}
else
{
//If connected we try to set the comm parameters
DCB dcbSerialParams = { 0 };
//Try to get the current
if (!GetCommState(this->hSerial, &dcbSerialParams))
{
//If impossible, show an error
printf("failed to get current serial parameters!");
}
else
{
//Define serial connection parameters for the arduino board
dcbSerialParams.BaudRate = CBR_9600;
dcbSerialParams.ByteSize = 8;
dcbSerialParams.StopBits = ONESTOPBIT;
dcbSerialParams.Parity = NOPARITY;
//Set the parameters and check for their proper application
if (!SetCommState(hSerial, &dcbSerialParams))
{
printf("ALERT: Could not set Serial Port parameters");
}
else
{
//If everything went fine we're connected
this->connected = true;
//We wait 2s as the arduino board will be reseting
Sleep(ARDUINO_WAIT_TIME);
}
}
}
}
Serial::~Serial()
{
//Check if we are connected before trying to disconnect
if (this->connected)
{
//We're no longer connected
this->connected = false;
//Close the serial handler
CloseHandle(this->hSerial);
}
}
int Serial::ReadData(char *buffer, unsigned int nbChar)
{
//Number of bytes we'll have read
DWORD bytesRead;
//Number of bytes we'll really ask to read
unsigned int toRead;
//Use the ClearCommError function to get status info on the Serial port
ClearCommError(this->hSerial, &this->errors, &this->status);
//Check if there is something to read
if (this->status.cbInQue>0)
{
//If there is we check if there is enough data to read the required number
//of characters, if not we'll read only the available characters to prevent
//locking of the application.
if (this->status.cbInQue>nbChar)
{
toRead = nbChar;
}
else
{
toRead = this->status.cbInQue;
}
//Try to read the require number of chars, and return the number of read bytes on success
if (ReadFile(this->hSerial, buffer, toRead, &bytesRead, NULL) && bytesRead != 0)
{
return bytesRead;
}
}
//If nothing has been read, or that an error was detected return -1
return -1;
}
bool Serial::WriteData(char *buffer, unsigned int nbChar)
{
DWORD bytesSend;
//Try to write the buffer on the Serial port
if (!WriteFile(this->hSerial, (void *)buffer, nbChar, &bytesSend, 0))
{
//In case it don't work get comm error and return false
ClearCommError(this->hSerial, &this->errors, &this->status);
return false;
}
else
return true;
}
bool Serial::IsConnected()
{
//Simply return the connection status
return this->connected;
}
void readme()
{
Serial serial("COM3");
char c[LEN + 1];
int numBytes = 0;
while (true)
{
numBytes = serial.ReadData(c, LEN);
if (numBytes != -1)
{
// Terminate the string if we want to use c variable as a string
c[numBytes] = 0;
break;
}
}
}
bool Serial::OpenPtoArd()
{
Serial* SP = new Serial("\\\\.\\COM3"); // adjust as needed
if (SP->IsConnected())
{
bool status = true;
}
}
void Serial::SendtoArd(int val, int var)
{
if (SP->IsConnected())
{
bool writeData = false;
writeData = SP->WriteData("test",4);
}
}
The problem with this code
bool Serial::OpenPtoArd()
{
Serial* SP = new Serial("\\\\.\\COM3"); // adjust as needed
if (SP->IsConnected())
{
bool status = true;
}
}
is that you are creating the new Serial - and then losing the pointer to that Serial when the function exits. If you want other functions to be able to access it, you need the SP variable to be outside the OpenPtoArd() function.
You can (should?) either make it a member of your class (which by the way will clash with Arduino's Serial class - call it something else!), or make it a global variable: put the following line near the top of the file:
YourSerialClass *SP = NULL;
Note that I set the variable to NULL. Your other code needs to know whether the SP port has been created yet or not - and to not use it if it hasn't been:
if ((SP!=NULL) && (SP->IsConnected()) {
... do SP things
} // if
I've been trying to communicate with Arduino through its serial port and with the C++ code below.
The only thing is: it is always returning an invalid_handle_value.
I've looked everywhere, and all people are using kind of the same code... except it's working for them.
P.S: Arduino is on COM15. This code worked with port COM4 (Bluetooth).
The code
#include "SerialClass.h"
Serial::Serial(char *portName)
{
//We're not yet connected
this->connected = false;
//Try to connect to the given port throuh CreateFile
this->hSerial = CreateFile(portName,
/*GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);*/
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
0);
//Check if the connection was successful.
if (this->hSerial==INVALID_HANDLE_VALUE)
{
//If not success full display an Error.
if (GetLastError()==ERROR_FILE_NOT_FOUND){
//Print Error if neccessary
printf("ERROR: Handle was not attached. Reason: %s not available.\n", portName);
}
else
{
printf("ERROR!!!");
}
}
else
{
//If connected we try to set the comm parameters
DCB dcbSerialParams = {0};
//Try to get the current
if (!GetCommState(this->hSerial, &dcbSerialParams))
{
//If impossible, show an error
printf("failed to get current serial parameters!");
}
else
{
//Define serial connection parameters for the arduino board
dcbSerialParams.BaudRate=CBR_9600;
dcbSerialParams.ByteSize=8;
dcbSerialParams.StopBits=ONESTOPBIT;
dcbSerialParams.Parity=NOPARITY;
//Set the parameters and check for their proper application
if (!SetCommState(hSerial, &dcbSerialParams))
{
printf("ALERT: Could not set Serial Port parameters");
}
else
{
//If everything went fine we're connected
this->connected = true;
//We wait 2s as the arduino board will be reseting
Sleep(ARDUINO_WAIT_TIME);
}
}
}
}
Serial::~Serial()
{
//Check if we are connected before trying to disconnect
if (this->connected)
{
//We're no longer connected
this->connected = false;
//Close the serial handler
CloseHandle(this->hSerial);
}
}
int Serial::ReadData(char *buffer, unsigned int nbChar)
{
//Number of bytes we'll have read
DWORD bytesRead;
//Number of bytes we'll really ask to read
unsigned int toRead;
//Use the ClearCommError function to get status info on the Serial port
ClearCommError(this->hSerial, &this->errors, &this->status);
//Check if there is something to read
if (this->status.cbInQue>0)
{
//If there is we check if there is enough data to read the required number
//of characters, if not we'll read only the available characters to prevent
//locking of the application.
if (this->status.cbInQue>nbChar)
{
toRead = nbChar;
}
else
{
toRead = this->status.cbInQue;
}
//Try to read the require number of chars, and return the number of read bytes on success
if (ReadFile(this->hSerial, buffer, toRead, &bytesRead, NULL) && bytesRead != 0)
{
return bytesRead;
}
}
//If nothing has been read, or that an error was detected return -1
return -1;
}
bool Serial::WriteData(char *buffer, unsigned int nbChar)
{
DWORD bytesSend;
//Try to write the buffer on the Serial port
if (!WriteFile(this->hSerial, (void *)buffer, nbChar, &bytesSend, 0))
{
//In case it don't work get comm error and return false
ClearCommError(this->hSerial, &this->errors, &this->status);
return false;
}
else
return true;
}
bool Serial::IsConnected()
{
//Simply return the connection status
return this->connected;
}
int main() {
Serial serial("COM15");
if (serial.IsConnected()){
serial.WriteData("1",1);
printf("\nData sent successfully!\n");
}
system("pause");
return 0;
}
Try using a filename of "\\\\.\\COM15" (see http://support.microsoft.com/kb/115831).
When I connect my embedded device to my system, I am running my program which will write to the port my embedded is connect and it prints the reply to console.
When I connect my device and run this program it is not giving any output.
But when I connect my device and use PUTTY to send some commands first and then run my program it is working.
Maybe there is a problem in the way I am starting communication?
My source code is:
#include "stdafx.h"
#include <iostream>
//#include <windows.h>
#include <afx.h>
int main()
{
using namespace std;
int i=0;
// cout << "Hello world!" << endl;
HANDLE hSerial;
hSerial = CreateFile("COM5",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_WRITE | FILE_SHARE_READ,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
if(hSerial==INVALID_HANDLE_VALUE)
{
if(GetLastError()==ERROR_FILE_NOT_FOUND)
{
// TRACE("serial port does not exist for reading\n");
//serial port does not exist. Inform user.
}
// TRACE("some other error,serial port does not exist for reading\n");
//some other error occurred. Inform user.
}
DCB dcbSerialParams = {0};
dcbSerialParams.DCBlength=sizeof(dcbSerialParams);
if (!GetCommState(hSerial, &dcbSerialParams))
{
// TRACE("error getting state for reading\n");
//error getting state
}
dcbSerialParams.BaudRate=9600;
dcbSerialParams.ByteSize=8;
dcbSerialParams.StopBits=ONESTOPBIT;
dcbSerialParams.Parity=NOPARITY;
if(!SetCommState(hSerial, &dcbSerialParams))
{
//TRACE("error setting state for reading\n");
//error setting serial port state
}
COMMTIMEOUTS timeouts={0};
timeouts.ReadIntervalTimeout=50;
timeouts.ReadTotalTimeoutConstant=50;
timeouts.ReadTotalTimeoutMultiplier=10;
timeouts.WriteTotalTimeoutConstant=50;
timeouts.WriteTotalTimeoutMultiplier=10;
if(!SetCommTimeouts(hSerial, &timeouts))
{
// TRACE("some error occured for reading\n");
//error occureed. Inform user
}
int n=100,n1=100;
char szBuff[100];
DWORD dwBytesRead = 0;
char szBuff1[100];
DWORD dwByteswrote = 0;
memset(szBuff1,0,100);
memcpy(szBuff1,"LIST\r",5);
if(!WriteFile(hSerial, szBuff1,5, &dwByteswrote, NULL))
{
cout << "error writing" ;
}
cout << szBuff1 << endl;
cout << dwByteswrote << endl;
while(1)
{
if(!ReadFile(hSerial, szBuff, n1, &dwBytesRead, NULL))
{
cout << "error reading";
break;
}
else
{
cout << dwBytesRead << endl;
szBuff[dwBytesRead]='\0';
if(dwBytesRead>0)
{
cout << (szBuff);
break;
}
}
}
cin >> i;
}
Try this... you will probably need to do the code for exceptions (ex: if the response is bigger than 2024)
bool SendModemATCommand(const string &strCommand, int iModemPort, string &strRetValue)
{
bool bRetValue = false;
strRetValue = "";
char cBuffer[2024];
HANDLE hCom = NULL;
char cComPort[64];
sprintf_s(cComPort,"\\\\.\\COM%d", iModemPort);
hCom = CreateFile( cComPort,
GENERIC_READ | GENERIC_WRITE,
0, // must be opened with exclusive-access
NULL, // no security attributes
OPEN_EXISTING, // must use OPEN_EXISTING
0, // not overlapped I/O
NULL // hTemplate must be NULL for comm devices
);
if (hCom != INVALID_HANDLE_VALUE)
{
COMMTIMEOUTS comTimeOuts;
comTimeOuts.ReadIntervalTimeout = MAXDWORD;
comTimeOuts.ReadTotalTimeoutMultiplier = MAXDWORD;
comTimeOuts.ReadTotalTimeoutConstant = 0;//MAXDWORD;
comTimeOuts.WriteTotalTimeoutMultiplier = 0;
comTimeOuts.WriteTotalTimeoutConstant = 0;
if(SetCommTimeouts(hCom, &comTimeOuts))
{
DCB dcb;
dcb.DCBlength = sizeof(DCB);
if(GetCommState(hCom, &dcb))
{
DWORD dwBytesWritten = 0;
DWORD dwBytesRead = 0;
DWORD dwBytesTotal = 0;
if( WriteFile(hCom, strCommand.c_str(), (int)strCommand.size(), &dwBytesWritten, NULL) )
{
if(dwBytesWritten == strCommand.size())
{
dwBytesRead = 0;
DWORD tickStart = GetTickCount();
bool bTimeOut = false;
while(true)
{
while(ReadFile(hCom, cBuffer + dwBytesTotal, 1, &dwBytesRead, NULL))
{
if(dwBytesRead == 0 && dwBytesTotal != dwBytesWritten)
break;
dwBytesTotal += dwBytesRead;
}
if ( dwBytesTotal == 0 )
{
// timeout
if ( GetTickCount() - tickStart > 10000) // 10 Seconds
{
bTimeOut = true;
break;
}
}
else
break;
}
cBuffer[dwBytesTotal] = '\0';
strRetValue = cBuffer;
if(bTimeOut)
strRetValue = "Timed out:" + strCommand;
else
bRetValue = true;
}
}
}
}
CloseHandle(hCom);
}
return bRetValue;
}
Most likely the problem is with your initialization.
I recall having this type of trouble before and Com Timeouts structure was particularly troublesome.
I suggest you get a null modem cable from COM5 to another port on the machine (if you have one), or to another computer. Then use a terminal program to open up the other port and see you can see the "List" command coming through when you run the program. If not then it's very likely to be related to the way you are initializing & opening the com port.
This link may prove useful. Just strip out the Afx stuff and look particularly at the initialization.
http://www.codeproject.com/KB/system/chaiyasit_t.aspx
One other suggestion, you only send List once. If the device is not already plugged in and ready, nothing will happen. Maybe it should keep sending the list command until it gets a
Response.
Also, do you need "List\r\n" or just "List\r"? What is the other ends expecting?