I'm querying a computer at 1200 baud using 2 chr ASCII commands. It
sends back a string of characters and I'm trying to get them into a
STRING in the BX-24 to process. This is the code I came up with many
years ago, it works but my sped bottle-neck is here. Is there a faster
way to send a TEXT to a serial port and grab the reply into a STRING?
'Gets a string of data from the selected serial port
'until the Queue is empty .
'Returns with a string of data in GETTDATA
PUBLIC Sub GetSerialData(ByVal SENDDATA as STRING)
ErrorFlag = 0
LAST = FALSE
TRY = 0
GETDATA = ""
CALL PUTPIN(RedLED, LEDoff)
' DO
CALL PutQueueStr(OutBuf,SENDDATA)
CALL SLEEP(0.4)
DO
IF (StatusQueue(INBUF)) THEN
GOTO CONT
END IF
TRY = TRY + 1
'DEBUG.PRINT"Trying to get DATA..."
'DEBUG.PRINT CSTR(TRY)
LOOP UNTIL(TRY = 5)
ErrorFlag = 1
GOTO ENDSUB
CONT:
GETDATA = ""
DO
IF (StatusQueue(INBUF)) THEN
CALL GetQueue(INBUF,INBYTE,1)
TEMP = CHR(INBYTE)
GETDATA = GETDATA & TEMP
ELSE
LAST = TRUE
END IF
LOOP UNTIL(LAST)
ENDSUB:
'DEBUG.PRINT"GETDATA =[";GETDATA;"]"
End Sub
[Non-text portions of this message have been removed]

(You need to be a member of basicx -- send a blank email to basicx-subscribe@yahoogroups.com )
Public Sub GetSerialData(ByVal SENDDATA as STRING)
GETDATA = ""
CALL PUTPIN(RedLED, LEDoff)
CALL PutQueueStr(OutBuf,SENDDATA)
Do While NOT(StatusQueue(INBUF))
Call Sleep(0) 'just sit idle
Loop
Do While (StatusQueue(INBUF))
CALL GetQueue(INBUF,INBYTE,1)
GETDATA = GETDATA & CHR(INBYTE)
Loop
End Sub
I think this is the fastest method, as far as code execution time.
You could also check the amount of data in the queue and read it all
at once, using GetQueueCount for a possible firther speed increase.
In your origional code, you wait for 0.4 seconds before you try to
read the data. That is what is holding up the code.
I would suggest you turn this sub into a separate task, and let it run
continuously. When used in that manner, it will not hold up the rest
of the application waiting for the data to arrive. Since tasks can't
take parameters, you'll have to make SENDDATA a global variable.
You'll need to impliment 2 flags, a Ready To Send Flag, and a Data
Received Flag. The GetSerialData task would sit in an idle loop until
the Ready To Send Flag is set. Once the data string is received,
GetSerialData will set the Data Received Flag. It's up to the rest of
the program to do something with the data and reset the flags.
The task version:
Public SENDDATA as String 'This is global now
Public DataReady as Boolean
Public ReadyToSend as Boolean
Public Sub GetSerialData()
GETDATA = ""
Do
'wait for the data to be ready so that
'we don't send partial data
'We also don't want to overwrite the string
'before it can get read by the rest of the
'program.
Do While NOT(ReadyToSend) OR (DataReady)
Call Sleep(0)
Loop
CALL PUTPIN(RedLED, LEDoff)
'Send the data
CALL PutQueueStr(OutBuf,SENDDATA)
'Wait until there is data in the queue
Do While NOT(StatusQueue(INBUF))
Call Sleep(0)
Loop
'Get the data
Do While (StatusQueue(INBUF))
CALL GetQueue(INBUF,INBYTE,1)
GETDATA = GETDATA & CHR(INBYTE)
Loop
'Set the flag
DataReady = True
'go back to waiting for SENDDATA to be ready
'Remember to reset the flags
Loop
End Sub
This version will hang if the data never shows up in the queue.
Depending on how long the PC side takes to respond, you can add a
counter in the loop:
Public SENDDATA as String 'This is global now
Public DataReady as Boolean
Public ReadyToSend as Boolean
Public Sub GetSerialData()
'Time in millisecinds to wait for a response
Const TimeOut As Integer = 500
Dim A as Integer
Do
'wait for the data to be ready so that
'we don't send partial data
'We also don't want to overwrite the string
'before it can get read by the rest of the
'program.
A = 0
Do While NOT(ReadyToSend) OR (DataReady)
Call Sleep(0)
Loop
CALL PUTPIN(RedLED, LEDoff)
'Send the data
CALL PutQueueStr(OutBuf,SENDDATA)
'Wait until there is data in the queue
Do While NOT(StatusQueue(INBUF)) OR (A = TimeOut)
Call Sleep(0.001) 'slow it down just a bit
A = A + 1
Loop
'Get the data
Do While (StatusQueue(INBUF))
CALL GetQueue(INBUF,INBYTE,1)
GETDATA = GETDATA & CHR(INBYTE)
Loop
'Set the flags if there is valid data
If Len(GETDATA) > 0 Then
DataReady = True
ReadyToSend = False
End If
'go back to waiting for SENDDATA to be ready
'Remember to reset the flags
'GETDATA should also be cleared elsewhere
'before DataReady is reset
Loop
End Sub
If the data isn't received before the TimeOut occurs, the task
continues it's loop. With no data in the queue, it loops around to
the beginning and tries again.
HTH
-Don
--- In b...@yahoogroups.com, "James R. Parish"
wrote:
>
> I'm querying a computer at 1200 baud using 2 chr ASCII commands. It
> sends back a string of characters and I'm trying to get them into a
> STRING in the BX-24 to process. This is the code I came up with many
> years ago, it works but my sped bottle-neck is here. Is there a faster
> way to send a TEXT to a serial port and grab the reply into a STRING?
>
>
>
> 'Gets a string of data from the selected serial port
>
> 'until the Queue is empty .
>
> 'Returns with a string of data in GETTDATA
>
>
>
> PUBLIC Sub GetSerialData(ByVal SENDDATA as STRING)
>
> ErrorFlag = 0
>
> LAST = FALSE
>
> TRY = 0
>
> GETDATA = ""
>
>
>
> CALL PUTPIN(RedLED, LEDoff)
>
> ' DO
>
> CALL PutQueueStr(OutBuf,SENDDATA)
>
> CALL SLEEP(0.4)
>
> DO
>
> IF (StatusQueue(INBUF)) THEN
>
> GOTO CONT
>
> END IF
>
> TRY = TRY + 1
>
> 'DEBUG.PRINT"Trying to get DATA..."
>
> 'DEBUG.PRINT CSTR(TRY)
>
> LOOP UNTIL(TRY = 5)
>
> ErrorFlag = 1
>
> GOTO ENDSUB
>
>
>
> CONT:
>
> GETDATA = ""
>
> DO
>
> IF (StatusQueue(INBUF)) THEN
>
> CALL GetQueue(INBUF,INBYTE,1)
>
> TEMP = CHR(INBYTE)
>
> GETDATA = GETDATA & TEMP
>
> ELSE
>
> LAST = TRUE
>
> END IF
>
> LOOP UNTIL(LAST)
>
>
>
> ENDSUB:
>
> 'DEBUG.PRINT"GETDATA =[";GETDATA;"]"
>
> End Sub
>
> [Non-text portions of this message have been removed]
>

