C# 如何等待服务请求(RQS)
**注:在LabVIEW论坛上交叉发布: 我正试图编写一个简单的C#(.NET 4.0)程序,通过VISA GPIB控制Keithley 2400 SMU,但我很难让程序等待Keithley在扫描结束时发送的服务请求 扫描是一种简单的线性电压扫描,由Keithley装置内部控制。我已将装置设置为在扫描结束或达到合规性时发送ServiceRequest信号 我能够将命令发送到SMU并读取数据缓冲区,但前提是我手动输入扫描开始命令和读取数据命令之间的超时 我遇到的一个问题是,我对C#还是个新手——我正在使用这个项目(移植我的LV代码的一部分)来学习它 以下是迄今为止我的C#代码: 以上所有内容都应模拟此LabVIEW代码: 你知道我哪里出了问题吗 谢谢 编辑: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#还是个新手——我
经过进一步的修改,我发现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 callDispose
。谢谢@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();