Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Strings vs Integer Arrays for Character Input 1

Status
Not open for further replies.

TomHAFC

Programmer
Feb 18, 2002
5
US
I'd like to write a fast routine that gets input from the COM port, parses it for various strings, and not add >0.5s second delays to the responses to dialog events.

ASPECT doesn't seem to have the ability to index into a 'string'. If true, I'm wondering how to get partial strings from the COM port using the built-in string functions and not waste so much time with system calls that the COM port's buffer overflows OR add delays to the responses to dialog events.

It appears that I could use 'comgetc' to intermittently move characters from the COM port into an integer array with an index. This would allow interruptions from polling the COM port to poll the dialog box for events. If I do this, how do I reduce the overhead of converting the integer array into a string array? Would it be faster to parse the integer array (with other integer arrays) using two indexes and a compare, than converting the integer array into a string array integer-by-integer (using 'itoa' and 'strcat' on each integer in the array) and performing the parsing using ASPECTS built-in string functions?

The COM port will be running at 9600 BAUD. This could probably be lowered, but I'd prefer tighter code.

Thanks,

Tom
 
Have you taken a look at the rget command? The nice thing about the rget command is that you can specify what character from the remote system terminates the rget command, which is much better than the comread command and may prevent you from having to do some of the parsing you've mentioned with the comgetc command. It sounds to me like you are more interested in receiving and potentially modifying a string than building it character by character, and the rget command may work better for you in this case. You may need to do a little trimming of the received string, but ASPECT's string commands should execute fairly quickly.
 
I have worked a little with this and the rget command works well, its quite flexible. If your looking specifically to capture something from the com port and its preceded by a static key word you can use a "waitfor" command followed by the "rget", you can set the rget to only grab a set amount of characters, and only wait so long for these characters. Remember that it will stop when it hits a carriage return so if its required to capture consecutive lines then use a one rget to strip off the return. Maybe something like this.

;grab two lines of characters directly after a key word is received

waitfor "string??"
rget line1
rget nothing 1 1 ;strips CR
rget line2

;put the two lines into one string

strcat lineall line1
strcat lineall line2

;if you needed to find and remove characters within this string, this will look for a key word then move ahead 5 characters and take the next 10 characters and put them into newstring

if strfind lineall "string??" pos
pos = pos + 5
strread linall pos newstring 10
endif

; if these characters are numerical and you want to
; convert them to an integer use:

strtonum newstring newinteger


hope some of this might help a little, one thing I did find and I'm not sure how the computer speed effects this is that if I run at more then 1200 baud the script sometime misses waifor commands.
 
Hi Knob, Chris909,
Thank you for your responses.

I wasn't clear about what I'm trying to do.

I want to search through the 9600 BAUD serial output from a device, to find various error messages. These error messages will be among many status messages that happen throughout a long period (days to weeks) of time. I must save all the messages to a file. And I need to time-stamp the error messages.

I can't afford to miss an error message while parsing non-error messages. I'll pass Chris909's suggestion, of using a static keyword in front of all error messages, on to our software development folks. Static keywords in front of error messages will make my job easier.

Another option is to time-stamp every message (status and error messages). I will do this just to get someting working this afternoon.

Will ASPECT multitask? Can I spawn two routines - one to check and act on dialogbox events and another to check on receive COM port data? Because of the modest speed of the serial port, I am looking for a way to interleave checking the COM port for messages AND checking the dialogbox for events - without ever delaying one because of the other.

The 'rget' command looks like it will always add a (minimum) one second delay (30 seconds if not specified).
Is that true? Also, it doesn't appear to have any advantage over 'comgetc' in the case where the command terminates with an incomplete string from the COM port.

The 'comgetc' command states, "comgetc effectively steals data from the received data buffer" - which I assume is a faster operation. I haven't tested that assumption.

I'd like to get receive characters only when they are waiting in the receive buffer by polling the $RXDATA system variable. It isn't clear to me why the manual says, "comgetc will not be interrupted by a 'when $RXDATA' command." Is this implying that I can write routines that functions similar to interrupt handlers with ASPECT?

If so, could "interrupt handlers" be written that just wait for a dialogbox event or for 'when $RXDATA' ?

If "interrupt handler"-like functions aren't available in ASPECT, I'm back to polling for events from my dialogbox and my COM port. This is where tight code (minimum system calls) to handle checking for dialogbox events WHILE polling the COM port for input might be the fastest way to go. This implies (to me) the need to manipulate strings.

What exactly is a string in ASPECT? Is it an array of four byte "integers" that has zero in the last four bytes?

If there were a 'Union' (C language) construct, I could fetch COM port data into the integer array using an index and pass the string (that was in union with - at the same address as - the integer array) to various system calls for parsing. Unfortunately, that option doesn't appear to exist in ASPECT.

In the interest of getting something going quickly, I will time-stamp all received strings - using rget (per your advice). I'll quickly find out whether, or not, long delays are added to dialogbox events.

Tom

 
For an interrupt type setup in aspect you might be able to use a "when target" command, this will call a procedure when a predetermined character(s) are received without having to continually poll the com port. This might work better for grabbing error codes. Aspect strings as far as I know are just ASCII characters to a max of 256 in length. Yes the rget will wait for a default of 30sec for either the specified amount of characters or a carriage return, and you can specify that time as well. I think you can also terminate the RGET with a specified character(s) as well. So ideally some kind of static character at the start and end of the error message would probably be the best:)
 
You can only have one ASPECT script active per Procomm window, but a script can launch another script using the execute command. I don't think this will help with faster execution though.

I don't see anything in the help file discussion of the rget command saying that there is a minimum delay of one second for the rget to execute. If you can verify that a line of text ends with a certain character (such as a carriage return or linefeed), you can use this as the character for the rget command to key off of. You can either get this information from your development staff, or bring up the monitor window (Data | Monitor Window menu item) within Procomm. Outgoing data is shown in blue and incoming data is shown in red. Make sure that focus is set to the main Procomm window and not the monitor window while you are doing this.
 
Chris909 & Knob,
I ended up using two ASPECT system calls:

#define TIMEOUT 1

string InputBuffer ; 256 bytes reserved
integer InChar
integer InputBufIndex = 0

if $RXDATA ; Check for characters at port.
comgetc InChar TIMEOUT ; Get the waiting character

strputc InputBuffer InputBufIndex InChar ;put in string

InputBufIndex++ ; Bump the index pointer

Checking RXDATA for available receive data prevents the TIMEOUT (1 sec) of 'comgetc' from adding a delay when a
character isn't present.

Once the character input is loaded into a string, ASPECT system calls can be used to manipulate it and search for strings (messages) of interest.

I was hoping to not use any system calls for character input. But, this appears to work fast enough to prevent lost data on a 9600 BAUD rate COM port. And, the dialog
box doesn't have noticeable delays.

Tom

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top