在现代的电子测试领域,远程控制仪器进行测量是一种常见的需求。这不仅可以提高工作效率,还可以实现自动化测试。本文将介绍如何通过局域网(LAN)远程控制电子测试仪器,并开发相应的仪器驱动程序。
要实现远程控制,首先需要将仪器与计算机连接。常见的连接方式包括GPIB、USB、Ethernet、LXI、LAN和串行端口。通过这些接口,可以设置测量条件、获取测量结果并记录数据以供后续分析。
市面上有许多厂商,如National Instruments、Agilent、Rohde Schwarz、Keithley、Tektronix等,提供了丰富的仪器控制硬件和软件工具,以帮助用户节省时间和成本,提高性能和可靠性。这些工具包括用于GPIB、USB、Ethernet、LXI、LAN和串行端口的总线硬件,以及如NI LabVIEW、Agilent VEE、Visual Studio C#和预制仪器驱动程序等软件工具。
虽然市面上的仪器驱动程序可以满足许多标准需求,但有时需要进行特定的应用和测量,这就需要自己开发仪器驱动程序。通过直接I/O命令(即测试仪器的用户/程序员手册中提供的命令集),可以解决自定义驱动程序的需求。
本文将以Agilent N9010A为例,介绍如何使用C#通过LAN远程控制桌面电子测试仪器。
通过仪器控制,可以利用计算机连接到桌面仪器并进行测量。控制仪器的方式有很多种,可以使用仪器驱动程序,也可以通过直接I/O命令进行控制。
本教程将介绍如何通过LAN与仪器通信。将与IP地址为192.168.1.47、端口号为5025的Agilent N9010A进行通信。
为了实现这一目标,需要使用Visual Studio 2010创建一个新的Windows项目。然后,需要设计用户界面(UI),包括以下控件及其相关属性:
控件 | 名称 | 文本 |
---|---|---|
Windows.Forms.MainForm | N9010A通信通过LAN | - |
Windows.Forms.Button | btnConnect | &连接 |
Windows.Forms.TextBox | tbSAPort | 5025 |
Windows.Forms.TextBox | tbSAAddress | 192.168.1.47 |
Windows.Forms.Label | lblIDN | 由N9010A的*IDN?查询填充文本 |
Windows.Forms.Label | labelControl1 | SA IP: |
Windows.Forms.Label | labelControl2 | SA端口: |
Windows.Forms.Label | labelControl3 | IDN: |
Windows.Forms.ToolStripMenuItem | tsmiFile | 文件 |
Windows.Forms.ToolStripMenuItem | tsmiExit | 退出 |
在名为N9010A的类中,将编写N9010A通信基础设施。writeLine(string command)方法向仪器发送一个命令,并附加"\n"。这个"\n"字符被称为EOL,表示命令的结束。readLine方法读取仪器对远程命令的响应,并将其作为ASCII字符串返回。
using System;
using System.Text;
using System.Net.Sockets;
using System.Net;
namespace N90101A
{
public class N9010A
{
private string IpAddr;
private int PortNumber;
private IPEndPoint ip = null;
public IPEndPoint Ip
{
get
{
if (ip == null)
ip = new IPEndPoint(IPAddress.Parse(this.IpAddr), this.PortNumber);
return ip;
}
set { ip = value; }
}
public N9010A(string instrIPAddress, int instrPortNo)
{
this.IpAddr = instrIPAddress;
this.PortNumber = instrPortNo;
if (!Soket.Connected)
throw new ApplicationException("Instrument at " + this.Ip.Address + ":" + this.Ip.Port + " is not connected");
}
public void writeLine(string command)
{
Soket.Send(Encoding.ASCII.GetBytes(command + "\n"));
}
public string readLine()
{
byte[] data = new byte[1024];
int receivedDataLength = Soket.Receive(data);
return Encoding.ASCII.GetString(data, 0, receivedDataLength);
}
private Socket soket = null;
public Socket Soket
{
get
{
if (soket == null)
{
soket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
if (!soket.Connected)
soket.Connect(this.Ip);
}
catch (SocketException e)
{
Console.WriteLine("Unable to connect to server.");
throw new ApplicationException("Instrument at " + this.Ip.Address + ":" + this.Ip.Port + " is not connected");
}
}
return soket;
}
set { soket = value; }
}
}
}
接下来,将设计一个表单,以便与仪器N9010A通信。表单上使用的控件如表1所示。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace N90101A
{
public partial class MainForm : Form
{
private N9010A sa;
public MainForm()
{
InitializeComponent();
}
private void btnSAConnect_Click(object sender, EventArgs e)
{
this.saBaglan(this.tbSAAddress.Text, this.tbSAPort.Text);
}
private void saBaglan(string saAddress, string saPort)
{
try
{
sa = new N9010A(saAddress, int.Parse(saPort));
sa.writeLine("*IDN?");
this.lblIDN.Text = sa.readLine();
}
catch (ApplicationException ex)
{
Console.WriteLine(ex.ToString());
}
}
}
}
从频谱分析仪获取的IDN响应如下:
现在是时候改进N9010A类了,通过添加更多的方法。可以将N9010A类扩展为.dll,通过创建新的类库项目。
public void saRbwVbwSweTime(double rbw, double vbw, byte swe)
{
writeLine("BAND " + rbw + " MHZ");
writeLine("BAND:VID " + vbw + " MHZ");
writeLine("SWE:TIME:AUTO " + (swe == 0 ? "OFF" : "ON"));
}
public void readMarker1Peak(out double SAFreqOut, out double SAAmpOut)
{
writeLine(":CALC:MARK1:STAT ON");
writeLine(":CALC:MARK1:MAX");
writeLine(":CALC:MARK1:X?");
SAFreqOut = double.Parse(readDouble()) / 1E6;
writeLine(":CALC:MARK1:Y?");
SAAmpOut = double.Parse(readLine());
}