QT+RSVisa控制LXI仪器

news2025/5/22 22:26:53

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();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2383422.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

springboot3+vue3融合项目实战-大事件文章管理系统-文章分类也表查询(条件分页)

在pojo实体类中增加pagebean实体类 Data NoArgsConstructor AllArgsConstructor public class PageBean <T>{private Long total;//总条数private List<T> items;//当前页数据集合 }articlecontroller增加代码 GetMappingpublic Result<PageBean<Article&g…

Canvas进阶篇:鼠标交互动画

Canvas进阶篇&#xff1a;鼠标交互动画 前言获取鼠标坐标鼠标事件点击事件监听代码示例效果预览 拖动事件监听代码示例效果预览 结语 前言 在上一篇文章Canvas进阶篇&#xff1a;基本动画详解 中&#xff0c;我们讲述了在Canvas中实现动画的基本步骤和动画的绘制方法。本文将进…

【Node.js】Web开发框架

个人主页&#xff1a;Guiat 归属专栏&#xff1a;node.js 文章目录 1. Node.js Web框架概述1.1 Web框架的作用1.2 Node.js主要Web框架生态1.3 框架选择考虑因素 2. Express.js2.1 Express.js概述2.2 基本用法2.2.1 安装Express2.2.2 创建基本服务器 2.3 路由2.4 中间件2.5 请求…

使用Vite创建一个动态网页的前端项目

1. 引言 虽然现在的前端更新换代的速度很快&#xff0c;IDE和工具一批批的换&#xff0c;但是我们始终要理解一点基本的程序构建的思维&#xff0c;这些环境和工具都是为了帮助我们更快的发布程序。笔者还记得以前写前端代码的时候&#xff0c;只使用文本编辑器&#xff0c;然…

系统架构设计师案例分析题——web篇

软考高项系统架构设计师&#xff0c;其中的科二案例分析题为5选3&#xff0c;总分75达到45分即合格。本贴来归纳web设计题目中常见的知识点即细节&#xff1a; 目录 一.核心知识 1.常见英文名词 2.私有云 3.面向对象三模型 4.计网相关——TCP和UDP的差异 5.MQTT和AMQP协…

MySQL--day5--多表查询

&#xff08;以下内容全部来自上述课程&#xff09; 多表查询 1. 为什么要用多表查询 # 如果不用多表查询 #查询员工名为Abel的人在哪个城市工作? SELECT* FROM employees WHERE last_name Abel;SELECT * FROM departments WHERE department_id 80;SELECT * FROM locati…

leetcode hot100刷题日记——7.最大子数组和

class Solution { public:int maxSubArray(vector<int>& nums) {//方法一&#xff1a;动态规划//dp[i]表示以i下标结尾的数组的最大子数组和//那么在i0时&#xff0c;dp[0]nums[0]//之后要考虑的就是我们要不要把下一个数加进来&#xff0c;如果下一个数加进来会使结…

基于Spring Boot和Vue的在线考试系统架构设计与实现(源码+论文+部署讲解等)

源码项目获取联系 请文末卡片dd我获取更详细的演示视频 系统介绍 基于Spring Boot和Vue的在线考试系统。为学生和教师/管理员提供一个高效、便捷的在线学习、考试及管理平台。系统采用前后端分离的架构&#xff0c;后端基于成熟稳定的Spring Boot框架&#xff0c;负责数据处理…

Android 绘制折线图

用了一段时间的 Jetpack Compose ,感觉写 UI 的效率确实会提升不少 。 配合 AI 编程绘制了一个折线图。供大家学习参考! @Composable fun TemperatureChart() {val timeLabels = listOf("7:00", "8:00", "9:00", "10:00", "11:…

自建srs实时视频服务器支持RTMP推流和拉流

文章目录 一、整体示意图二、服务器端1.srs简介及架构2.docker方式安装3.k8s方式安装4.端口 三、推流端1.OBS Studio2.ffmpeg推流3.streamlabs苹果手机4.twire安卓手机5.网络推流摄像头 四、拉流端1.vlc2.srs 参考awesome系列&#xff1a;https://github.com/juancarlospaco/aw…

Spring IOCDI————(2)

DI详解 我们之前讲了控制反转IOC&#xff0c;也就是bean的存&#xff0c;那么我们还需要Bean的取&#xff0c;就是DI了&#xff0c;DI翻译过来就是依赖注入&#xff0c;啥意思呢&#xff0c;就是我们通过IOC容器&#xff0c;把所有的对象交给Spring管理&#xff0c;我们指定哪…

融云 uni-app IMKit 上线,1 天集成,多端畅行

融云 uni-app IMKit 正式上线&#xff0c;支持一套代码同时运行在 iOS、Android、H5、小程序主流四端&#xff0c;集成仅需 1 天&#xff0c;并可确保多平台的一致性体验。 融云 uni-app IMKit 在 Vue 3 的高性能加持下开发实现&#xff0c;使用 Vue 3 Composition API&#x…

篇章五 项目创建

目录 1.创建一个SpringBoot项目 2.创建核心类 2.1 Exchange类 2.2 MessageQueue类 2.3 Binding类 2.4 Message类 1.Message的组成 2.逻辑删除 3.工厂方法 4.序列化与反序列化 5.offsetBeg和offsetEnd 1.创建一个SpringBoot项目 1.点击 2.填写表单 3.添加依赖 2.创建…

aws平台s3存储桶夸域问题处理

当我们收到开发反馈s3存在跨域问题 解决步骤&#xff1a; 配置 S3 存储桶的 CORS 设置&#xff1a; 登录到 AWS 管理控制台。转到 S3 服务。选择你存储文件的 存储桶。点击 权限 标签页。在 跨域资源共享&#xff08;CORS&#xff09;配置 部分&#xff0c;点击 编辑。 登陆…

【vue-text-highlight】在vue2的使用教程

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、下载二、使用步骤1.引入库2.用法 效果速通 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 例如&#xff1a;随着人工智能的不断发…

pycharm无法正常调试问题

pycharm无法正常调试问题 1.错误代码 已连接到 pydev 调试器(内部版本号 231.8109.197)Traceback (most recent call last):File "E:\Python\pycharm\PyCharm 2023.1\plugins\python\helpers\pydev\_pydevd_bundle\pydevd_comm.py", line 304, in _on_runr r.deco…

Leetcode百题斩-哈希

看来面试前还是要老老实实刷leetcode为好&#xff0c;今天看到一个题库&#xff0c;leetcode百题斩&#xff0c;刚好最近面试的这两题全在里面。瞄了一眼&#xff0c;也有不少题之前居然也刷过。那么&#xff0c;冲冲冲&#xff0c;看多久能把这百题刷完。 第一天&#xff0c;先…

EXIST与JOIN连表比较

结论 1&#xff1a;EXIST可以用于链表&#xff0c;且可以利用到索引2&#xff1a;当join无法合理利用到索引&#xff0c;可以尝试EXIST链表3&#xff1a;EXIST在某些情况下可以更好地利用到索引4&#xff1a;大数据量时&#xff0c;要考虑EXIST的使用 EXIST SQL: EXPLAN JOIN…

【Linux】利用多路转接epoll机制、ET模式,基于Reactor设计模式实现

&#x1f4da; 博主的专栏 &#x1f427; Linux | &#x1f5a5;️ C | &#x1f4ca; 数据结构 | &#x1f4a1;C 算法 | &#x1f152; C 语言 | &#x1f310; 计算机网络 上篇文章&#xff1a;多路转接epoll&#xff0c;实现echoserver 至此&#xff0c;Linux与…

react中运行 npm run dev 报错,提示vite.config.js出现错误 @esbuild/win32-x64

在React项目中运行npm run dev时&#xff0c;如果遇到vite.config.js报错&#xff0c;提示esbuild/win32-x64在另一个平台中被使用&#xff0c;通常是由于依赖冲突或缓存问题导致的。解决方法是删除node_modules文件夹&#xff0c;并重新安装依赖。 如下图&#xff1a; 解决办…