浏览目录
前言
最近在项目中多次需要使用上位机软件通过网口对安捷伦电源进行远程控制,使用频率比较高,所以写下此文以便自己日后遗忘时查询。也给遇到同样问题的朋友,提供些许帮助。本文仅对安捷伦电源进行简单的远程操控、数据读取。
一、 环境设置
上位机与安捷伦电源的通信环境本例中用的是NI-VISA
版本是:NI-VISA 18.5
可以直接百度 NI-VISA 在NI官网中下载
链接提供:NI-VISA官网下载链接
必须安装NI-VISA的环境 才能与电源正常通讯(有一次电源数据读不到,排查了半天的代码问题,才想起来是新电脑没有装环境,,“血”的教训)
按默认路径安装后,可以在
C:\Users\Public\Documents\National Instruments\NI-VISA\Examples.NET\17.5\SimpleReadWrite
中找到官方给出的范例代码。
在范例中也能找到在官方提供的两个dll:
Ivi.Visa.dll
NationalInstruments.Visa.dll
顺便提供下上述所有材料连接
链接:https://pan.baidu.com/s/1_mUQ018RBIrPnqJUDaKgAQ
提取码:9sl0
二、 与电源交流的语言
与电源交流使用的是SCPI。
SCPI作为仪器程控命令,实现对仪器的控制,使得不同测试仪器的相同功能具有相同的命令形式,同时,SCPI使用相同的命令可以控制同一类仪器中的相同功能。
在测试中,要控制数字源表的执行使其实现特定的功能,可以向仪器输入如下的命令:
三、 开始程控电源
1. 寻找我们需要的电源
当不知道被控制电源的IP配置信息时,是可以主动寻找与当前本机链接的所有电源。并获取电源的 资源名称
using (var rmSession = new ResourceManager())
{
Log = "寻找电源组件中...";
//按链接类型来寻找电源组件
var resources = rmSession.Find("(ASRL|GPIB|TCPIP|USB)?*");
//此时resources是一个 字符串数组,每个字符串分别对应一个电源名
if (resources.Count() > 0)
{
//检测到有电源存在并得到电源资源名称
foreach (var s in resources)
{
ResourceName = s;
}
}
else
{
//未检测到有电源存在,退出测试
MessageBox.Show("未检测到有电源,退出测试");
}
}
获取了电源的 资源名称 也就意味着获得了打开电源的钥匙。
2. 先有连接,才能控制
得到电源的资源名称,就可以调用Open方法,按资源名称连接至电源。
private ResourceManager _rmSession;
private MessageBasedSession mbSession;
public void DyTest()
{
using (_rmSession = new ResourceManager())
{
//寻找电源组件
var resources = _rmSession.Find("(ASRL|GPIB|TCPIP|USB)?*");
if (resources.Count() > 0)
{
//检测到有电源存在并得到电源资源名称
foreach (var s in resources)
{
//按资源名称进入测试流程
Init(s);
}
}
else
{
//未检测到有电源存在,退出测试
MessageBox.Show("未检测到有电源,退出测试");
}
}
}
public void Init(string resourcename)
{
mbSession = (MessageBasedSession)_rmSession.Open(resourcename);
}
在已知电源的IP配置的情况下 ,也可以直接跳过寻找电源,直接通过资源名称来连接电源,如果需要连接至其他电源,只需修改 IP 即可.
private ResourceManager _rmSession;
private MessageBasedSession mbSession;
public void DyTest()
{
using (_rmSession = new ResourceManager())
{
string ip = "192.168.0.200";
//按资源名称进入测试流程
Init("TCPIP0::" + ip + "::inst0::INSTR");
}
}
public void Init(string resourcename)
{
mbSession = (MessageBasedSession)_rmSession.Open(resourcename);
}
记住现在这个 mbSession ,现在它就是我们需要的电源。
有了连接,才能控制。
3. 设置电压、电流,输出电源
记住!现在mbSession就是我们的电源。
所谓的控制,就是把指令符写到电源中,电源会根据收到的指令进行不同的操作。
按所设置的电压与电流,输出电源。
1) 设置电压
double Voltage = 28.5; //输入电压28.5V
int Channel = 1; // 输出通道 1
SetVolt(Voltage,Channel);
public void SetVolt(double volt, int channel = 1)
{
string voltstr = volt.ToString();
mbSession.RawIO.Write($"SOUR:VOLT:LEV:IMM:AMPL {voltstr},(@{channel})\n");
}
电源有时候有多个通道,不同的通道可以输出不同的电压电流。在写入指令时,设置电压电流也要区分通道。
2) 设置电流
double Current= 2; //输入电压2A
int Channel = 2; // 输出通道 2
SetCurr(Current,Channel);
internal void SetCurr(double curr,int channel = 1)
{
string currstr = curr.ToString();
mbSession.RawIO.Write($":SOUR:CURR:LEV:IMM:AMPL {currstr},(@{channel})");
}
3) 按设置输出、停止输出
string Channel = 1 ;
PowerOn(Channel); //电源按设置输出
internal void PowerOn(int channel = 1)
{
// 电源按设置输出
mbSession.RawIO.Write($":OUTP:STAT ON,(@{channel})\n");
}
4) 读取电流、电压
internal float ReadCURR(int channel =1)
{
//读取电流
string RESULT = null;
Application.Current.Dispatcher.Invoke(new Action(() =>
{
mbSession.RawIO.Write($":MEAS:SCAL:CURR? (@{channel})\n");
RESULT = mbSession.RawIO.ReadString(); //获得当前电流数值
}));
return Convert.ToSingle(RESULT);
}
internal float ReadVolt(int channel = 1)
{
float result = 0;
Application.Current.Dispatcher.Invoke(new Action(() =>
{
mbSession.RawIO.Write($":MEAS:SCAL:VOLT? (@{channel})");
string result_str = mbSession.RawIO.ReadString();
result = Convert.ToSingle(result_str);
}));
return result;
}
在正常使用中Application.Current.Dispatcher.Invoke() 不是必须的。
在两个方法中使用Application.Current.Dispatcher.Invoke() 是因为在项目中该方法被异步线程调用,不声明主线程,会出现线程调用错误。
5) 设置电流浮动范围
double CurrRange = 0.01 ; // 电流浮动范围为10mA
SetCurrRange(CurrRange);
internal void SetCurrRange(double currRange,int channel = 1)
{
mbSession.RawIO.Write($":SOUR:CURR:RANG {currRange}");
}
4. 关闭电源输出
string Channel = 1 ;
PowerOFF(Channel);//电源停止输出
public void PowerOFF(int channel = 1)
{
// 电源停止输出
mbSession.RawIO.Write($":OUTP:STAT OFF,(@{channel})\n");
}
四、 代码范例
public void DyTest()
{
using (_rmSession = new ResourceManager())
{
//寻找电源组件
var resources = _rmSession.Find("(ASRL|GPIB|TCPIP|USB)?*");
if (resources.Count() > 0)
{
//检测到有电源存在并得到电源资源名称
foreach (var s in resources)
{
int channel = 1;
//按资源名称进入测试流程
Init(s);
//设置电压、电流
double curr = 2;
double volt = 20;
SetCurr(2, channel);//设置当前 电流2A
SetVolt(volt, channel);// 这只当前 电压20V
//设置电流范围
SetCurrRange(0.01, channel);//电流范围10mA
//电源输出
PowerOn();
//读取电压
double now_volt = ReadVolt();
MessageBox.Show($"当前电压为{now_volt}");
double now_curr = ReadCURR();
MessageBox.Show($"当前电流为{now_curr}");
PowerOFF();
}
}
else
{
//未检测到有电源存在,退出测试
MessageBox.Show("未检测到有电源,退出测试");
}
}
}