C# 如何等待服务请求(RQS)

C# 如何等待服务请求(RQS),c#,labview,visa,gpib,C#,Labview,Visa,Gpib,**注:在LabVIEW论坛上交叉发布: 我正试图编写一个简单的C#(.NET 4.0)程序,通过VISA GPIB控制Keithley 2400 SMU,但我很难让程序等待Keithley在扫描结束时发送的服务请求 扫描是一种简单的线性电压扫描,由Keithley装置内部控制。我已将装置设置为在扫描结束或达到合规性时发送ServiceRequest信号 我能够将命令发送到SMU并读取数据缓冲区,但前提是我手动输入扫描开始命令和读取数据命令之间的超时 我遇到的一个问题是,我对C#还是个新手——我

**注:在LabVIEW论坛上交叉发布:

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

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

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

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

以下是迄今为止我的C#代码:

以上所有内容都应模拟此LabVIEW代码:

你知道我哪里出了问题吗

谢谢

编辑:
经过进一步的修改,我发现Service Request上的Service Request函数实际上是在正确的时间启动的(“Service Request Received!”被打印到控制台上)。

我认为您所做的是正确的,所以NI库可能有问题

我能想到的唯一一件事是等待“所有事件”,而不仅仅是“ServiceRequest”。如下所示:

mbSession.WaitOnEvent(MessageBasedSessionEventType.AllEnabledEvents, timeout);
注意:看起来您不能“启用”所有事件(所以不要更改该部分)

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

        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); 
            }
        }
int timeout=10000;
int-cycleewait=1000;
对于(int i=0;i

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

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

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();

如果可能的话,我想尽量避免轮询,但感谢您提供的信息。我会将其用作备用。我编辑了这篇文章,提供了有关服务请求的更多信息:服务请求处理程序在正确的时间被调用,因此我可能可以使用它来继续该程序。我已经编辑了您的标题。请参阅“”,其中有共识“不,他们不应该"。谢谢@JohnSaunders,对此表示抱歉。欢迎使用C#。大多数会话方法,包括
Write
,都可能导致异常,中断执行流。因此,您应该将对
Dispose
的调用放在
finally
块中。这是.NET中的常见模式,C#具有try finally just to call
Dispose
。谢谢@TomBlodget。当我完成代码时,我会将大部分内容放在try…catch…finally块中。我主要是一名Python开发人员,习惯于将大部分内容放在这些块中:-)。我没有把它们包括在这篇文章中,这样事情就更容易阅读了。但是关于使用
语句的
的好信息,我不知道。
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();