Qt 使用Visa库与数字仪器仪表TCP/IP通信(SCPI指令自动化测试)
标准数字仪器仪表可通过 GPIB, RS232, USB, LAN接口等与上位机数据通信和控制。如示波器、数字万用表、频率计、台式电源等。通过SCPI协议(字符串形式)与设备通信,串口,USB等接口可以直接用字符串通信,但是LAN通信不同于一般TCP/UDP用ip和端口通信,需要用Visa协议栈通信。Qt开发时只需要把visa动态库和头文件导入即可。
以普源的数字万用表DM3068为例,使用LAN口通信:
根据官方编程文档,通信协议如下:查询当前测量直流电压值发送字符串“:MEASure:VOLTage:DC?”
1.获取visa.lib,可以安装 NI-MAX,毕竟调试也需要, 安装 NI-VISA
2.安装完成后可以去安装目录下拷贝lib库到Qt目录下,需要的文件有:
2.1 C:\Program Files (x86)\IVI Foundation\VISA\WinNT\Include\visa.h和visatype.h
2.2 C:\Program Files (x86)\IVI Foundation\VISA\WinNT\Lib_x64\msc\visa64.lib
2.3 拷贝到Qt目录下
2.4 Qt添加动态库和visa.h头文件
3.现在可以使用了,但是通信需要知道仪器的Ip地址字符串,可以使用安装的NI-MAX查看。打开MAX,连接网线,添加设备,添加仪器IP地址,
完成后会显示仪器名称,
把这个复制到Qt 测试程序: 发送测量当前输入的8V电压值.
static ViSession defaultRM;
static ViSession instr;
static ViUInt32 retCount;
static ViUInt32 writeCount;
static ViStatus status;
static unsigned char buffer[100];
static char stringinput[512];
#define DM3068IPSTR "TCPIP0::192.168.1.30::inst0::INSTR"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//串口检测线程
spThread = new SerialPortThread();
connect(spThread,&SerialPortThread::reflashSerialPort, this,&MainWindow::showSerialPort);
spThread->start();
status = viOpenDefaultRM(&defaultRM);
if (status < VI_SUCCESS)
{
qDebug() << "Could not open a session to the VISA Resource Manager!\n";
}
status = viOpen(defaultRM, DM3068IPSTR, VI_NULL, VI_NULL, &instr);
if (status < VI_SUCCESS)
{
qDebug() << "Cannot open a session to the device.\n";
goto Close;
}
/* Set the timeout to 5 seconds (5000 milliseconds). */
status = viSetAttribute(instr, VI_ATTR_TMO_VALUE, 5000);
/* Set the baud rate to 4800 (default is 9600). */
status = viSetAttribute(instr, VI_ATTR_ASRL_BAUD, 4800);
/* Set the number of data bits contained in each frame (from 5 to 8).
* The data bits for each frame are located in the low-order bits of
* every byte stored in memory.
*/
status = viSetAttribute(instr, VI_ATTR_ASRL_DATA_BITS, 8);
status = viSetAttribute(instr, VI_ATTR_ASRL_PARITY, VI_ASRL_PAR_NONE);
status = viSetAttribute(instr, VI_ATTR_ASRL_STOP_BITS, VI_ASRL_STOP_ONE);
status = viSetAttribute(instr, VI_ATTR_TERMCHAR_EN, VI_TRUE);
/* Set the termination character to 0xA
*/
status = viSetAttribute(instr, VI_ATTR_TERMCHAR, 0xA);
strcpy(stringinput, ":MEASure:VOLTage:DC?\n");
//strcpy(stringinput, "*IDN?\n");
status = viWrite(instr, (ViBuf)stringinput, (ViUInt32)strlen(stringinput), &writeCount);
if (status < VI_SUCCESS){
qDebug() << "Error writing to the device.\n";
goto Close;
}
status = viRead(instr, buffer, 100, &retCount);
if (status < VI_SUCCESS){
qDebug() << "Error reading a response from the device.\n";
}else{
qDebug() << "Data read:" << retCount << QString::fromLocal8Bit((char*)buffer,retCount);
ui->textBrowser->setText(QString::fromLocal8Bit((char*)buffer,retCount));
}
Close:
status = viClose(instr);
status = viClose(defaultRM);
}
结果如下:
也可以用NI-MAX调试,
版权声明:本文为wy212670原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。