目录
一、写作说明
二、常用两种库对比
1. 库对比分析表格
2. 常用方法说明
三、代码实现示例
1.NI-VISA 封装类
2.Ivi.VISA 封装类
3.主函数调用
四、两种库适用范围总结
一、写作说明
刚入行时很疑惑,一门编程语言是如何和仪器实现通信的。在上篇文章《射频测试入门学习(三)——程控仪器是怎样和电脑连接通信的》中已经详细说明控制仪器的电脑必备条件。本文通过实际举例介绍C#是如何控制仪器并与之通信的。
二、常用两种库对比
1. 库对比分析表格
特性 |
NI-VISA |
Ivi.VISA |
依赖 |
需安装 NI-VISA Runtime(商业授权) |
无需 NI 依赖,通过 NuGet 直接安装(如 Ivi.Visa 包),但需底层 VISA 驱动(如 Keysight IO 套件) |
跨平台支持 |
支持 Windows/Linux(需对应版本) |
跨平台兼容性更好(支持 .NET Core/Standard) |
接口支持 |
GPIB、USB、LAN、Serial 等(需硬件支持) |
类似 NI-VISA,但依赖底层驱动 |
性能 |
高(专为仪器通信优化) |
中等(托管实现,略低于原生库) |
开发便捷性 |
需 NI 软件环境,文档完善 |
轻量级集成(NuGet),代码更简洁 |
适用场景 |
需稳定性和高性能的场景(如产线测试) |
跨平台开发、快速原型设计或避免商业依赖 |
2. 常用方法说明
操作 |
NI-VISA 方法 |
Ivi.VISA 方法 |
连接仪器 |
ResourceManager.Open() |
ResourceManager.Open() |
发送指令 |
MessageBasedSession.RawIO.Write() |
IMessageBasedSession.RawIO.Write() |
读取响应 |
MessageBasedSession.RawIO.ReadString() |
IMessageBasedSession.RawIO.ReadString() |
断开连接 |
MessageBasedSession.Dispose() |
IMessageBasedSession.Dispose() |
三、代码实现示例
1.NI-VISA 封装类
using NationalInstruments.Visa;
using System;
public class PowerSupply_NIVisa {
private MessageBasedSession _session;
public void Connect(string visaAddress) {
var rm = new ResourceManager();
_session = (MessageBasedSession)rm.Open(visaAddress);
}
public void Disconnect() {
_session?.Dispose();
}
public string Query(string command) {
_session.RawIO.Write(command);
return _session.RawIO.ReadString().Trim();
}
public void SetVoltage(double voltage, int channel) {
_session.RawIO.Write($"INST:NSEL {channel}");
_session.RawIO.Write($"VOLT {voltage}");
}
public void SetCurrent(double current, int channel) {
_session.RawIO.Write($"INST:NSEL {channel}");
_session.RawIO.Write($"CURR {current}");
}
public void OutputOn() {
_session.RawIO.Write("OUTP:STAT ON");
}
public void OutputOff() {
_session.RawIO.Write("OUTP:STAT OFF");
}
public double MeasureVoltage(int channel) {
_session.RawIO.Write($"INST:NSEL {channel}");
return double.Parse(_session.RawIO.ReadString());
}
public double MeasureCurrent(int channel) {
_session.RawIO.Write($"INST:NSEL {channel}");
return double.Parse(_session.RawIO.ReadString());
}
}
2.Ivi.VISA 封装类
using Ivi.Visa;
using System;
public class PowerSupply_IviVisa {
private IMessageBasedSession _session;
public void Connect(string visaAddress) {
var rm = new ResourceManager();
_session = rm.Open(visaAddress) as IMessageBasedSession;
}
public void Disconnect() {
_session?.Dispose();
}
public string Query(string command) {
_session.RawIO.Write(command);
return _session.RawIO.ReadString().Trim();
}
public void SetVoltage(double voltage, int channel) {
_session.RawIO.Write($"INST:NSEL {channel}");
_session.RawIO.Write($"VOLT {voltage}");
}
public void SetCurrent(double current, int channel) {
_session.RawIO.Write($"INST:NSEL {channel}");
_session.RawIO.Write($"CURR {current}");
}
public void OutputOn() {
_session.RawIO.Write("OUTP:STAT ON");
}
public void OutputOff() {
_session.RawIO.Write("OUTP:STAT OFF");
}
public double MeasureVoltage(int channel) {
_session.RawIO.Write($"INST:NSEL {channel}");
return double.Parse(_session.RawIO.ReadString());
}
public double MeasureCurrent(int channel) {
_session.RawIO.Write($"INST:NSEL {channel}");
return double.Parse(_session.RawIO.ReadString());
}
}
3.主函数调用
class Program {
static void Main() {
string visaAddress = "TCPIP0::192.168.1.101::inst0::INSTR";
// 使用 NI-VISA
var niPs = new PowerSupply_NIVisa();
niPs.Connect(visaAddress);
Console.WriteLine("IDN: " + niPs.Query("*IDN?"));
niPs.SetVoltage(12.0, 1);
niPs.SetCurrent(1.0, 1);
niPs.OutputOn();
Console.WriteLine("Measured Voltage: " + niPs.MeasureVoltage(1));
niPs.Disconnect();
// 使用 Ivi.VISA
var iviPs = new PowerSupply_IviVisa();
iviPs.Connect(visaAddress);
Console.WriteLine("IDN: " + iviPs.Query("*IDN?"));
iviPs.SetVoltage(5.0, 2);
iviPs.SetCurrent(0.5, 2);
iviPs.OutputOn();
Console.WriteLine("Measured Current: " + iviPs.MeasureCurrent(2));
iviPs.Disconnect();
}
}
四、两种库适用范围总结
库 |
推荐场景 |
NI-VISA |
需要高性能、稳定性的环境(如产线测试),且允许安装 NI 商业软件。 |
Ivi.VISA |
跨平台开发、快速原型设计,或需避免依赖 NI 的商业授权(依赖底层 VISA 驱动)。 |