Aberrant data reading COM port in windows

70 Views Asked by At

From an arduino type microcontroller, the following code sends 16 bit unsigned data over a serial port as raw bytes.

void sendTestData() {
    uint16_t *p16 = &bufferp[DATASTART];
    Serial.println( "TESTDATA" );
    for ( int n = 0; n < NPIXELS; n++ ) {
       p16[n] = n;
    }

    Serial.print( "BINARY16 " );
    Serial.println( NPIXELS );
    Serial.write( (byte *) p16, 2*NPIXELS );
    Serial.println( "END DATA" );
}

On a Linux host computer, the data is read by the following python code, and everything is okay. The data is exactly as sent, the values count from 0 to the value of NPIXELS-1.

data = self.ser.read( ndata*2 )
data = struct.unpack( '<%dH'%(len(data)/2), data )
data = np.array(data)

Now the question/mystery:

On a windows machine (Win11 in vbox), the data is read with the following code.

int readBuffer( void *buffer, DWORD nbytes) 
{
    DWORD nread = 0;
    ReadFile(hSerial,buffer,nbytes,&nread, NULL);
    return nread;
}

if ((nread=readBuffer( rawbuffer, nbytes)))
{
    n = 0;
    m = 0;
    while( n<npixels)
    {
        hi = *b++;
        lo = *b++;
        u16 = hi;
        u16 <<= 8;
        u16 |= lo;
        rawbuffer[n++] = u16;
    }
}

Scanning the data, we find the following errors. In the listing, to the right of the color are u16, hi, and lo from the above code.

Notice that the error occurs every 256 U16 words, or every 512 bytes. In other words it occurs only when the low byte of each reaches 0. And notice, errors such as the first byte, 0x0A = 0101 rather than 0000, are not simple sign bit errors. It looks more like the com port is applying some character coding.

aberrant test value at 0 (0x0000): 2560 from read bytes 0x0a 0x00
aberrant test value at 256 (0x0100): 0 from read bytes 0x00 0x00
aberrant test value at 512 (0x0200): 256 from read bytes 0x01 0x00
aberrant test value at 768 (0x0300): 512 from read bytes 0x02 0x00
aberrant test value at 1024 (0x0400): 768 from read bytes 0x03 0x00
aberrant test value at 1280 (0x0500): 1024 from read bytes 0x04 0x00
aberrant test value at 1536 (0x0600): 1280 from read bytes 0x05 0x00
aberrant test value at 1792 (0x0700): 1536 from read bytes 0x06 0x00
aberrant test value at 2048 (0x0800): 1792 from read bytes 0x07 0x00
aberrant test value at 2304 (0x0900): 2048 from read bytes 0x08 0x00
aberrant test value at 2560 (0x0a00): 2304 from read bytes 0x09 0x00
aberrant test value at 2816 (0x0b00): 2560 from read bytes 0x0a 0x00
aberrant test value at 3072 (0x0c00): 2816 from read bytes 0x0b 0x00
aberrant test value at 3328 (0x0d00): 3072 from read bytes 0x0c 0x00
aberrant test value at 3584 (0x0e00): 3328 from read bytes 0x0d 0x00

Here is how the com port is opened:

bool opencomport(const char *name)
{
    COMMTIMEOUTS timeouts = { 100, //interval timeout. 0 = not used
                              0, // read multiplier
                             100, // read constant (milliseconds)
                              0, // Write multiplier
                              0  // Write Constant
                            };


    bool retv;

    hSerial = CreateFile(name,
                         GENERIC_READ | GENERIC_WRITE,
                         0,
                         0,
                         OPEN_EXISTING,
                         FILE_ATTRIBUTE_NORMAL,
                         0);

    if (hSerial == INVALID_HANDLE_VALUE) {
        MessageBox(NULL,"failed to open comport","",MB_OK);
        exit(-1);
    }

    if ( !SetupComm(hSerial,2*16384,4096) ) {
        MessageBox(NULL,"failed to allocate serial port buffers","",MB_OK);
        exit(-1);
    }

    set8bit();

    if (!SetCommTimeouts(hSerial, &timeouts)) {
        MessageBox(NULL,"failed to set timeouts","",MB_OK);
        exit(-1);
    }
    
    getcomportbuffersizes();

    return true;
}

So, what is wrong? The data is good in the python code in Linux, the errors appear only in windows.

0

There are 0 best solutions below