Help Parsing out a return message from a stage controller


I am attempting to interface an IAI stage system with IP7. It communicates on serial and needs a convoluted (IMHO) messaging string to communicate. In general it communicates in hex but with varying field widths and then the first character is thrown in just to mess you up.

Example: Stage move
Sprintf input, "!99234%02X%04X%04X%04X%08X",axispattern(ctrlName),Accel,decel,vel,VarNum*1000

This part works now I am trying to figure out how to parse the response specifically I want to know when it has stop moving.

The response format is
Header "#" width of 1 byte
Station "XX(h)" width of 2 bytes
Mess ID "212(h)" width of 3 bytes
Axis Pattern "XX(h)" width of 2 bytes
Axis Status "XX(h)" width of 2 bytes
... to carriage return and line feed.

I need to look at bit 0 of the Axis status field to see it is still moving. So in principle I should know where to expect the data.
Do date I have tried just getting the whole message as a text string but I am getting a bunch of unknown characters which show up as diamonds with question marks. Any suggestions?


If I look at the VTDReadHex2 it is looking for either 4 or 8 bytes. So how should I approach this?
Attached is a screenshot. The computer has limited connectivity. I highlighted the variable in the data browser to show the value. Additionally my interface has a set variable field that has the response variable linked. Note that the value of the variable response is not the same in both places.

When Igor 7 displays the contents of string variables, such as in the data browser, it interprets their contents as UTF-8 encoded text. If that's not what the string contains (likely in your case) then the display of the value won't be of much use. I know that doesn't answer your question but it explains the unknown characters.
It looks to me like the device is sending binary, not hexadecimal which uses only ASCII characters.

To see each byte's value expressed as decimal and hex, execute:
Function Test()
    SVAR response = root:response
    Variable numBytes = strlen(response)
    Variable i
    for(i=0; i<numBytes; i+=1)
        Variable byte = char2num(response[i]) & 0xFF
        Printf "Offset %d: byte=%d, as hex=%02X\r", i, byte, byte

Typically when I do serial communications I have always taken the strings or numbers as a group ending with the terminators and I guess that works for the vast majority of cases. For this case where I need to pick a particular value out of the message can I (and how would) just get the piece I need and throw away the rest. For example in the message I need bytes 9 and 10 taken as a hex number and then I can do a test for the value either in bit 0 or bit 4. So in this case would this work?

Read 8 bytes using VDTreadbinary /s=8 dummyVariable // throw away
Read 2 bytes using VDTreadHex2 realVariable
Read the rest using VDTread2 /T="\n\r" dummyString //Throw away and clear out the rest of the message


I am only a novice at such stuff. Regardless, I might (perhaps mistakenly) suggest to

* read the entire line to the EoL character (storage is cheap, r/w is slow, and who knows what you might need later vs now)
* parse out the required content from the line in a clever HEX or BYTE or BIT or ... space.

As for the second step, I might wonder if you could use a bit/byte-mask and do bit/byte-operation-math. I think for example

testval = mask && line // where mask is cleverly designed to expose only the bytes to be tested
if (testval ...) // the test that you need

Mostly I wonder if, with some clever coding in HEX or BYTE or whatever space, you can avoid doing some other complicated or back-and-forth conversions just to test the input value.

J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAH
So in this case would this work?

It would if bytes 8 and 9 were a two-digit hex number. But I see nothing in to indicate that is the case. My guess is that it is a two-byte binary number.

The "4C" that appears in the Data Browser looks like a two-byte hex number, but it is not at byte position 8 and 9.

I did a quick test. I had an earlier version of my experiment that was developed using IP6.3 I talk to the stage controller and get responses from it. The response are all text without any missing characters. See attached screenshots and the IAI Response field.

Is there a bug in the VDT2 code for IP7?

Is there a bug in the VDT2 code for IP7?

Possibly but this would not be my first suspicion.

First, separate the VDT2 issue from the IAI Response control issue as follows:

1. Try setting the IAI Response field using a SetVariable command from the command line to what you think it should say and see if you can get it to misbehave. If so, post the simplest possible complete example.

2. Write the simplest possible function that gets the response from the instrument and print it to the history. If it misbehaves then print the response to the history as hexadecimal using the Test function that I posed on November 15. Then post the output from the Test function.

Since Igor7 uses Unicode to store text, if the instrument is returning non-ASCII text, you will need to convert it to UTF-8 using ConvertTextEncoding.

The system controller has a test call feature where it just returns the same message you send. Previously when I was using IP6.3 this worked as expected.

I issue this command to the controller Input

The response without the ConvertTextEncoding command

With it the response variable is empty (0 length)

Function TestCall()

    String Input
    Sprintf input, "!99200%010d", datetime

Function ExecuteIAI(CmdStr)
    String CmdStr
    VDT2 /P=$IAI killio
    SVAR InputCommand
    SVAR Response
    InputCommand = CmdStr
    CmdStr = CmdStr+"@@\r\n"
    VDTOperationsPort2 $IAI
    VDTWrite2 /O=3 CmdStr
    sleep /t 2
    VDTRead2  /O=5  /T="\r\n" response
    //response = ConvertTextEncoding(response , 1 , 3 , 1, 1 ) I tried it both ways with and without the conversion
    if (stringmatch(response, "*#*" ))//check to see if response has correct code
        SetVariable IAIResponse valueBackColor=(32768,65280,32768) //set color to green
        Setvariable  IAIResponse valueBackcolor=(65280,32768,32768) //set color to red

The response without the ConvertTextEncoding command

Now, if you will run the Test function posted above, we can see what bytes those erroneous characters represent.

I would also like to see the dump from a simpler test string, such as "ABC".
Found the problem and as I should have predicted it was not an IP7 issue.

The serial communications had been switched to 2 stop bits instead of 1. It is still odd to me that communication to the controller worked fine, but not back. I am far from an expert in serial communications.

Found the problem and as I should have predicted it was not an IP7 issue.

The serial communications had been switched to 2 stop bits instead of 1. It is still odd to me that communication to the controller worked fine, but not back. I am far from an expert in serial communications.