Friday, October 06, 2006

The Spy Among Us -- Debugging I/O

Have you used NI Spy? It's one of our software tools for helping you see and understand the messages sent to instruments. It's especially useful for seeing the low-level SCPI commands sent to Serial, GPIB, or LAN instruments...

NI-Spy Log

It's useful for debugging, optimizing, or just learning more about instrumentation.

NI Spy only works when using NI Software. For example, you'll only see VISA calls if you use NI-VISA, and you'll only see GPIB calls if you use NI-488.2. (Spy also works for NI's Modular Instrument drivers, NI-CAN, NI-DeviceNet, NI's IVI Class Drivers, and maybe some other drivers I'm forgetting.)

I want to be clear that Spy is not a hardware bus analyzer. We sell a GPIB Bus Analyzer for really low-level debugging, but most users can get by with NI Spy.

I find NI Spy especially useful when I run into problems with an instrument driver. If I have a LabVIEW source code driver, I can sometimes go into it and figure out what we're sending to the instrument. But the strings we send to instruments aren't usually constants; usually some part of the string is computed. If I want to know what we really sent to the instrument, NI Spy can show me. Obviously, if you don't have LabVIEW source code to look through, NI Spy may be your only choice.

For example, I have a C-based driver for talking to the Agilent 34401A DMM. It works fine with this DMM. My problems started when I used a different instrument that could pretend to be the Agilent 34401A. There was actually a bug in the C driver that caused it to send an invalid command. The real 34401A didn't care, but the emulation mode of this second instrument failed.

With NI Spy, I can see the actual SCPI command sent to the instrument...

Here I can see that we're sending ":CONF:VOLT AUTO,DEF". If I go look at the official 34401A command reference, I see that the syntax is supposed to be ":CONF:VOLT DEF,DEF". The "AUTO" is wrong.

I had the C source code to the driver, so I tried to find the mistake in the source. It wasn't entirely obvious. Searching for "VOLT" or "AUTO,DEF" doesn't work. Here's the snippet of code that's wrong...

        /*  Configure the measurement  */
if (autorange == VI_ON)
Fmt (wrtBuf, "%s<:CONF:%s AUTO,%s\r\n", funcStr[func], resolStr[resol]);

Without NI Spy, it would have taken me even longer to solve the problem.

By the way, I reported the problem to both the provider of the C driver, as well as to the provider of the instrument emulator.

Finally, I want to highlight a few features we added in LabVIEW 8...

  • NI Spy was ported to Linux and Mac. (It was originally written in MFC for Windows. The Spy team rewrote it in LabVIEW to port it to these other platforms.)
  • The logged calls make more sense for LabVIEW users. Before LabVIEW 8, you only saw the NI-488.2 or NI-VISA C-language calls. Here's the log from a simple write followed by a read...

    While this gives you some insight into how LabVIEW calls NI-VISA under the hood, it's not always easy to map this to your block diagram. Note that I hid six hundred calls to viWaitOnEvent as we waited for the I/O to complete. So in LabVIEW 8, the output looks like this...

    This is from a slightly different driver, but you see the idea. The function names match your diagram, and you don't have to look at the C-language calls.
  • In LabVIEW 8.2, we did the same sort of simplification for the GPIB functions in LabVIEW. You see functions such as "GPIB Read", not "ibrda".

There are a lot of other features of NI Spy that I won't go into here. You can track instrument calls from multiple threads and processes. You can see timestamps to help debug tricky timing situations. It's an indispensable tool for users and developers of instrument drivers.

1 comment:

Anonymous said...

Hi Brian,
Thanks for an awesome post. I didn't notice the new features in NI-Spy for LV 8.0/8.2 before this post. Thanks for the information.