I'm trying to figure out how to read a packet of HEX Bytes of an unknown length that have no specific termination character over a serial port as efficiently as practical. The packet ends when there is just no more data to read.
I have something that is working that I wrote using SerRead from the Serial unit in FPC, and it works at 9600bps, but the method I am using will not work well at anything higher unless I can figure out how to a very accurate very short delay. At 9600, I need a delay just a little less than 1ms, so I use Sleep(1) for my delay, but since 1ms is the minimum for sleep, and sleep itself is not really that accurate, I am doing a lot more delay than I need to in order to make sure it works. The procedure is: Check the serial port for a byte in a loop until you either get a byte or you get a timeout Then once you have one byte, you delay enough time for few bytes to be in the buffer Next read one byte at time, Delay at the correct rate for the baudrate until you run out of bytes or hit a maximum number of bytes. What is needed is to stop at a timeout in case there is nothing to read, OR to stop when maximum bytes are read OR stop when 2 bytes are missed meaning you ran out of data to read. But once you read one byte, you abandon the timeout. SerReadTimeout has a timeout, but it seems to be a timeout for the whole operation.. what I need is the first timeout to be a long timeout to wait for the device to respond, but once you get one byte, you cancel the timeout and never use it again.. now you read as many bytes as you can until you miss two in a row... then you stop. Either that or have two timeouts, one timeout to delay for receiving the first byte and the second timeout a way to tell when you have no more bytes left to read. It Seems like lots of people would want to read serial ports in this way, because you never know how many bytes are coming, and you don't want to always wait the entire timeout, that is just there to stop it in case there is no data. Then again, I guess most applications can read until they get a linefeed or carriage return, which I will not be. I'm thinking this has already been done somewhere and maybe there is already a solution that is tested and works, but I don't know where it is or what it's called. I could not even find any documentation of SerReadTimout. Here is pseudocode of the procedure that would be needed... the only thing I am really lacking is the accurate time delay. So if there is not already a function somewhere that works this way, then a recommendation on very fast and accurate timing delays would be helpful. repeat Read the serial port and check for a byte Delay the amount of time one byte should take Inc(Timeout); Until (Timeout=Max_Allowed) or Byte_ is_received If Byte is received Begin Count:=-0; String:=String+ByteRead; Inc(Bytes_Read); End; Delay enough time for a few more bytes to get in the buffer Repeat Read serial port Delay the amount of time one byte should take If Byte is received Begin Count:=-0; String:=String+ByteRead; Inc(Bytes_Read); End Else Inc(Count); Until MaxBytesRead Or (Count=2) James _______________________________________________ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal