Search code examples
vb.netserial-portcnc

Reading all data from serial port, but incoming stream doesn't have a consistent end of stream


I'm trying to reverse engineer an old DOS CNC program and I've had limited success. I sniffed the Rx/Tx stream from the DOS program and saw this...

Tx from DOS:

"OUTPUT TEST" 0D 

Rx from machine:

"OUTPUT TEST" 0D 0D 0A 
0D 0A 
"TEST" 0D 0A 
"0001>  +09000  +09000  +00000  +00000  +00000  +00032  +00000  D  O  " 0D 0A 
"0002>  +00000  +03000  +00000  +00000  +00000  +00032  +00000  B  N  " 0D 0A 
"0003>  +00000  +03000  +00000  +00000  +00000  +00032  +00000  B  N  " 0D 0A 
"0004>  +00000  +03000  +00000  +00000  +00000  +00032  +00000  B  N  " 0D 0A 
"0005>  +00000  +03000  +00000  +00000  +00000  +00033  +00000  B  N  " 0D 0A 
"0006>  +00000  +03000  +00000  +00000  +00000  +00033  +00000  B  N  " 0D 0A 
"0007>  +00000  +03000  +00000  +00000  +00000  +00033  +00000  B  N  " 0D 0A 
"0008>  +00000  +03000  +00000  +00000  +00000  +00033  +00000  B  N  " 0D 0A 
"0009>  +00000  +03000  +00000  +00000  +00000  +00033  +00000  B  N  " 0D 0A 
"0010>  +09000  +17000  +00000  +00000  +00000  +00064  +00000  B  X  .  " 0D 0A 
14 0D 0A 
"PIN>  " 

Of course, I had to reformat the stream so it's readable.

As you can see, the last line does not have a line feed. This makes ReadLine useless, as the last line will only show up on the next request. I need to be able to send a command and read to the end. The only way I've been able to achieve this is by sleeping long enough for the transmission to complete on the machine then process the data on the PC. On some machines, the delay has to be set as high as 5 seconds. I'd hate to do it this way, but it works.

While spUISC.BytesToRead > 0
    buffer &= spUISC.ReadExisting
    Threading.Thread.Sleep(100)
End While

Summary

How can I tell if an incoming stream is done if it doesn't have a terminating char?


Solution

  • I personally would modify the loop to do the following:

    1. Read available bytes into the buffer
    2. Attempt to validate that the buffer has a valid response
    3. If yes on #2, consume the buffer and exit the loop. Else keep waiting for more data.

    If you can perform a blocking read, there is no need to sleep at all. You'll just keep looping until you get a valid frame. Obviously, other error handling may be required.