Click here to Skip to main content
15,886,799 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
C++
#include <windows.h>
#include <stdio.h>


int main()
{

    // Defining hexadecimal bytes
    int bytes_to_send[5];
    bytes_to_send[0] = 0x81;
    bytes_to_send[1] = 0x11;
    bytes_to_send[2] = 0xF1;
    bytes_to_send[3] = 0x11;
    bytes_to_send[4] = 0x04;

// 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(
                "COM4", GENERIC_READ|GENERIC_WRITE, 0, NULL,
                OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
    if (hSerial == INVALID_HANDLE_VALUE)
    {
            fprintf(stderr, "Error\n");
            return 1;
    }
    else fprintf(stderr, "OK\n");

    // Set device parameters (10400 baud, 1 start bit,
    // 1 stop bit, no parity)
    dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
    if (GetCommState(hSerial, &dcbSerialParams) == 0)
    {
        fprintf(stderr, "Error getting device state\n");
        CloseHandle(hSerial);
        return 1;
    }

    dcbSerialParams.BaudRate = 10400;
    dcbSerialParams.ByteSize = 8;
    dcbSerialParams.StopBits = ONESTOPBIT;
    dcbSerialParams.Parity = NOPARITY;
    if(SetCommState(hSerial, &dcbSerialParams) == 0)
    {
        fprintf(stderr, "Error setting device parameters\n");
        CloseHandle(hSerial);
        return 1;
    }

    // Set COM port timeout settings
    timeouts.ReadIntervalTimeout = 50;
    timeouts.ReadTotalTimeoutConstant = 50;
    timeouts.ReadTotalTimeoutMultiplier = 10;
    timeouts.WriteTotalTimeoutConstant = 50;
    timeouts.WriteTotalTimeoutMultiplier = 10;
    if(SetCommTimeouts(hSerial, &timeouts) == 0)
    {
        fprintf(stderr, "Error setting timeouts\n");
        CloseHandle(hSerial);
        return 1;
    }

    // Send specified text (remaining command line arguments)
    DWORD bytes_written, total_bytes_written = 0;
    fprintf(stderr, "sending bytes...");
    
    if(!WriteFile(hSerial, bytes_to_send, 5, &bytes_written, NULL))
    {
        fprintf(stderr, "Error\n");
        CloseHandle(hSerial);
        return 1;
    }
    fprintf(stderr, "%d bytes written\n", bytes_written);



    // Close serial port
    fprintf(stderr, "Closing serial port...");
    if (CloseHandle(hSerial) == 0)
    {
        fprintf(stderr, "Error\n");
        return 1;
    }
    fprintf(stderr, "OK\n");

    // exit normally
    return 0;
}

[EDIT: Added code formatting, Jochen Arndt]
Posted
Updated 19-Mar-15 4:29am
v2

1 solution

This depends on your type of application. If you are going to create a GUI application or need to perform other tasks, you must use a worker thread or overlapped I/O.

Your current implementation uses a blocking write call. This means that the call will not return until all data has been send or a timeout occurs. During this time your application can not perform other tasks like processing user input.

For a simple console test program you can just put the write calls into a while loop that breaks upon errors or key press (include conio.h and use _kbit() followed by a _getch() call when a key was pressed).

I suggest to use the above simple method at least until the communication is working.

[EDIT: Added example]
C++
int GetPressedKey()
{
    int ret = 0;
    if (_kbhit())
    {
        ret = _getch();
    }
    return ret;
}

// Code to write and read inside a loop
while (1)
{
    if (!WriteFile(hSerial, bytes_to_send, 5, &bytes_written, NULL))
        break;
    fprintf(stderr, "%d bytes written\n", bytes_written);
    if (GetPressedKey())
        break;
    // Read data here
    if (GetPressedKey())
        break;
}
CloseHandle(hSerial);
 
Share this answer
 
v2
Comments
vinod b v 19-Mar-15 10:51am    
@ Jochen I could not follow what you meant? My main aim atlast is a GUI, but at first place i need to work on this part, sending bytes across the port and reading back and looping the data continously to observe the waveform with oscilloscope. ALthough not an expert at C.But i have created applications before with Labview.
Jochen Arndt 19-Mar-15 12:12pm    
I have update my answer with a code snippet.

If you are going for a GUI app I suggest to use C++ rather than C.

Implementing a worker thread and using overlapped I/O are advanced topics that require some incorporation.

Windows GUI apps contain a message loop that is called continuously. But when your app is blocked by serial I/O, this message loop is never called and the app "hangs". A simple solution is calling the message loop from within your while loop (like the GetPressedKey() in my example). But that is bad design and may lead to problems. The common solution is to use a worker thread that uses overlapped I/O.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900