I'm coding in visual studio. i have a problem in ConfigureSerialPort function.

#include <windows.h>
#include <stdio.h>
#include <string.h>

HANDLE hPort;

BOOL WriteByte(BYTE bybyte)
{
    DWORD iBytesWritten=0;
    DWORD iBytesToRead = 1;
    if(WriteFile(hPort,(LPCVOID) 
        &bybyte,iBytesToRead,&iBytesWritten,NULL)==0)
        return FALSE;
    else return TRUE;
}

BOOL WriteString(const void *instring, int length)
{
    int index;
    BYTE *inbyte = (BYTE *) instring;
    for(index = 0; index< length; ++index)
    {
        if (WriteByte(inbyte[index]) == FALSE)
            return FALSE;
    }
    return TRUE;
}

BOOL ReadByte(BYTE  &resp)
{
    BOOL bReturn = TRUE;
    BYTE rx;
    DWORD dwBytesTransferred=0;

    if (ReadFile (hPort, &rx, 1, &dwBytesTransferred, 0)> 0)
    {
        if (dwBytesTransferred == 1)
        {
            resp=rx;
            bReturn  = TRUE;
        }
        else bReturn = FALSE;
    }
    else    bReturn = FALSE;
    return bReturn;
}

BOOL ReadString(void *outstring, int *length)
{
    BYTE data;
    BYTE dataout[4096]={0};
    int index = 0;
    while(ReadByte(data)== TRUE)
    {
        dataout[index++] = data;
    }
    memcpy(outstring, dataout, index);
    *length = index;
    return TRUE;
}

void ClosePort()
{
    CloseHandle(hPort);
    return;
}

HANDLE ConfigureSerialPort(LPCSTR  lpszPortName)
{
    HANDLE hComm = NULL;
    DWORD dwError;
    DCB PortDCB;
    COMMTIMEOUTS CommTimeouts;
    // Open the serial port.
    hComm = CreateFile (lpszPortName, // Pointer to the name of the port
        GENERIC_READ | GENERIC_WRITE,
        // Access (read-write) mode
        0,              // Share mode
        NULL,           // Pointer to the security attribute
        OPEN_EXISTING,  // How to open the serial port
        0,              // Port attributes
        NULL);          // Handle to port with attribute to copy
    // Initialize the DCBlength member.
    PortDCB.DCBlength = sizeof (DCB);
    // Get the default port setting information.
    GetCommState (hComm, &PortDCB);
    // Change the DCB structure settings.
    PortDCB.BaudRate = 9600;              // Current baud
    PortDCB.fBinary = TRUE;               // Binary mode; no EOF check
    PortDCB.fParity = TRUE;               // Enable parity checking
    PortDCB.fOutxCtsFlow = FALSE;         // No CTS output flow control
    PortDCB.fOutxDsrFlow = FALSE;         // No DSR output flow control
    PortDCB.fDtrControl = DTR_CONTROL_ENABLE; // DTR flow control type
    PortDCB.fDsrSensitivity = FALSE;      // DSR sensitivity
    PortDCB.fTXContinueOnXoff = TRUE;     // XOFF continues Tx
    PortDCB.fOutX = FALSE;                // No XON/XOFF out flow control
    PortDCB.fInX = FALSE;                 // No XON/XOFF in flow control
    PortDCB.fErrorChar = FALSE;           // Disable error replacement
    PortDCB.fNull = FALSE;                // Disable null stripping
    PortDCB.fRtsControl = RTS_CONTROL_ENABLE; // RTS flow control
    PortDCB.fAbortOnError = FALSE;        // Do not abort reads/writes on error
    PortDCB.ByteSize = 8;                 // Number of bits/byte, 4-8
    PortDCB.Parity = NOPARITY;            // 0-4=no,odd,even,mark,space
    PortDCB.StopBits = ONESTOPBIT;        // 0,1,2 = 1, 1.5, 2

    // Configure the port according to the specifications of the DCB structure.
    if (!SetCommState (hComm, &PortDCB))
    {
        printf("Could not configure serial port\n");
        return NULL;
    }
    // Retrieve the time-out parameters for all read and write operations
    // on the port.
    GetCommTimeouts (hComm, &CommTimeouts);
    // Change the COMMTIMEOUTS structure settings.
    CommTimeouts.ReadIntervalTimeout = MAXDWORD;
    CommTimeouts.ReadTotalTimeoutMultiplier = 0;
    CommTimeouts.ReadTotalTimeoutConstant = 0;
    CommTimeouts.WriteTotalTimeoutMultiplier = 0;
    CommTimeouts.WriteTotalTimeoutConstant = 0;
    if (!SetCommTimeouts (hComm, &CommTimeouts))
    {
        printf("Could not set timeouts\n");
        return NULL;
    }
    return hComm;
}

