|
Post by johnnyd on Jun 13, 2019 4:39:16 GMT -5
Hi,
I use the following code snippet as a routine to detect when I connect a USB device that transmits a constant string. I look for a header marker to determine it's the correct device and then grab and use the port number in a main routine.
As USB com ports can be anything, I look through the first 16 which is where it is most likely to appear.
find$=chr$(255)+chr$(255) com$=""
[comloop] scan for a=1 to 16 oncomerror[comerr] open "com"+str$(a)+":,9600,N,8,1,cs0,ds0,rs" for input as #coms calldll #kernel32,"Sleep",200 as ulong,r as void a$=input$(#coms,lof(#coms)) close #coms if a$="" then[next] pa=instr(a$,find$) if mid$(a$,pa,2)=find$ and mid$(a$,pa+11,2)=find$ then com$=str$(a) exit for end if goto[next]
[comerr] oncomerror
[next] calldll #kernel32,"Sleep",100 as ulong,r as void next a if com$<>"" then[csok] goto[comloop]
[csok] wait
The problem is that memory usage will creep up and eventually crash out with "stack overflow".
I've tried with and without the oncomerror and increased the sleep delay at the end but the problem remains.
If you run this in debug and have task manager open, you will see the effect.
Sounds like a housekeeping issue?
John.
|
|
|
Post by Brandon Parker on Jul 6, 2019 20:38:46 GMT -5
Hey John, Just with a quick look, I suspect there is a stack build-up issue occurring. A better way to do this would be to use Subroutine/ Function to encapsulate things like this that way when it happens and the Subroutine/ Function exits the For...Next stack is marked for garbage collection.
Here is a short example with the function I use when doing something like this. This way if there is an error trying to open a comm port while testing if it is active the [COMOpenError] branch sends the program control back into the For...Next loop at the end of it so that the next iteration can continue. This allows the For...Next loop to work all the way through, and no matter what anything left over after the For...Next loop has finished will be marked for garbage collection when the function exits and returns control to where it was called from.
Also, I do believe that COM ports are supposed to be opened as "Random" not "Input" in Liberty BASIC. Only Carl would be able to say whether that would make any difference, but I always use "Random" as the type of file to open with COM Ports.
Global False : False = 0 Global True : True = 1
numBaudRates = 3 BaudRate(0) = 9600 BaudRate(1) = 19200 BaudRate(2) = 56200 BaudRate(3) = 115200
If Not(TestCOMPorts(16, numBaudRates)) Then Print "No COM Ports have been identified as being available!" Print "This program has been terminated." Wait End If End
Function TestCOMPorts(upperLimit, numBaudRates) OnCOMError [COMOpenError] For i = 1 To upperLimit For ii = 0 To (numBaudRates - 1) ComErrorNumber = 0 Print "Testing COM Port - [";str$(i);"] At BaudRate -[";str$(BaudRate(ii));"]" Open "Com";str$(i);":";BaudRate(ii);",n,8,1,ds0,cs0,rs0" For Random As #COM Print "Active COM Port - [";str$(i);"] At BaudRate -[";str$(BaudRate(ii));"]" TestCOMPorts = True Close #COM [ForLoop] Next ii Next i Exit Function [COMOpenError] GoTo [ForLoop] End Function
I hope this example helps with what you are doing. Let me know if it does not make sense or you need further help with it.
{:0)
Brandon Parker
|
|