I think there may be a solution with this performance counter for my purposes… here’s what I’m trying to accomplish:
I’m trying to read a string from a serial port until I get a linefeed, but I don’t want it to get stuck in an endless loop which could happen if: A: nothing is ever received B: garbage is being received due to bad connection or baudrate mismatch.. etc.. So I keep reading the port in a loop until A: I try 10 times and still get nothing B: I get the data I’m looking for ending with a #10 C: I get too much data, then I stop after 254 bytes, the response should never be that long, so I’ll flag that as garbage. D: I try 1000 times and still do not have a #10 but I also do not have 254+ bytes For fast baud rates, this works fine, but for slow baudrates, I reach 1000 tries way before the string is finished, so I planned on putting in a delay calculated from the baudrate… however I think I can take a different approach here. I don’t really care the exact amount of time between retries, I just want to try for a long enough length of total time before giving up, so I don’t get stuck in a loop. Perhaps I can read QueryPerformanceCounter(ct); during the loop and if it exceeds the set amount of time, then use that to end the loop and give up. Here’s my function as it is.. fyi, my entire project is in turbo pascal compatibility mode: Function ReadSerial(SerPortNum:Byte):String; Var Loopcount:Word; CharCount:Byte; InputString:String; InputLetter:Char; Begin LoopCount:=0; CharCount:=0; InputString:=''; repeat Status:= SerRead(SerialHandle[SerPortNum], Inputletter, 1); if (status > 0) {and ((InputLetter<>#10) AND (InputLetter<>#13))} then begin Inc(CharCount); case InputLetter of ' ':InputString:=InputString+'.'; #10:InputString:=InputString+'#10'; #13:InputString:=InputString+'#13'; else InputString:=InputString+(InputLetter); end; end; Inc(Loopcount); {need delay here for slow baud rates} Until (InputLetter=#10) OR ((Loopcount>10) AND (InputString='')) OR (CharCount>254) OR (Loopcount>1000); ReadSerial:=InputString; end; From: fpc-pascal-boun...@lists.freepascal.org [mailto:fpc-pascal-boun...@lists.freepascal.org] On Behalf Of Dmitry Boyarintsev Sent: Tuesday, July 26, 2016 1:05 PM To: FPC-Pascal users discussions <fpc-pascal@lists.freepascal.org> Subject: Re: [fpc-pascal] Microsecond Delay Suggestions? On Tue, Jul 26, 2016 at 12:38 PM, James Richters <ja...@productionautomation.net <mailto:ja...@productionautomation.net> > wrote: What I need is a timer that I can specify in microseconds, a millisecond is too long. I am using it for timing to read in a string on a serial connection. My fastest baudrate is 250000, so at that rate I would need to delay only 36 microseconds. So I can’t use sleep () or delay () because they only go down to 1mS and that’s too slow. Here's an example of Sleep with microseconds that I came up with procedure SleepMcs(mcs: Int64); var ct : TLargeInteger; fr : TLargeInteger; af : TLargeInteger; trg : TLargeInteger; const NanoInMicro = 1000; begin QueryPerformanceCounter(ct); QueryPerformanceFrequency(fr); trg:=round(mcs * NanoInMicro / (NSInSec/fr)); repeat QueryPerformanceCounter(af); until trg<=(af-ct); end; I'm hoping that there's a better solution out there, because this procedure will end up with 100% CPU load. I doubt it's possible to unload the CPU, since the windows scheduler is in milliseconds accuracy. May be a lower (kernel/driver) level allows that. thanks, Dmitry
_______________________________________________ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal