65.9K
CodeProject 正在变化。 阅读更多。
Home

通过 LAN 远程控制仪器

starIconstarIconstarIconstarIconstarIcon

5.00/5 (5投票s)

2011年12月26日

CPOL

3分钟阅读

viewsIcon

62036

downloadIcon

2941

通过 LAN 远程控制测试仪器的分步说明

引言

远程控制桌面测试仪器包括:使用 GPIB、USB、以太网、LXI、局域网和串口将仪器物理连接到计算机;通过仪器的命令集设置测量条件;获取测量结果;并记录测量结果以供进一步分析。

一些供应商(例如 National Instruments、Agilent、Rohde Schwarz、Keithley、Tektronix...)提供了大量的仪器控制硬件和软件工具,以帮助您在仪器控制系统的整个生命周期中节省时间和金钱。通过用于 GPIB、USB、以太网、LXI、LAN 和串行的总线硬件提高性能和可靠性,同时利用诸如 NI LabVIEW、Agilent VEE、Visual Studio C# 和预制仪器驱动程序等软件工具提高生产力。

使用现成的仪器驱动程序可能不符合我们的需求,因为我们需要供应商永远无法知道的自定义应用程序和测量。因此,使用直接 I/O 命令(测试仪器的用户/程序员手册中提供的命令集)开发仪器驱动程序,解决了自定义驱动程序的需求。本文解释了如何使用 C# 通过 LAN 逐步远程控制桌面电子测试仪器(在本例中为 Agilent N9010A)。

背景

通过仪器控制,可以使用计算机连接到桌面仪器并进行测量。有几种不同的方式来控制您的仪器 – 您可以使用仪器驱动程序或通过直接 I/O 命令控制仪器(参见图 1)。

instrumentDriverArchitecture.png

图 1。

开始 

在本教程中,我们将通过 局域网 与仪器通信。 我们通信的仪器是 Agilent N9010A,IP 地址为 192.168.1.47,端口号为 5025。(参见图 2)

UIDesign.png

图 2. N9010A 局域网 通信用户界面

为了完成这项工作,我们需要使用 Visual Studio 2010 创建一个新的 Windows 项目,因此单击“文件”->“新建项目”。 然后为项目指定名称和位置(参见图 3)

N9010ANewProject-300x207.png

图 3. N9010A 项目设置

创建 VS C#.NET 项目后,我们开始设计用户界面 (UI)。 我们的 UI 由以下控件和相关属性组成:

表 1. 仪器控制表单

Control  名称 文本
Windows.Forms MainForm N9010A 通过 局域网 通信
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 方法读取仪器对 writeLine(string command) 发送的远程命令的响应,并以 ASCII 字符串形式返回。

using System;
using System.Text;
using System.Net.Sockets;
using System.Net;

namespace N90101A
{
    // N9010A Spectrumm Analyzer Class
    public class N9010A
    {
        //N9010A IP Address
        private string IpAddr;
        //N9010A Port number
        private int PortNumber;
        //a network endpoint as an IP address and a port number
        private IPEndPoint ip = null;
        //IPEndPoint property for N9010A
        public IPEndPoint Ip
        {
            get
            {
                if (ip == null)
                    ip = new IPEndPoint(IPAddress.Parse(this.IpAddr), this.PortNumber);
                return ip;
            }
            set { ip = value; }
        }
        //N9010A Spectrum Analyzer Constructor
        //instrIPAddress:N9010A IP Address,ex:"192.168.001.047"
        //instrPortNo:N9010A Port Number, ex:5025
        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");
        }

        //Writes an remote command to an N9010A with "\n"
        public void writeLine(string command)
        {
            Soket.Send(Encoding.ASCII.GetBytes(command + "\n"));
        }
        //Reads the N9010A response as string to a command sent with writeLine method
        public string readLine()
        {
            byte[] data = new byte[1024];
            int receivedDataLength = Soket.Receive(data);
            return Encoding.ASCII.GetString(data, 0, receivedDataLength);
        }

        Socket soket = null;

        //TCPIP connection to a N9010A
        public Socket Soket
        {
            get
            {
                if (soket == null)
                {
                    soket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    try
                    {
                        if (!soket.Connected)
                            soket.Connect(this.Ip);
                    }
                    //Throw an exception if not connected
                    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 中给出。

MainForm 类的代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;

namespace N90101A
{
    public partial class MainForm : Form
    {
        private N9010A sa;
        public MainForm()
        {
            
            InitializeComponent();
        }
        //When invoked, the Instrument is connected and instrument handle is created
        private void btnSAConnect_Click(object sender, EventArgs e)
        {
            this.saBaglan(this.tbSAAddress.Text, this.tbSAPort.Text);
        }
        //Sends a command "*IDN?" to an instrument whose IP Address is saAddress Port Number is saPort, reads the response from N9010A and update the User Interface
        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 响应如下:

SpectrumAnalyzerIdnResponse.png

改进 N9010A 类

现在是时候通过添加更多方法来改进 N9010A 类了。可以通过创建新的类库项目将 N9010A 类扩展到 .dll

        
        // Adjusts the N9010A's RBW, VBW and Sweep Time
        // RBW in MHz
        // VBW in MHz
        // Sweep Auto 0-->OFF, 1-->ON
        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"));
        }

//Read the Marker Peak values and return the marker1 frequency to SAFreqOut, amplitude value to SAAmpOut
public void readMarker1Peak(out double SAFreqOut, out double SAAmpOut)
        {
            writeLine(":CALC:MARK1:STAT ON");
            writeLine(":CALC:MARK1:MAX");//Do a peak search
            writeLine(":CALC:MARK1:X?");//Query the marker peak value
            SAFreqOut = double.Parse(readDouble())/1E6;//in MHz
            writeLine(":CALC:MARK1:Y?");
            SAAmpOut = double.Parse(readLine());
        }

结论 

在本教程中,我解释了如何通过 LAN 远程控制电子测试仪器,以及如何在没有 VISA 库和仪器供应商设备驱动程序(dll、驱动程序文件...)的情况下开发仪器驱动程序。 要扩展 N9010A 类,可以编写并向类添加更多方法,并为仪器开发自定义驱动程序。 更多文章请访问 http://www.miltest.com/

频谱分析仪、网络分析仪、EMI 接收器、万用表、信号发生器的仪器驱动程序也可提供,并且可以设计自定义驱动程序。 如有其他问题,请与我联系 

© . All rights reserved.