int main(void)
{
    //  Can also use COM2, COM3 or COM4 here
    hPort = ConfigureSerialPort("COM1");
    if(hPort == NULL)
    {
        printf("Com port configuration failed\n");
        return -1;
    }
    // Call your ReadString and WriteString functions here
    ClosePort();
    return 0;
}

i have a problem in ConfigureSerialPort function.

What is the problem? Have you compiled for debug and single-stepped through the function to find out where it goes wrong? Or is there a compiler error?

 // Can also use COM2, COM3 or COM4 here
hPort = ConfigureSerialPort("COM1");
if(hPort == NULL)
{
printf("Com port configuration failed\n");
return -1;
}

I'm assuming your problem is due to using a non existent COM port. In this case, COM1 does not exist.

Thus, one possible solution would be to enumerate all existing COM ports. A basic example follows...

#include <windows.h>
#include <stdio.h>

int main(void)
{
 char ComPort[255];
    for (UINT i = 1; i < 255; i++)
    {
        memset(ComPort, 0, sizeof ComPort);
        sprintf(ComPort,"\\\\.\\COM%d",i);
        bool bSuccess = false;
        HANDLE hPort = CreateFile(ComPort, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
        if (hPort == INVALID_HANDLE_VALUE)
        {
            DWORD dwError = GetLastError();
            //Check to see if the error was because some other app had the port open
            if (dwError == ERROR_ACCESS_DENIED)
                bSuccess = TRUE;
        }
        else
        {
            //The port was opened successfully
            bSuccess = TRUE;
            //Close the port, since it will not be used
            CloseHandle(hPort);
        }
        if (bSuccess)
            printf("%s is available\n", ComPort);
    }
    return 0;
}

When i compiled for debug your basic example, it went wrong:
error C2664: 'CreateFileW' : cannot convert parameter 1 from 'char [255]' to 'LPCWSTR'

you are trying to compile the program for UNICODE, which is the default for Visual Studio compilers. Either got to Project--> Properties-->ConfigurationProperties --> General, then on the right paine change CharacterSet to "Not Set", which disables UNICODE. Or convert the code to use UNICODE strings.

Thank you.
But I have the problem, when I send file without the received Com, it still send and exit, so i'm not received file

#include <windows.h>
#include <conio.h>
#include <string.h>
#include <iostream>
#include <string>
using namespace std;
HANDLE hPort;
BOOL WriteByte(BYTE bybyte)
    {
        DWORD iBytesWritten=0;
        DWORD iBytesToRead = 1;
        if(WriteFile(hPort,(LPCVOID) &bybyte,iBytesToRead,&iBytesWritten,NULL)==0)
            return FALSE;
        else 
            return TRUE;
    }
BOOL ReadByte(BYTE  &resp)
{
    BOOL bReturn = TRUE;
    BYTE rx;
    DWORD dwBytesTransferred=0;
    if (ReadFile (hPort, &rx, 1, &dwBytesTransferred, 0)> 0)
    {
        if (dwBytesTransferred == 1)
        {
            resp=rx;
            bReturn  = TRUE;
        }
        else bReturn = FALSE;
    }
    else    bReturn = FALSE;
    return bReturn;
}
HANDLE ConfigureSerialPort(LPCSTR  lpszPortName)
    {
        HANDLE hComm = NULL;
        //DWORD dwError;
        DCB PortDCB;
        COMMTIMEOUTS CommTimeouts;
    // Open the serial port.
        hComm = CreateFile (lpszPortName, // Pointer to the name of the port
                            GENERIC_READ | GENERIC_WRITE,// Access (read-write) mode
                            0,              // Share mode
                            NULL,           // Pointer to the security attribute
                            OPEN_EXISTING,  // How to open the serial port
                            0,              // Port attributes
                            NULL);          // Handle to port with attribute to copy
    // Initialize the DCBlength member.
        PortDCB.DCBlength = sizeof (DCB);
    // Get the default port setting information.
        GetCommState (hComm, &PortDCB);
    // Change the DCB structure settings.
        PortDCB.BaudRate = 9600;              // Current baud
        PortDCB.fBinary = TRUE;               // Binary mode; no EOF check
        PortDCB.fParity = TRUE;               // Enable parity checking
        PortDCB.fOutxCtsFlow = FALSE;         // No CTS output flow control
        PortDCB.fOutxDsrFlow = FALSE;         // No DSR output flow control
        PortDCB.fDtrControl = DTR_CONTROL_ENABLE; // DTR flow control type
        PortDCB.fDsrSensitivity = FALSE;      // DSR sensitivity
        PortDCB.fTXContinueOnXoff = TRUE;     // XOFF continues Tx
        PortDCB.fOutX = FALSE;                // No XON/XOFF out flow control
        PortDCB.fInX = FALSE;                 // No XON/XOFF in flow control
        PortDCB.fErrorChar = FALSE;           // Disable error replacement
        PortDCB.fNull = FALSE;                // Disable null stripping
        PortDCB.fRtsControl = RTS_CONTROL_ENABLE; // RTS flow control
        PortDCB.fAbortOnError = FALSE;        // Do not abort reads/writes on error
        PortDCB.ByteSize = 8;                 // Number of bits/byte, 4-8
        PortDCB.Parity = NOPARITY;            // 0-4=no,odd,even,mark,space
        PortDCB.StopBits = ONESTOPBIT;        // 0,1,2 = 1, 1.5, 2
  // Configure the port according to the specifications of the DCB structure.
        if (!SetCommState (hComm, &PortDCB))
        {
            printf("Could not configure serial port\n");
            return NULL;
        }
    // Retrieve the time-out parameters for all read and write operations on the port.
        GetCommTimeouts (hComm, &CommTimeouts);
    // Change the COMMTIMEOUTS structure settings.
        CommTimeouts.ReadIntervalTimeout = MAXDWORD;
        CommTimeouts.ReadTotalTimeoutMultiplier = 0;
        CommTimeouts.ReadTotalTimeoutConstant = 0;
        CommTimeouts.WriteTotalTimeoutMultiplier = 0;
        CommTimeouts.WriteTotalTimeoutConstant = 0;
        if (!SetCommTimeouts (hComm, &CommTimeouts))
        {
            cout<<"Could not set timeouts\n"<<endl;
            return NULL;
        }
        return hComm;
    } 
int main(void)
{
    HANDLE hAppend;
    HANDLE hFile;
    DWORD dwBytesRead=1, dwBytesWritten=1,dwBytesTransferred=1;
    BYTE buff;
    int choice;
    char f1[1000];
    do
    {   cout<<"\n===============================================================";
        cout<<"\nPlease select\n[1]\tFor sending file \n[2]\tFor receiving file \n[3]\tTo exit\n";
        cout<<"=================================================================\n";
        cin>>choice;
    }
    while((choice!=1)&&(choice!=2)&&(choice!=3));
    if(choice==1)
    {   
        hPort = ConfigureSerialPort("COM1");
        if(hPort == NULL)
        {
            cout<<"Com port configuration failed"<<endl;
            return -1;
        }
        cout<<"Enter source file name(ex:source.txt): "<<endl;
        fflush(stdin);
        cin>>f1;
        hFile = CreateFile(f1, // open ***.TXT 
        GENERIC_READ, // open for reading 
        0, // do not share 
        NULL, // no security 
        OPEN_EXISTING, // existing file only 
        FILE_ATTRIBUTE_NORMAL, // normal file 
        NULL); // no attr. template 
        if (hFile == INVALID_HANDLE_VALUE) 
        { 
            cout<<"Could not open file."<<endl;
            return -1;// process error 
        };
        cout<<"File sending ... "<<endl;
        do
        { 
            if (ReadFile(hFile, &buff, 1, &dwBytesRead, NULL)) 
            {
                if(!WriteByte(buff))
                {
                    cout<<"Could not write to port."<<endl;
                    break;
                }
            }
            else 
            {
                cout<<"Could not read flie."<<endl;
                break;
            }           
        } while (dwBytesRead == 1); 
        CloseHandle(hPort);
        CloseHandle(hFile); 
    };
    if(choice==2)
    {   
        hPort = ConfigureSerialPort("COM2");
        if(hPort == NULL)
        {
            cout<<"Com port configuration failed"<<endl;
            return -1;
        };
        cout<<"Enter destination file name(ex:destination.txt): "<<endl;
        fflush(stdin);
        cin>>f1;
        hAppend = CreateFile(f1, // open ***.TXT 
        GENERIC_WRITE, // open for writing 
        0, // do not share 
        NULL, // no security 
        OPEN_ALWAYS, // open or create 
        FILE_ATTRIBUTE_NORMAL, // normal file 
        NULL); // no attr. template 
        if (hAppend == INVALID_HANDLE_VALUE) 
        { 
            cout<<"Could not open file."<<endl;// process error
            CloseHandle(hPort);
            _getch();
        }
        cout<<"File received: "<<f1<<endl;
        cout<<"Reading from the port COM .........."<<endl;
        do
        { 
            if (ReadFile (hPort, &buff, 1, &dwBytesTransferred, 0)>0) 
            {

                if(WriteFile(hAppend,&buff, 1, &dwBytesWritten, NULL))
                {
                    cout<<".";
                }
                else
                {
                    cout<<"Could not to write file."<<endl;
                    break;
                }
            }
            else 
            {
                cout<<"Could not read from port."<<endl;
                break;
            }
        } while (dwBytesTransferred== 1); 
        CloseHandle(hPort);
        CloseHandle(hAppend); 
    };
    if(choice==3) return 0;
    _getch();
    return 0;
}

Edited 3 Years Ago by Quân

This is c++ forum, not vb.net

when I send file without the received Com, it still send and exit,

What part of that program are you talking about -- which Choice? Sorry, but I can't test your program because none of my computers have serial ports.

Edited 3 Years Ago by Ancient Dragon

This article has been dead for over six months. Start a new discussion instead.