QT+R&SVisa控制LXI仪器

1.下载并安装visa

R&S®VISA - Rohde & Schwarz China

2.安装后的目录说明

安装了64位visa会默认把32位的安装上;

64位库和头文件目录为:C:\Program Files\IVI Foundation

32位库和头文件目录为:C:\Program Files (x86)\IVI Foundation

以64位为例:

lib:【用Visa32.lib和RsVisa32.lib都可以】

h:【包含visa.h即可】

dll:

3.QT的pro

复制代码
QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++17
DEFINES += RSVISA_EXTENSION  #如果需要查找设备需要把这个宏打开
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    MainWindow.cpp

HEADERS += \
    MainWindow.h

FORMS += \
    MainWindow.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target



contains(QT_ARCH, i386){
    message("32-bit")
    INCLUDEPATH += $$PWD/rsvisa/x32/include
    LIBS += -L$$PWD/rsvisa/x32/lib/ -lRsVisa32
}else{
    message("64-bit")
    INCLUDEPATH += $$PWD/rsvisa/x64/include
    LIBS += -L$$PWD/rsvisa/x64/lib/ -lRsVisa32
}

注意:如果需要查找设备需要把这个宏:RSVISA_EXTENSION打开

4.MainWindow.h

复制代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "visa.h"

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();


public slots:
    void setDevices(QStringList items);
    void setStatus(const QString& msg);

    void setPortSource(int port);
    void setPortBoth(int port);
    void setPortAll(int port);
    void setPortNone(int port);

private:
    //初始化
    void init();

    // 发送数据
    void writeData(QString data);

    // 读取数据
    void readData(QByteArray& data);

private slots:
    void on_pushButton_find_clicked();

    void on_pushButton_open_clicked();

private:
    Ui::MainWindow *ui;

    ViSession m_defRM     = -1;
    ViSession m_vi        = -1;
};
#endif // MAINWINDOW_H

5.MainWindow.cpp

复制代码
#include "MainWindow.h"
#include "ui_MainWindow.h"
#include <QDebug>
#include <thread>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    (void)init();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::setDevices(QStringList items)
{
    if(!items.isEmpty())
    {
        ui->comboBox_devices->clear();
        ui->comboBox_devices->addItems(items);
    }
}

void MainWindow::setStatus(const QString &msg)
{
    ui->statusbar->showMessage(msg);
}

void MainWindow::setPortSource(int port)
{
    //[1] 使端口可以与VNA源连接
    QString cmd = QString(":PORT%1:FUNCtion %2").arg(port).arg("SOURce");
    writeData(cmd);
}

void MainWindow::setPortBoth(int port)
{
    //[1] 使端口测量路可以与VNA测量接收机连接
    QString cmd = QString(":PORT%1:FUNCtion %2").arg(port).arg("MEASure");
    writeData(cmd);

    //[2] 使端口参考路可以与VNA参考接收机连接
    cmd = QString(":PORT%1:FUNCtion %2").arg(port).arg("REFerence");
    writeData(cmd);
}

void MainWindow::setPortAll(int port)
{
    //[1] 使端口源、测量路、参考路可以与VNA的源和接收机连接
    QString cmd = QString(":PORT%1:FUNCtion %2").arg(port).arg("ALL");
    writeData(cmd);
}

void MainWindow::setPortNone(int port)
{
    //[1] 使端口测量路可以与VNA测量接收机连接
    QString cmd = QString(":PORT%1:FUNCtion %2").arg(port).arg("NONE");
    writeData(cmd);
}

void MainWindow::init()
{
    //[1] visa设备管理器初始化
    if(VI_SUCCESS != viOpenDefaultRM(&m_defRM))
    {
        setStatus("open rm failed");
    }
    else
    {
        setStatus("open rm success");
    }

    //[2] 2x16物理端口按钮点击初始化
    auto btnList1 = ui->groupBox->findChildren<QPushButton*>();     //group1
    for (const auto btn : btnList1)
    {
        QObject::connect(btn, &QPushButton::clicked, this, [this, btn](){
            setPortAll(btn->text().toInt());
        });
    }
    auto btnList2 = ui->groupBox_2->findChildren<QPushButton*>();   //group2
    for (const auto btn : btnList2)
    {
        QObject::connect(btn, &QPushButton::clicked, this, [this, btn](){
            setPortAll(btn->text().toInt());
        });
    }

    //[3] 4x8物理端口按钮点击初始化
    auto btnList3 = ui->groupBox_3->findChildren<QPushButton*>();   //group1
    for (const auto btn : btnList3)
    {
        QObject::connect(btn, &QPushButton::clicked, this, [this, btn](){
            setPortAll(btn->text().toInt());
        });
    }
    auto btnList4 = ui->groupBox_4->findChildren<QPushButton*>();   //group2
    for (const auto btn : btnList4)
    {
        QObject::connect(btn, &QPushButton::clicked, this, [this, btn](){
            setPortAll(btn->text().toInt());
        });
    }
    auto btnList5 = ui->groupBox_5->findChildren<QPushButton*>();   //group3
    for (const auto btn : btnList5)
    {
        QObject::connect(btn, &QPushButton::clicked, this, [this, btn](){
            setPortAll(btn->text().toInt());
        });
    }
    auto btnList6 = ui->groupBox_6->findChildren<QPushButton*>();   //group4
    for (const auto btn : btnList6)
    {
        QObject::connect(btn, &QPushButton::clicked, this, [this, btn](){
            setPortAll(btn->text().toInt());
        });
    }
}

