Windows – Arduino and Windows serial communications issue

arduinocserial-portvisual studio 2010windows

I am working on a project that involves some 'c' serial communication implemented in Visual Studio 2010 Proffesional on a Windows 7 32-bit platform connected to an Arduino Mega device (to control some hardware **not relevant to problem). The code for this works 100%; the ONLY problem I'm having is that something very funny is going on with my serial communication.

The Visual C program is as follows.

HANDLE hDevice = CreateFile(L"COM5",
                            GENERIC_READ | GENERIC_WRITE,
                            FILE_SHARE_READ | FILE_SHARE_WRITE,
                            NULL,
                            OPEN_EXISTING,
                            0,
                            0); //Open COM handle (create file)
if (hDevice !=INVALID_HANDLE_VALUE) //If COM3 connected
{
    printf("Com port opened\n");
    DCB lpTest;
    GetCommState(hDevice,&lpTest);
    lpTest.BaudRate = CBR_9600;
    lpTest.ByteSize = 8;
    lpTest.Parity = NOPARITY;
    lpTest.StopBits = ONESTOPBIT;
    SetCommState(hDevice,&lpTest);
    DWORD btsIO;
    WriteFile(hDevice,c1,strlen(c1),&btsIO,NULL);
    CloseHandle(hDevice);
}

The output of this program is a text string, and I'm 100% happy with it (should end in Null, have x characters, etc.).

Typing the result obtained from this program in Serial Communicator, it does not seem to work! Using a COM spy program, I am able to obtain the "handshaking" protocols from the terminal application.

However, it seems that communication with the Arduino board works on HyperTerminal and not on Serial Communicator or any other serial applications (no handshaking, etc. is done on the Arduino board **not relevant).

The following "handshaking" was obtained from HyperTerminal (THIS WORKS!!)

*
COM port is opened
In/out queue size 8192/8192
Baud rate 9600
DTR on
Data bits=8, Stop bits=1, Parity=None
Set chars: Eof=0x00, Error=0x00, Break=0x00, Event=0x00, Xon=0x11, Xoff=0x13
Handflow: ControlHandShake=(DTR_CONTROL, CTS_HANDSHAKE, ERROR_ABORT), FlowReplace=    (TRANSMIT_TOGGLE, RTS_HANDSHAKE, XOFF_CONTINUE), XonLimit=80, XoffLimit=200
Set timeouts: ReadInterval=10, ReadTotalTimeoutMultiplier=0, ReadTotalTimeoutConstant=0,     WriteTotalTimeoutMultiplier=0,     WriteTotalTimeoutConstant=5000
*

And this is from Serial Communicator (it does not work; incorrect and inconsistent numbers):

*
COM port is opened
In/out queue size 2048/2048
Baud rate 9600
RTS off
DTR off
Data bits=8, Stop bits=1, Parity=None
Set chars: Eof=0x00, Error=0x00, Break=0x00, Event=0x00, Xon=0x11, Xoff=0x13
Handflow: ControlHandShake=(), FlowReplace=(), XonLimit=80, XoffLimit=200
Set timeouts: ReadInterval=0, ReadTotalTimeoutMultiplier=0, ReadTotalTimeoutConstant=0,     WriteTotalTimeoutMultiplier=0, WriteTotalTimeoutConstant=0
*

I can obviously see the differences but need to know how to make the Arduino board independent of these "handshaking" protocols. (DTR, timing, etc.)

And this is from my Visual Studio program (does not work; incorrect and inconsistent numbers)

*
COM port is opened
Baud rate 9600
RTS off
DTR off
Data bits=8, Stop bits=1, Parity=None
Set chars: Eof=0x00, Error=0x00, Break=0x00, Event=0x00, Xon=0x11, Xoff=0x13
Handflow: ControlHandShake=(), FlowReplace=(), XonLimit=80, XoffLimit=200
*

Thus I would like to get the Arduino board away from DTR and all handshaking, as I want the final implementation to "speak" directly from Visual Studio to the Arduino board.

*****UPDATE*******

Thanks for the advice, the thing is I do not understand is why an open source piece of hardware would require so much handshaking.. That is, why does only the worst serial terminal program work where Serial Communicator, advance serial monitor, terterm, terminal, etc. don't seem to work?

I have updated my code to mirror HyperTerminal exactly (complete all handshaking), but it does not seem to work!

Heres the updated code fragement:

