Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Device simulation on COM port

I have a device that sends data to COM port. And I'd like to simulate this device when it's not plugged in. I thought that this can be accomplished by simply sending data to a specific COM port:

int main() {
    char *port = "\\\\.\\COM40";

    HANDLE hCom = CreateFile(port, GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
    if (hCom==INVALID_HANDLE_VALUE) return 0;

    DWORD writeBytes;
    int buffer = 0xDEADBEAF;
    BOOL success = WriteFile(hCom, &buffer, 4, &writeBytes, NULL);

    FlushFileBuffers(hCom);
    Sleep(1000);

    HANDLE hCom2 = CreateFile(port, GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
    if (hCom2==INVALID_HANDLE_VALUE) return 0; // Exit. GetLastError() == 5

    DWORD readBytes;
    success = ReadFile(hCom2, &buffer, 4, &readBytes, NULL);

    CloseHandle(hCom);
    CloseHandle(hCom2);
    return 0;
}

Unfortunately that doesn't work and second CreateFile() sets last error to ERROR_ACCESS_DENIED. What am I missing?

like image 865
AlexP Avatar asked Apr 28 '26 11:04

AlexP


1 Answers

For simulation, install a virtual COM port driver, such as com0com. You can then define 2 COM ports that are linked together in the driver. No hardware needed. Anything written to one port is readable on the other port. You can then open a handle to each port with separate calls to CreateFile().

I use this technique myself, it works very well. When I need to write an app that communicates with a device, I usually write a separate simulation app that generates data for the main app to read, and consumes data the main app sends. The main app doesn't know it is not communicating with a real device, so you don't have to change any code in the main app to support simulations .

like image 176
Remy Lebeau Avatar answered Apr 30 '26 00:04

Remy Lebeau