简体   繁体   中英

Serial port not reading complete transmission

I attempted to modify Teunis van Beelen's Rs232 library, from Polling to event driven and non-overlapped to suit my project. RS232 Library

I expect to receive blocks of data (roughly 100 to 200 chars) every 200ms.

Problem I am having is the received data is very inconsistent, it is cut off at random points, and incomplete.

I would like ReadFile() to return only after reading one whole block of data.( or something to that effect)

I feel like the problem is with the time out settings, because by altering the figures I get different results, but I just cant get it right, my best result so far has been set all time out values to 0 and let ReadFile() expect 150 bytes, this way ReadFile() dose not return unless it reads 150 chars, but this just go out of sync after few transmissions, as I have no idea how much data to expect.

these are the main changes to the polling function in Teunis's code , besides time out settings, all other settings are unchanged:

//Using the EV_RXCHAR flag will notify the thread that a byte arrived at the port
 DWORD dwError  = 0;
//use SetCommMask and WaitCommEvent to see if byte has arrived at the port
//SetCommMask sets the desired events that cause a notification.
if(!SetCommMask(Cport[comport_number],EV_RXCHAR)){
    printf("SetCommMask Error");
    dwError = GetLastError();
    // Error setting com mask
    return FALSE;
}
//WaitCommEvent function detects the occurrence of the events.
DWORD dwCommEvent;
for( ; ; )
{
    //wait for event to happen
    if (WaitCommEvent(Cport[comport_number],&dwCommEvent,NULL))
    {
        if(ReadFile(Cport[comport_number], buf, 1, (LPDWORD)((void *)&n), NULL)){
            //Byte has been read, buf is processed in main
        }
        else{
            //error occoured in ReadFile call
            dwError = GetLastError();
            break;
            }
    else{
        //error in WaitCommEvent
        break;
    }

    break;  //break after read file
}

attempt 2 as suggested by MSDN article on serial com using Do While to cycle through every character in the buffer, this method did not yield any good results either.

DWORD dwError  = 0;

/*
Using the EV_RXCHAR flag will notify the thread that a byte arrived at the port
*/
//use SetCommMask and WaitCommEvent to see if byte has arrived at the port
//SetCommMask sets the desired events that cause a notification.
if(!SetCommMask(Cport[comport_number],EV_RXCHAR)){
    printf("SetCommMask Error");
    dwError = GetLastError();
    // Error setting com mask
    return FALSE;
}
//WaitCommEvent function detects the occurrence of the events.
DWORD dwCommEvent;
for( ; ; )
{
    //wait for event to happen
    if (WaitCommEvent(Cport[comport_number],&dwCommEvent,NULL))
    {
        //Do while loop will cycle ReadFile until bytes-read reach 0,
        do{
        if(ReadFile(Cport[comport_number], buf, size, (LPDWORD)((void *)&n), NULL)){
            //Byte has been read, buf is processed in main
        }
        else{
            //error occoured in ReadFile call
            dwError = GetLastError();
            break;
            }
            }while(n);
        }
    else{
        //error in WaitCommEvent
        break;
    }
    break;  //break after read file
}

I am wondering if rewriting the code in overlapped mode will improve things, but I dont see the advantages as I have no need for multi threading. any suggestions would be great!

Thank you.

ReadFile has no way to detect what a "block of data" is. You should not expect it to understand your data or the timing of that data. The only fix for this issue is for you to process whatever it gives you, using your own knowledge of the data to divide it up into "blocks" for further processing. If you get a partial block keep it, and append to it with the next read.

There is no need to call WaitCommEvent for data. ReadFile will wait for data. But give it a suitably sized buffer and ask for a lot more than one byte at a time. It's extremely inefficient to call it for only one byte. Select the requested count and the timeouts so that ReadFile will return within an acceptable time, whether there is data or not.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM