bartolo-otrit
bartolo-otrit

Reputation: 2519

WinAPI ReadFile returns 0 byte

I'm doing something wrong or the device simply does not respond? How to read data from com port, now I'm doing this:

hCom = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, NULL);


Other settings ....


DWORD dwBytesCount = 0;
    unsigned char response[5] = {0};
    unsigned char command[6] = {0x0A, 0xFF, 0x03, 0x20, 0x04};
    command[5] = Crc8(command, 5);
    printf("\ncrc-8 sum is:%d", command[5]);

    if(!(WriteFile(hCom, command, 6, &dwBytesCount, NULL)) || (dwBytesCount != 6)) {
        dwErrorCode = GetLastError();
        printf("\nError in function WriteFile, error code:%ld, bytes write:%ld", GetLastError(), dwBytesCount);
        std::cin >> input;
        return false;
    }
    printf("\nwrite bytes is:%ld", dwBytesCount);

//  DWORD dwMask;
//  printf("\nWaitCommEvent");
//  if(!WaitCommEvent(hCom, &dwMask, NULL)) {
//      printf("\nError in function WaitCommEvent, error code:%ld", GetLastError());
//      std::cin >> input;
//      return false;
//  }

    for(int i = 0; i < 10; ++i) {
        printf("\nread file");
        if(!(ReadFile(hCom, response, 4, &dwBytesCount, NULL))) {
            dwErrorCode = GetLastError();
            printf("\nError in function ReadFile, error code:%ld, bytes read:%ld", GetLastError(), dwBytesCount);
            std::cin >> input;
            return false;
        }
        Sleep(100);
        printf("\nread bytes is:%ld", dwBytesCount);
    }
    printf("\nread bytes is:%ld", dwBytesCount);
    printf("\nreader response status is:%d", response[3]);
    std::cin >> input;

It reads zero bytes. If I uncomment WaitCommEvent then the program freezes.

I tried the version with the flag OVERLAPPED and GetOverlappedResult after each operation, the result is the same.

addition

As I understand it cannot simultaneously connect to the com port http://www.ms-news.net/f3608/createfile-shared-mode-doesnt-work-2057561.html

Connecting in the second stream produces the same result

Other settings are:

            SetCommMask(hCom, (EV_RXCHAR | EV_RXFLAG | EV_BREAK | EV_CTS | EV_DSR | EV_ERR | EV_RING | EV_RLSD));

            if(!(GetCommTimeouts(hCom, &timeout))) {
                printf("Error in function GetCommTimeouts error code:%ld", GetLastError());
                std::cin >> input;
                return false;
            }

            timeout.ReadIntervalTimeout = 50;
            timeout.ReadTotalTimeoutConstant = 50;
            timeout.ReadTotalTimeoutMultiplier = 10;
            timeout.WriteTotalTimeoutConstant = 50;
            timeout.WriteTotalTimeoutMultiplier = 10;

                    //timeout.ReadIntervalTimeout = 0xFFFFFFFF;
            //timeout.ReadTotalTimeoutConstant = 1000;
            //timeout.ReadTotalTimeoutMultiplier = 0;
            //timeout.WriteTotalTimeoutConstant = 1000;
            //timeout.WriteTotalTimeoutMultiplier = 0;

            if(!(SetCommTimeouts(hCom, &timeout))) {
                printf("Error in function GetCommTimeouts error code:%ld", GetLastError());
                std::cin >> input;
                return false;
            }

        if(!(SetupComm(hCom, 128, 128))) {
            printf("Error in function SetupComm error code:%ld", GetLastError());
            std::cin >> input;
            return false;
        }

        if(!(GetCommState(hCom, &ComDCM))) {
            printf("Error in function GetCommState error code:%ld", GetLastError());
            std::cin >> input;
            return false;
        }

        ComDCM.BaudRate = 115200;
        ComDCM.ByteSize = 8;
        ComDCM.Parity = NOPARITY;
        ComDCM.StopBits = ONESTOPBIT;
        ComDCM.fAbortOnError = TRUE;
        ComDCM.fDtrControl = DTR_CONTROL_DISABLE;
        ComDCM.fRtsControl = RTS_CONTROL_DISABLE;
        ComDCM.fBinary = TRUE;
        ComDCM.fParity = FALSE;
        ComDCM.fInX = ComDCM.fOutX = FALSE;
        ComDCM.XonChar = 0;
        ComDCM.XoffChar = uint8_t(0xff);
        ComDCM.fErrorChar = FALSE;
        ComDCM.fNull = FALSE;
        ComDCM.fOutxCtsFlow = FALSE;
        ComDCM.fOutxDsrFlow = FALSE;
        ComDCM.XonLim = 128;
        ComDCM.XoffLim = 128;

        if(!(SetCommState(hCom, &ComDCM))) {
            printf("Error in function SetCommState error code:%ld", GetLastError());
            std::cin >> input;
            return false;
        }

        printf("success");
        std::cin >> input;

addition 2

I've tested this code with com port emulator and it works, it means that the problem is in the device.

Thank you all for responses and help

Upvotes: 2

Views: 4309

Answers (2)

Martin James
Martin James

Reputation: 24907

You should split up this problem a bit, unless some other poster has already spotted a bug.

Does anything get sent? If you 'scope the tx, or connect to another port where some effective terminal program, or even HyperTerm, is connected, do the command chars go out? WaitCommEvent is blocking if run in non-overlapped mode, and so if uncommented and the thread blocks on it, probably no chars are being received at all. The possible reason for this are many - cables, connectors, baud rate mismatch, incorrect flow control & all the other painful baggage associated with RS232.

Non-overlapped I/O is best done in a thread of its own, but nevertheless, you should get something back here, I think, if the link is working and the peer is capable of responding.

Rgds, Martin

BTW, 'Other settings' here is the order I use. It works on every OS from W2k to W7:

CreateFile(); SetupComm(); setCommTimeouts(); setCommState(); setCommMask(); ReadWriteStuff();

Martin

Upvotes: 3

Bhargav
Bhargav

Reputation: 10209

Have you set the COMMTIMEOUTS structure with correct values and called the function SetCommTimeouts? Please refer to: http://msdn.microsoft.com/en-us/library/aa363190 for further details. Especially the remarks section in there.

This symptom can appear when ReadIntervalTimeout member is set to MAXDWORD and the members ReadTotalTimeoutConstant and ReadTotalTimeoutMultiplier are set to zero because this particular combination of values allows ReadFile to retun immediately even if no bytes have been received.

Upvotes: 1

Related Questions