UWP Serial Port Missing Bytes, Bytes Written Windows IoT
Whilst writing a PCX format, 1 bit per pixel (1bpp) byte array to a serial port FTDI USB serial adapter using WinRT/UWP, on a Laptop (using for developing before deploying to RPi2), it kept failing to work correctly. The serial port was going to the RS232 input of a Zebra Thermal printer, the PCX representing a bitmap to print. The code below was used to push the byte array through to the serial port, after failing to find any answers on line and eliminating other possibilities, a logic analyser on the serial port uncovered the issue. The bye array was not complete.
public async Task Print(byte[] bytesTosend)
{
using (DataWriter dataWriteObject = new DataWriter(serialPort.OutputStream))
{
await WriteBytesAsync(dataWriteObject, bytesTosend);
if (dataWriteObject != null)
{
dataWriteObject.DetachStream();
}
}
}
public async Task WriteBytesAsync(DataWriter dataWriteObject, byte[] bytesTosend)
{
Task<UInt32> storeAsyncTask;
int offset = 0;
do
{
int buffersize = bytesTosend.Length;
//if (buffersize > 1000) { buffersize = 1000; }
byte[] sendBuffer = new byte[buffersize];
System.Buffer.BlockCopy(bytesTosend, offset, sendBuffer, 0, buffersize);
dataWriteObject.WriteBytes(sendBuffer);
storeAsyncTask = dataWriteObject.StoreAsync().AsTask();
UInt32 bytesWritten = await storeAsyncTask;
offset += buffersize;
} while (offset < bytesTosend.Length);
}
Running the code in debug and looking at the length of the byte array, compared to the bytes sent, the problem is clear to see. The image is 200x200 pixels, so at 1bpp this is 200/8 bytes wide * 200 rows = 5000 bytes.
Indeed the byte array is 5000 bytes to send, but wait look at how many bytes have actually been sent,4096 bytes! Somewhere four bytes have gone missing, thus the printer is awaiting the complete image and does not print.
There seems to be no way to flush the buffer or any other methods on the DataWriter that could be used to force these extra bytes out, anyway the missing bytes might not necessarily from the end of the array. There is a FlushAsync method, however that returns a “not implemented” exception – gotta love coding on this platform…
So perhaps by gut says this is actually some kind of serial buffer overflow problem. Some support to this theory is that writing low numbers of bytes to the serial port works just fine.
Fixing serial port write on UWP application missing bytes
MakerFaire is in three weeks time so a solution is needed quick, not time to raise with Microsoft. As smaller writes works, and my suspicion is a buffer overflow, the solution is to uncomment the commented out line in the code above. This will break any byte array larger than one thousand bytes into chunks and send them one chunk at a time.
Running the code worked, printing the image perfectly every time.
This seems to be how it is in the world of Windows IoT and UWP at the moment, if feels like the first couple of years of the first versions of .NET all over again!