C#通过NI-VISA操作Tektronix TBS 2000B系列示波器
一、概述
本文描述采用C#语言访问控制Tektronix TBS 2000B 系列示波器。接口协议采用NI-VISA。
最近一个项目需要和一款示波器进行通信,需要对示波器进行一些简单控制并获取到波形数据。经过一段时间研究,大致了解了相关操作,因为发现相关资料不是很多,所以把我了解的相关知识和大家分享一下。文末将提供本文涉及的相关文档、代码、安装程序的下载地址。
正常情况下,我们如果需要和一个设备进行通信,首先需要知道PC通过什么方式和设备进行连接,通信协议是什么。由于工作需要和很多设备进行过连接,常用的连接方式主要有:网络连接、串口连接、USB接口连接等;通信协议都是自定义的协议文本。 本来以为这个项目首先得需要搞清楚示波器的通信协议,然后才能进行下一步开发,在官方网站下载了一些编程资料,发现该设备是可以通过VISA进行连接的,那什么是VISA呢?VISA是由National Instruments公司牵头,联合一些设备制造厂商共同指定的一个通用设备连接标准,不管设备通过何种方式进行连接,只要符合VISA规范就可以通过该标准协议进行连接,而NI-VISA就是NI公司实现的一个协议,通过这个协议接口,我们不用直接和设备进行通信,只需要通过NI-VISA提供的接口就可以访问设备,而常用的接口非常简单,主要就是OPEN、WRITE、READ等几个命令。符合规范的设备都会公开一份SCPI指令集的文档,只要仔细阅读该文档就可以实现设备的控制。在整个项目过程中,我仅仅通过几个官方网站下载的文档就完成项目开发,几乎没有什么障碍,在此不得不感慨我们的制造业和发达国家相比确实有很大差距,我们就缺少这样标准性的东西,什么事情都得从底层做起,很不科学。要是那些巨头们肯做一些这方面的工作就太好了,比做什么买菜、卖鱼的APP有意义得多了。
二、连接
示波器通过网络接口和PC进行连接

配置示波器IP和PC在同一个网段,例如:192.168.11.11,在设置时注意IP内不要有0,然后在PC上先ping一下,看能否ping通。

如果能ping通就在浏览器输入http://192.168.11.11看能否打开示波器主页,确认SCPI指令可以运行。

三、安装驱动
运行NI-VISA Runtime安装程序,选中运行时基础包和.NET支持包。

.NET支持包选.NET 4.0-4.5.1 Runtime Support(IVI),不选.NET XX Runtime Support(NS),NS的包是老版本。
安装完成后形成两个包:Ivi.Visa和NationalInstruments.Visa
其中Ivi.Visa有两个版本:
32位位置:C:\Program Files (x86)\IVI Foundation\VISA\Microsoft.NET\Framework32\v2.0.50727\VISA.NET Shared Components 5.8.0
64位位置:C:\Program Files\IVI Foundation\VISA\Microsoft.NET\Framework64\v2.0.50727\VISA.NET Shared Components 5.8.0
NationalInstruments.Visa位置:C:\Windows\Microsoft.NET\assembly\GAC_MSIL\NationalInstruments.Visa\v4.0_17.0.0.0__2eaa5af0834e221d
四、引用
新建VS工程,按上述地址添加Ivi.Visa和NationalInstruments.Visa两个引用。Ivi.Visa的库根据需要可以选32位或64位。
程序运行需要在目标机器安装运行时,所以引用的库不需要复制到项目文件夹。

五、代码
已经有网友把VISA接口得调用进行了封装,我直接使用了相关代码,几乎一字未改,相关代码请查阅:https://www.cnblogs.com/cncc/p/7866899.html
连接代码:

string IP = this.txtIP.Text.Trim();
string IpRegex = @"^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$";
if (!Regex.IsMatch(IP, IpRegex))
{
MessageBox.Show("IP地址不正确!");
return;
}
if (!PortUltility.OpenIPAddress(IP, out string fullAddress))
{
MessageBox.Show("未找到设备!");
return;
}
try
{
_portOperatorBase = new LANPortOperator(fullAddress);
}
catch (Exception ex)
{
MessageBox.Show($"初始化设备失败:{ex.Message}");
return;
}
try
{
_portOperatorBase.Timeout = 2000;
_portOperatorBase.Open();
}
catch (Exception ex)
{
MessageBox.Show($"连接设备失败:{ex.Message}");
return;
}
EnabledControls(true);
MessageBox.Show("连接成功!");
写指令一共有两种,一种不需要返回数据、一种需要返回数据,下发了需要返回数据的指令后才能进行读取指令,否则就会读取失败。
读写指令如下:

private void btnWrite_Click(object sender, EventArgs e)
{
string CmdStr = this.txtCommand.Text.Trim(); try
{
_portOperatorBase.WriteLine(CmdStr);
ShowLog($"[Write][{CmdStr}][Success]");
}
catch
{
ShowLog($"[Write][{CmdStr}][ERROR]");
}
} private void btnReadString_Click(object sender, EventArgs e)
{
try
{
var result = _portOperatorBase.Read();
ShowLog($"[Read][{result}][{result.Length}]");
}
catch (IOTimeoutException)
{
ShowLog($"[Read][ERROR:Timeout]");
}
catch (Exception ex)
{
ShowLog($"[Read][Exception:{ex.Message}]");
}
}
核心代码就这么多,剩下的就根据需要查询SCPI指令表就可以了。
附录、相关SCPI指令
以下指令仅适用于Tektronix TBS 2000B系列示波器。

(一) 基本指令
1. 身份
WRITE:*IDN? READ: (二) 设置
1. 默认设置
RECAll:SETUp FACtory 2. 通道控制
Select:CH<x> ON/OFF 3. 水平位置与比例
HORizontal:POSition? HORizontal:POSition 10 HORizontal:SCAle? 400 单位是秒 HORizontal:SCAle 0.2 4. 垂直位置与比例
CH1:POSition? CH1:POSition 1 CH1:SCAle? CH1:SCAle 2.5 5. 触发
模式 TRIGger:A:MODe? NORMAL 触发类型 TRIGger:A:TYPe? EDGE 触发源 TRIGger:A:EDGE:SOUrce CH1 耦合: TRIGger:A:EDGE:COUPling g {DC|HFRej|LFRej|NOISErej} 斜率 TRIGger:A:EDGE:SLOpe {RISe|FALL} 触发电平(当前) TRIGger:A:LEVel? 2.0800 TRIGger:A:LEVel 3.5 触发电平(指定通道) TRIGger:A:LEVel:CH1? 2.0800 TRIGger:A:LEVel :CH1 3.5 (三) 控制
1. 设置/查询工作类型
ACQuire:STOPAfter SEQuence ACQuire:STOPAfter RUNSTOP 查询:ACQuire:STOPAfter? 返回最后一次设置的工作类型 2. 设置/查询运行状态
ACQuire:STATE? 0:Run或Single 1:Stop 设置:ACQuire:STATE ON/OFF 3. 查询触发状态
TRIGger:STATE? READY:等待触发 SAVE:已经触发 (四) 读取数据
1. 设置数据来源(通道)
DATA:SOURCE CH1 2. 设置/读取记录宽度
HORizontal:RECOrdlength? 2000 3. 读取波形数据宽度(仅读取,触发完成后有效)
WFMOutpre:RECOrdlength? 2000 4. 设置传输数据窗口
DATa:STARt 1 最小为1 DATa:STOP 2000 DATa:WIDth? 单个数据宽度(字节数)默认为1,可以修改为2字节,但高位始终为0 5. 数据读取
CURVe? Read(Bytes):返回指定长度的字节数据【LENGTH= N+(STOP-STARt+1)+1】 数据为:帧头(N字节)+数据(STOP-STARt+1字节)+帧尾(1字节)。 帧头为:#(1字节)+数据长度的长度(1字节)+数据长度(1~9字节) 帧尾为:\n 数据每个字节表示一个波形高度值,采用补码方式,即第一个位表示符号,范围从-128~127
相关文档、代码下载:https://gitee.com/seabluescn/tksamples.git
C#通过NI-VISA操作Tektronix TBS 2000B系列示波器的更多相关文章
- DocX开源WORD操作组件的学习系列四
DocX学习系列 DocX开源WORD操作组件的学习系列一 : http://www.cnblogs.com/zhaojiedi1992/p/zhaojiedi_sharp_001_docx1.htm ...
- DocX开源WORD操作组件的学习系列三
DocX学习系列 DocX开源WORD操作组件的学习系列一 : http://www.cnblogs.com/zhaojiedi1992/p/zhaojiedi_sharp_001_docx1.htm ...
- DocX开源WORD操作组件的学习系列二
DocX学习系列 DocX开源WORD操作组件的学习系列一 : http://www.cnblogs.com/zhaojiedi1992/p/zhaojiedi_sharp_001_docx1.htm ...
- DocX开源WORD操作组件的学习系列一
DocX学习系列 DocX开源WORD操作组件的学习系列一 : http://www.cnblogs.com/zhaojiedi1992/p/zhaojiedi_sharp_001_docx1.htm ...
- C#操作Excel开发报表系列整理(转)
C#操作Excel进行报表开发系列共写了七篇,也已经有很久没有新东西了,现在整理一下,方便以后查阅,如果有写新的,会同时更新.需要注意的是因为Office的版本不同,实际的代码可能会有所不同,但是都是 ...
- Django models ORM基础操作--白话聊Django系列
上次我们讲完了views视图,那我们这次来看一下Django强大的ORM,可以这么说,你不懂Django的ORM,你就不懂Django,那废话不多说 ORM又称关系对象映射,在ORM里,一张表就是一个 ...
- 标题 发布状态 评论数 阅读数 操作 操作 CNN目标检测系列算法发展脉络简析——学习笔记(三):Fast R-CNN
最近两周忙着上网课.投简历,博客没什么时间写,姑且把之前做的笔记放上来把... 下面是我之前看论文时记的笔记,之间copy上来了,内容是Fast R-CNN的,以后如果抽不出时间写博客,就放笔记上来( ...
- C#操作Excel开发报表系列整理
C#操作Excel进行报表开发系列共写了八篇,也已经有很久没有新东西了,现在整理一下,方便以后查阅,如果有写新的,会同时更新.需要注意的是因为Office的版本不同,实际的代码可能会有所不同,但是都是 ...
- NI MAX中缺少串口(转)
Software Measurement & Automation Explorer (MAX) Driver NI-VISA 问题详述 在NI MAX中,设备和接口中的串口不可用或缺 ...
随机推荐
- vue-cli快速创建项目,可视化创建
之前学习了交互式创建,发现过程无聊,而且不方便,后面又学习了图形可视化创建,下面进行分享 1.打开cmd 2.输入vue ui,输入后会出现如下 C:\Users\12235>vue ui St ...
- OpenSSL 常见对称加密算法特性分析
在选择加密算法,面对一大长串的选项时,大家都有这样的疑问,究竟哪种加密方式是最好的呢? 对于加密方式.算法来说,一般安全性与性能呈负相关,越是安全的,对性能要求则更高. 现在主流的加密协议的安全性均能 ...
- 选出ip记录表最近的10行数据
w select * from wip where id>(select (select max(id)from wip)-10) ;
- (Sql Server)存储过程(转载)
SQL Server 存储过程 Transact-SQL中的存储过程,非常类似于Java语言中的方法,它可以重复调用.当存储过程执行一次后,可以将语句缓存中,这样下次执行的时候直接使用缓存中的语句.这 ...
- 解决windows git乱码问题
在windows中打开git bash git config --global i18n.commitencoding utf-8 设置提交日志使用utf-8 git config --g ...
- C++ Primer Plus读书笔记(十)对象和类
1.类 不废话,上定义 class ClassName { public: xxx; private: xxx; protected: xxx; } private部分数据只能通过public 提供的 ...
- Python中,单引号,双引号,三引号的使用区别与原因
先说1双引号与3个双引号的区别,双引号所表示的字符串通常要写成一行如:s1 = "hello,world"如果要写成多行,那么就要使用/ ("连行符")吧,如s ...
- loj10170
在 n×n 的棋盘上放 k 个国王,国王可攻击相邻的 8 个格子,求使它们无法互相攻击的方案总数. -------------------------------------------------- ...
- (十八)整合Nacos组件,环境搭建和入门案例详解
整合Nacos组件,环境搭建和入门案例详解 1.Nacos基础简介 1.1 关键特性 1.2 专业术语解释 1.3 Nacos生态圈 2.SpringBoot整合Nacos 2.1 新建配置 2.2 ...
- Web漏洞扫描-Burp Suite
Web漏洞扫描-Burp Suite 一.Burp Suite概述 二.功能及特点 三.Burp Suite安装 四.Burp Suite使用 一.Burp Suite概述 安全渗透界使用最广泛的漏扫 ...