Help Requested with VDT2 Reading

Hi there, I'm currently implementing some new measurement control software for a UHV system and the majority of this involves the reading out of vacuum gauge controllers by RS232. This has been going fine up to now and my VDT2 implementation seems to work for all devices so far up to the Pfeiffer controllers, which use a slightly different format it seems. In brief, I can write the command to request the pressure "PR1". I then expect an ACK message back, I send ENQ and then the gauge delivers the pressure. This has been tested to work fine with a basic terminal, the challenge is in getting VDT2 to work nicely with it. The code as it stands is pasted below:

Function Pfeiffer_Read()

    String pfeiffercom = "COM7"
    String null
    String/G output
   
    String presread = "PR1\r\n"
    String enq = num2char(5)
   
    VDT2 /P=$pfeiffercom baud=9600, buffer=1024, databits=8, in=0, out=0, stopbits=1, parity=0
    VDTOperationsPort2 $pfeiffercom
    VDTOpenPort2 $pfeiffercom
   
    //Request pressure from guage
    VDTWrite2 presread
    //Receive acknowledge
    VDTRead2 /O=2 /T="\n"  null
    //Send enquiry
    VDTWrite2 enq  
    //Read back value
    VDTRead2 /O=2 /T="\n"  output
   
    print output

End


The end result is always that the VDTRead2 commands timeout (even with timout set very long) an no data is read from the bus. Oddly, the data is there on the bus to be read (see attached screenshot) but it seems VDT2 won't read it for some reason. Any suggestions are most appreciated!

Thanks,
Liam

It seems like it should work. I don't know why it is timing out.

For debugging, I would try reading one byte at a time using VDTReadBinary2/S=1 in a loop to see if it can read anything.

Another debugging technique is to do VDTRead2/T=/Q. Then use strlen(output) to see how many bytes were read. See the discussion of /Q in the details section of the documentation for VDTRead2.

Also, during debugging especially, execute "VDT2 killio" before a test to make sure that VDT2 is in a clean state to start with.

This is off topic but, I recommend avoiding global variables as much as possible. Change Pfeiffer_Read to return the string instead of using a global variable for the output. Add /S after Function. Remove /G from "String/G output". And add "return output" at the end.
Thanks for replying so quickly. I've tried both of your suggestions, yet sadly the timeout problem remains. I now have a line that looks like below:

VDTRead2/T=""/Q/O=5 output
print strlen(output)


I understand that this should suppress any error and essentially read everything it can ignoring the CR or LF. The string length is still 0 though. It also reads 0 characters with VDTReadBinary2.

In regards to the global variables, you are right that it is good to avoid them. I being somewhat lazy as this makes it easy to watch what is happening in the data browser, I intend for the final version to report back to the main program in the manner you describe.
I'm pretty-much out of ideas, but...

I'm not sure if Device Monitoring Studio, in the Reads tab, is showing bytes that were read by the serial driver or bytes that were read by Igor. The bytes received would first be read by the serial driver and stored in a driver buffer. Later, they would be read by the VDTRead2 call. My guess is that Device Monitoring Studio is showing bytes read by the driver. You can verify this by commenting out the last VDTRead2 call and seeing if Device Monitoring Studio still shows "0, 3.7100E-08" as being read.

Perhaps Device Monitoring Studio can show you all calls made to the serial driver and all results from those calls. It looks like PortMon (https://technet.microsoft.com/en-us/sysinternals/portmon.aspx) can do that.

The only reason I can see for VDTRead2 reading 0 bytes when you call VDTReadBinary2/S=1 is if the driver said there were no bytes available to be read.

You can call:
VDTGetStatus2 0, 0, 0
Print V_VDT

This attempts to read any bytes received by the serial driver, and stored in the driver's buffer, into a VDT2 buffer, and then returns the number of bytes in the VDT2 buffer. This should tell you how many bytes are available to be read at any given time.

Try changing this:
VDTRead2 /O=2 /T="\n"  null

to this:
VDTRead2 /O=2 /T="\n"  null
Print strlen(null)   // Should print 2


Try changing this:
VDTRead2 /O=2 /T="\n"  output

to this:
Variable number
VDTRead2 /O=2 /T=","  number    // Read first number
Print number
VDTRead2 /O=2 /T="\r"  number  // Read second number
Print number
VDTRead2 /O=2 /N=1 null  // Read LF
Print "Finished"


Other long shots...

Try restarting your machine. I have seen that fix a lot of strange problems.

Try a different serial adapter. I had success with one Prolific adapter - see http://www.igorexchange.com/node/6708#comment-12059. But I have a vague recollection that different Prolific adapters use different chipsets, and we have seen issues with some serial chipsets. Also, update your Prolific driver.
Ok, short version is that it is now working and thank you very much for your help!

The long version is that it seemed to be a driver issue. None of the other suggestions worked, so I uninstalled the driver and re-installed the latest one from Prolific. I have no idea at all why it may be that the driver works perfectly for RealTerm (and with some old C++ code we had lying around) but not with Igor. But that, it seems, was the answer.

For the record I was previously using a driver version 3.3.2.102 dated 24/09/2008 and this did not work. The new driver is version 3.6.81.357 dated 04/09/2015 and both were provided by Prolific. I hope this information may be of help if anyone ever has a similar problem.

Thanks again,
Liam