(You need to be a member of basicx -- send a blank email to basicx-subscribe@yahoogroups.com )Don, I tried all your suggestions and the one that I got to work was
using "GetQueueCount".
This SUB can be optimized some more I'm sure but I was just trying to
get it working. It's running as fast as I can get it to but I'm at a
loss as why I still need the SLEEP(0.001) to make it work. Something
about trying to get the buffer status to soon maybe? Since I know how
many characters are suppose to be sent from each query I decided to use
the GetQueueCount() and it works great. I really don't care that there
IS data in the queue but whether it is the correct data. I'm thinking
maybe the 1200 BAUD may be a bit slow, I might try stepping up to 9600
to see if that gets rid of the sleep statement.
Anyone else have any comments?
The serial port is setup for 1200,N,8,1
'Gets a string of data from the selected serial port
'until the Queue is empty .
'Returns with a string of data in GETTDATA
PUBLIC Sub GetSerialData(ByVal SENDDATA as STRING, ByVal QCOUNT as
integer)
ErrorFlag = 0
DIM COUNT as integer
LAST = FALSE
TRY = 0
GETDATA = ""
Call ClearQueue(InBuf)
Call ClearQueue(OutBuf)
CALL PUTPIN(RedLED, LEDoff)
CALL PutQueueStr(OutBuf,SENDDATA)
DO
CALL SLEEP(0.001)
IF (GetQueueCount(InBuf) = QCOUNT) THEN
GOTO CONT
END IF
TRY = TRY + 1
' DEBUG.PRINT"Trying to get DATA..."
' DEBUG.PRINT CSTR(TRY)
'Count = GetQueueCount(inbuf)
'Debug.Print "Count = "; CStr(Count);" QCOUNT NEEDS=";Cstr(qcount)
LOOP UNTIL(TRY = 255)
ErrorFlag = 1
GOTO ENDSUB
CONT:
GETDATA = ""
DO
IF (StatusQueue(INBUF)) THEN
CALL GetQueue(INBUF,INBYTE,1)
TEMP = CHR(INBYTE)
GETDATA = GETDATA & TEMP
ELSE
LAST = TRUE
END IF
LOOP UNTIL(LAST)
ENDSUB:
'DEBUG.PRINT"GETDATA = ";GETDATA;"=";CSTR(ASC(GETDATA))
End Sub
[Non-text portions of this message have been removed]

(You need to be a member of basicx -- send a blank email to basicx-subscribe@yahoogroups.com )