void MainWindow::writeData(QString data)
{
    do
    {
        //[1] 资源管理器判断
        if(m_defRM <= 0)
        {
            setStatus("m_defRM is null");
            break;
        }

        //[2] 设备判断
        if(m_vi <= 0)
        {
            setStatus("writeData m_vi is null");
            break;
        }

        //[3] 确保以回车结束
        if(!data.endsWith("\n"))
        {
            data = data + "\n";
        }

        //[4] 写数据
        if(VI_SUCCESS != viPrintf(m_vi, data.toStdString().data()))
        {
            setStatus("writeData failed");
            break;
        }
        else
        {
            ui->textEdit->append("write:"+data);
        }
    }while(0);
}

void MainWindow::readData(QByteArray &data)
{
    do
    {
        //[1] 资源管理器判断
        if(m_defRM <= 0)
        {
            setStatus("m_defRM is null");
            break;
        }

        //[2] 设备判断
        if(m_vi <= 0)
        {
            setStatus("m_vi is null");
            break;
        }

        //[3] 读数据
        int bufLeng = 1024*4;
        unsigned char buf[1024*4];
        long unsigned int retcount;
        if(VI_SUCCESS != viRead(m_vi, buf, bufLeng, &retcount))
        {
            setStatus("readData failed");
            break;
        }

        data = QByteArray::fromRawData((char*)buf, retcount);
    }while(0);
}

void MainWindow::on_pushButton_open_clicked()
{
    do
    {
        if("打开"==ui->pushButton_open->text())
        {
            setStatus("open devices");
            QString deviceName = ui->comboBox_devices->currentText();

            //[1] 资源管理器判断
            if(m_defRM <= 0)
            {
                setStatus("m_defRM is null");
                break;
            }

            //[2] 设备恢复
            if(m_vi > 0)
            {
                viClose(m_vi);
                m_vi = -1;
            }

            //[3] 打开设备
            int timeout = 20000;
            auto ret = viOpen(m_defRM, deviceName.toStdString().data(), 0, timeout, &m_vi);
            if(VI_SUCCESS != ret)
            {
                setStatus("viOpen failed");
                break;
            }
            ui->pushButton_open->setText("已打开");

            //[4] 设置属性
            viSetAttribute(m_vi, VI_ATTR_TMO_VALUE, timeout);//设置读写超时
        }
        else
        {
            setStatus("close devices");
            auto ret = viClose(m_vi);
            if(VI_SUCCESS != ret)
            {
                setStatus("viClose failed");
                break;
            }
            else
            {
                ui->pushButton_open->setText("打开");
                setStatus("viClose success");
            }
        }
    }while(0);
}

void MainWindow::on_pushButton_find_clicked()
{
    setStatus("find devices");
    auto findDeivesFun = [this](){
        QStringList rsrcList;
        do
        {
            //[1] 资源管理器判断
            if(m_defRM <= 0)
            {
                setStatus("m_defRM is null");
                break;
            }

            //[2] 设置查找属性
            ViAttrState searchAttributes = VI_RS_FIND_MODE_CONFIG | VI_RS_FIND_MODE_VXI11 | VI_RS_FIND_MODE_MDNS;
            auto ret = viSetAttribute(m_defRM, VI_RS_ATTR_TCPIP_FIND_RSRC_MODE, searchAttributes);
            if(VI_SUCCESS != ret)
            {
                setStatus("viSetAttribute failed");
                break;
            }

            //[3] 查找设备
            ViUInt32 retCnt;
            ViChar desc[256];
            ret = viFindRsrc(m_defRM, "?*", &m_vi, &retCnt, desc);
            if(VI_SUCCESS != ret)
            {
                setStatus("viFindRsrc failed");
                break;
            }
            rsrcList.push_back(desc);

            for (ViInt16 i = 0; i < static_cast<ViInt16>(retCnt)-1; ++i)
            {
                if(VI_SUCCESS == viFindNext(m_vi, desc))
                {
                    rsrcList.push_back(QString(desc));
                }
            }
        }while(0);

        //[4] 如果查找到了VXI设备,则增加一个通过SOCKET控制它的方式
        QStringList socketItems;
        for(auto item : rsrcList)
        {
            if(-1 != item.indexOf("inst0") && -1 != item.indexOf("INSTR"))
            {
                auto newItem = item.replace("inst0", "5025");
                newItem = newItem.replace("INSTR", "SOCKET");
                socketItems.append(newItem);
            }
        }
        rsrcList.append(socketItems);

        QMetaObject::invokeMethod(this, "setDevices", Qt::QueuedConnection, Q_ARG(QStringList, rsrcList));
    };

    std::thread t(findDeivesFun);
    t.detach();
}
相关推荐
用户805533698034 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner4 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz9 天前
QML Hello World 入门示例
qt
xcyxiner12 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner13 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner13 天前
DicomViewer (添加模型类)3
qt
xcyxiner14 天前
DicomViewer (目录调整) 2
qt
xcyxiner14 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
LDR00616 天前
Type-C 快充全面升级!LDR6601 赋能个人护理便携电机,重塑剃须刀 / 理发器新体验
c语言·开发语言
雪碧聊技术16 天前
Tree.js是什么?一文讲透
开发语言·javascript·ecmascript