HANDLE hDevice = CreateFile(L"COM5",GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ |     FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,0); //Open COM handle (create file)
if (hDevice !=INVALID_HANDLE_VALUE) //If COM3 connected
{
    printf("Com port opened\n"); //Show it's open
    DCB lpTest;
    // Initialize the DCBlength member.
    lpTest.DCBlength = sizeof (DCB);
    GetCommState(hDevice,&lpTest); //com state
    lpTest.BaudRate = CBR_9600;//load baud
    lpTest.ByteSize = 8;// load no. bits
    lpTest.Parity = NOPARITY;//parity
    lpTest.StopBits = ONESTOPBIT;//stop bits

    lpTest.fBinary = FALSE;            // Binary mode; no EOF check
    lpTest.fOutxCtsFlow = TRUE;         // No CTS output flow control
    lpTest.fOutxDsrFlow = FALSE;         // No DSR output flow control
    lpTest.fDtrControl = DTR_CONTROL_ENABLE;  // DTR flow control type
    lpTest.fDsrSensitivity = FALSE;      // DSR sensitivity
    lpTest.fTXContinueOnXoff = TRUE;     // XOFF continues Tx
    lpTest.fOutX = FALSE;                // No XON/XOFF out flow control
    lpTest.fInX = FALSE;                 // No XON/XOFF in flow control
    lpTest.fErrorChar = FALSE;           // Disable error replacement
    lpTest.fNull = FALSE;                // Disable null stripping
    //lpTest.fRtsControl = RTS_CONTROL_ENABLE; //// RTS flow control
    lpTest.fAbortOnError = TRUE;        // Do not abort reads/writes on error
    SetCommState(hDevice,&lpTest);
    DWORD btsIO;
    //ETC
}

The result is exactly the same as the working result from HyperTerminal except there is no timing conditions. However, I have used a 1 second delay after this code before closing the port.

Is the issue with my write statement?

WriteFile(hDevice,c1,strlen(c1),&btsIO,NULL); //Write string to serial

It seems like there is something fundamentally wrong that I am doing, and I can't find it!

*************UPDATE2***********

I have stumbled across something, how would I configure my program to send each character individually?

Visual Studio does not allow me to remove the Null or send one character in the code:

 WriteFile(hDevice,c1,strlen(c1),&btsIO,NULL);//WRITE STRING TO SERIAL

How do I fix this problem? It seems like the Arduino board only accepts one character at a time.

I have edited the character variables to be one char, etc.!

*********UPDATE3********************

This are the results from monitoring the communication from Visual Studio 2010 (or serial communicator) and HyperTerminal. The issue is sending a bit at a time!

HyperTerminal:

Baud rate 9600
DTR on
Data bits=8, Stop bits=1, Parity=None
Set chars: Eof=0x00, Error=0x00, Break=0x00, Event=0x00, Xon=0x11, Xoff=0x13
Handflow: ControlHandShake=(DTR_CONTROL, CTS_HANDSHAKE, ERROR_ABORT), FlowReplace=    (TRANSMIT_TOGGLE, RTS_HANDSHAKE, XOFF_CONTINUE), XonLimit=80, XoffLimit=200
Set timeouts: ReadInterval=10, ReadTotalTimeoutMultiplier=0,     ReadTotalTimeoutConstant=0, WriteTotalTimeoutMultiplier=0, WriteTotalTimeoutConstant=5000

and Program/serial communication:

Baud rate 9600
DTR on
Data bits=8, Stop bits=1, Parity=None
Set chars: Eof=0x00, Error=0x00, Break=0x00, Event=0x00, Xon=0x11, Xoff=0x13
Handflow: ControlHandShake=(DTR_CONTROL, CTS_HANDSHAKE, ERROR_ABORT), FlowReplace=    (TRANSMIT_TOGGLE, RTS_HANDSHAKE, XOFF_CONTINUE), XonLimit=80, XoffLimit=200

An X sec wait in program code.

Best Answer

It's been a long time since I last did serial work -- but it was very clear in those days that your software on the computer had to be configured exactly as the hardware device required. Your non-working example doesn't have DTR or RTS raised, and that's exactly what the board appears to require.

Since software on a full-powered computer is usually far easier to modify than hardware on an embedded board, it'd make sense to look into the configuration options available in your serial software -- any tolerable piece of software will have those settings to fiddle with. If not, I liked both Qmodem and ProComm, though I had friends that were adamant that Telix was the nicer tool. (I had some Trade Wars scripts for Telix that were amazing...)