3

**注:交叉发布在 LabVIEW 论坛:http ://forums.ni.com/t5/LabVIEW/C-VISA-wait-on-RQS/td-p/3122939

我正在尝试编写一个简单的 C# (.NET 4.0) 程序来通过 VISA GPIB 控制 Keithley 2400 SMU,但我无法让程序等待 Keithley 在扫描结束时发送的服务请求.

扫描是简单的线性电压扫描,由 Keithley 设备内部控制。我已将设备设置为在扫描结束时或达到合规性时发送 ServiceRequest 信号。

我能够将命令发送到 SMU 并读取数据缓冲区,但前提是我在扫描开始命令和读取数据命令之间手动输入超时。

我遇到的一个问题是我对 C# 很陌生——我正在使用这个项目(移植我的 LV 代码的一部分)来学习它。

这是我到目前为止的 C# 代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using NationalInstruments.VisaNS;

private void OnServiceRequest(object sender, MessageBasedSessionEventArgs e)
{
    Console.WriteLine("Service Request Received!");
}

// The following code is in a class method, but
public double[,] RunSweep()
{
    // Create the session and message-based session
    MessageBasedSession mbSession = null;
    Session mySession = null;
    string responseString = null;

    // open the address
    Console.WriteLine("Sending Commands to Instrument");
    instrAddr = "GPIB0::25::INSTR";
    mySession = ResourceManager.GetLocalManager().Open(instrAddr);

    // Cast to message-based session
    mbSession = (MessageBasedSession)mySession;

    // Here's where things get iffy for me... Enabling the event and whatnot
    mbSession.ServiceRequest += new MessageBasedSessionEventHandler(OnServiceRequest);
    MessageBasedSessionEventType srq = MessageBasedSessionEventType.ServiceRequest;
    mbSession.EnableEvent(srq, EventMechanism.Handler);

    // Start the sweep (SMU was set up earlier)
    Console.WriteLine("Starting Sweep");
    mbSession.Write(":OUTP ON;:INIT");

    int timeout = 10000;             // milliseconds
    // Thread.Sleep(10000);          // using this line works fine, but it means the test always takes 10s even if compliance is hit early

    // This raises error saying that the event is not enabled.
    mbSession.WaitOnEvent(srq, timeout);

    // Turn off the SMU.
    Console.WriteLine("I hope the sweep is done, cause I'm tired of waiting");
    mbSession.Write(":OUTP OFF;:TRAC:FEED:CONT NEV");

    // Get the data 
    string data = mbSession.Query(":TRAC:DATA?");

    // Close session
    mbSession.Dispose();

    // For now, create a dummy array, 3x3, to return. The array after is the starting value.
    double[,] dummyArray = new double[3, 3] {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};

    return dummyArray;
}

以上所有内容都应该模仿这个LabVIEW代码: 简单的吉时利扫描

那么,关于我要去哪里错的任何想法?

谢谢,

编辑:

经过一番折腾,我发现服务请求函数OnServiceRequest实际上是在正确的时间触发的(“服务请求已收到!”打印到控制台)。

4

2 回答 2

2

事实证明,我需要将事件启用为队列而不是处理程序。这一行:

mbSession.EnableEvent(srq, EventMechanism.Handler);

实际上应该是:

mbSession.EnableEvent(srq, EventMechanism.Queue);

资料来源:“备注”下的文档。在上面找到文档很痛苦……NI需要让它更容易:-(。

有了这个改变,我也不需要创建MessageBasedSessionEventHandler.

最终的工作代码如下所示:

rm = ResourceManager.GetLocalManager().Open("GPIB0::25::INSTR");
MessageBasedSession mbSession = (MessageBasedSession)rm;
MessageBasedSessionEventType srq = MessageBasedSessionEventType.ServiceRequest;
mbSession.EnableEvent(srq, EventMechanism.Queue);    // Note QUEUE, not HANDLER
int timeout = 10000;

// Start the sweep
mbSession.Write(":OUTP ON;:INIT");

// This waits for the Service Request
mbSession.WaitOnEvent(srq, timeout);

// After the Service Request, turn off the SMUs and get the data
mbSession.Write(":OUTP OFF;:TRAC:FEED:CONT NEV");
string data = mbSession.Query(":TRAC:DATA?");
mbSession.Dispose();
于 2015-04-22T16:51:18.507 回答
1

您所做的对我来说看起来是正确的,因此 NI 库可能存在问题。

我能想到的唯一尝试是等待“所有事件”,而不仅仅是“服务请求”。像这样:

mbSession.WaitOnEvent(MessageBasedSessionEventType.AllEnabledEvents, timeout);

注意:看起来你不能“启用”所有事件(所以不要改变那部分)。

我还寻找了一些其他人如何进行 Keithley 扫描的示例,我发现了这个这个(Matlab ex)。正如我在两者中所怀疑的那样,他们不使用事件来确定扫描何时完成,而是使用“不断轮询 Keithley 的 while 循环”(第一个链接实际上使用线程,但它是相同的想法)。这让我觉得这也许是你最好的选择。所以你可以这样做:

        int timeout = 10000;
        int cycleWait = 1000;

        for (int i = 0; i < timeout / cycleWait; i++)
        {
            try
            {
                string data = mbSession.Query(":TRAC:DATA?");
                break;
            }
            catch
            {
                Thread.Sleep(cycleWait); 
            }
        }

(您可能还必须检查数据是否为空,但必须有某种方式知道扫描何时完成)。

于 2015-04-22T14:56:28.917 回答