QT实现固高运动控制卡示波器

这篇具有很好参考价值的文章主要介绍了QT实现固高运动控制卡示波器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、固高示波器

二、基于QCustomPlot实现示波器

三、完整源码


一、固高示波器

        固高运动控制卡自带的软件有一个示波器功能,可以实时显示速度的波形,可辅助分析电机的运行状态。但是我们基于sdk开发了自己的软件,无法再使用该功能,原因是2个软件不能同时与控制卡通信,故此需要我们自己再开发一个示波器。

固高示波器功能展示,功能包括多条曲线的显示、继续/暂停、左移、右移、设置、轴选择等。

QT实现固高运动控制卡示波器

二、基于QCustomPlot实现示波器

GCustomPlot简介与使用看官网就可以了

简介, Qt Plotting Widget QCustomPlot - Introduction

下载, Qt Plotting Widget QCustomPlot - Download

需要注意的是需要在pro文件中加入printsuppot模块,源码中使用该模块做pdf打印功能

QT       += printsupport

 参考固高的功能实现速度示波器效果如下

QT实现固高运动控制卡示波器

 QCustomPlot初始化设置

    m_customPlot = new QCustomPlot(this);
    m_customPlot->setObjectName(QLatin1String("customPlot"));
    ui->vlyPlot->addWidget(m_customPlot);

    m_customPlot->setBackground(QBrush(QColor("#474848")));
    m_customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom |
                                  QCP::iSelectPlottables);  /* 可拖拽+可滚轮缩放 */
    m_customPlot->legend->setVisible(true);

添加两条曲线图,addGraph

    m_customPlot->addGraph();
    m_customPlot->graph(0)->setPen(QPen(Qt::green, 3));
    m_customPlot->graph(0)->setName(QStringLiteral("实际速度"));

    m_customPlot->addGraph();
    m_customPlot->graph(1)->setPen(QPen(Qt::yellow, 3));
    m_customPlot->graph(1)->setName(QStringLiteral("规划速度"));

 左右移动,通过设置X轴的范围来改变,再使用replot函数更新视图

m_customPlot->xAxis->setRange(m_customPlot->xAxis->range().lower - ui->spbStep->value(),
                                      m_customPlot->xAxis->range().upper - ui->spbStep->value());
        m_customPlot->replot();

网格线显示与隐藏

        m_customPlot->xAxis->grid()->setVisible(checked);
        m_customPlot->yAxis->grid()->setVisible(checked);
        m_customPlot->replot();

添加数据,示波器有向左自动滚动的效果,也是通过设置范围来实现

void OscilloscopeFrame::addData(double key, double actVel, double prfVel)
{
    m_customPlot->graph(0)->addData(key, actVel);
    m_customPlot->graph(1)->addData(key, prfVel);

    m_customPlot->xAxis->rescale();
    m_customPlot->graph(0)->rescaleValueAxis(false, true);
    m_customPlot->graph(1)->rescaleValueAxis(false, true);

    m_customPlot->xAxis->setRange(m_customPlot->xAxis->range().upper,
                                  m_fixedLength, Qt::AlignRight);
    m_customPlot->replot(QCustomPlot::rpQueuedReplot);  /* 实现重绘 */
}

实时显示数据,通过定时器实现

    m_timer = new QTimer();
    connect(m_timer, &QTimer::timeout, updateData);
    m_timer->start(OSCILLOSCOPE_UPDATE_MSEC);

鼠标放在曲线上显示当前值,关联鼠标移动信号,映射坐标pixelToCoord

    connect(m_customPlot, SIGNAL(mouseMove(QMouseEvent *)), this,
            SLOT(plotMouseMoveEvent(QMouseEvent *)));
void OscilloscopeFrame::plotMouseMoveEvent(QMouseEvent *event)
{
    if ( Qt::ControlModifier == event->modifiers())
    {
        int x_pos = event->pos().x();
        int x_val = m_customPlot->xAxis->pixelToCoord(x_pos);
        float y = m_customPlot->graph(0)->data()->at(x_val)->value;
        QString strToolTip = QString("%1,%2").arg(x_val).arg(y);
        QToolTip::showText(cursor().pos(), strToolTip, m_customPlot);
    }
}

三、完整源码

OscilloscopeFrame.h

#ifndef OSCILLOSCOPEFRAME_H
#define OSCILLOSCOPEFRAME_H

#include <QFrame>
#include "oscilloscopelib_global.h"

namespace Ui
{
    class OscilloscopeFrame;
}

class QCustomPlot;

class AbstractRobot;

class OSCILLOSCOPELIBSHARED_EXPORT OscilloscopeFrame : public QFrame
{
    Q_OBJECT

public:
    explicit OscilloscopeFrame(QWidget *parent = 0);
    ~OscilloscopeFrame();
    void setFixedLength(double length);
    void addData(double key, double actVel, double prfVel);
    void installController(AbstractRobot *controller);

private slots:
    void plotMouseMoveEvent(QMouseEvent *event);

private:
    Ui::OscilloscopeFrame *ui;
    QCustomPlot *m_customPlot = nullptr;
    QTimer *m_timer = nullptr;
    double m_fixedLength;
    AbstractRobot *m_controller = nullptr;
    double m_actPos = 0;
    double m_count = 0;
};

#endif // OSCILLOSCOPEFRAME_H

OscilloscopeFrame.cpp文章来源地址https://www.toymoban.com/news/detail-444483.html

#include "OscilloscopeFrame.h"
#include "qcustomplot.h"
#include "ui_OscilloscopeFrame.h"
#include <QtMath>
#include <QDebug>
#include <device/AbstractRobot.h>

#define OSCILLOSCOPE_UPDATE_MSEC  60

OscilloscopeFrame::OscilloscopeFrame(QWidget *parent) :
    QFrame(parent),
    ui(new Ui::OscilloscopeFrame)
{
    ui->setupUi(this);
    ui->spbStep->setValue(1);
    for(int i = 1; i <= 8; ++i)
    {
        ui->cmbAxisId->addItem(QString::number(i));
    }

    m_customPlot = new QCustomPlot(this);
    m_customPlot->setObjectName(QLatin1String("customPlot"));
    ui->vlyPlot->addWidget(m_customPlot);

    m_customPlot->setBackground(QBrush(QColor("#474848")));
    m_customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom |
                                  QCP::iSelectPlottables);  /* 可拖拽+可滚轮缩放 */
    m_customPlot->legend->setVisible(true);

    m_customPlot->addGraph();
    m_customPlot->graph(0)->setPen(QPen(Qt::green, 3));
    m_customPlot->graph(0)->setName(QStringLiteral("实际速度"));

    m_customPlot->addGraph();
    m_customPlot->graph(1)->setPen(QPen(Qt::yellow, 3));
    m_customPlot->graph(1)->setName(QStringLiteral("规划速度"));

    m_customPlot->axisRect()->setupFullAxesBox();
    m_customPlot->yAxis->setRange(0, 3.3);

    ui->btnPause2Continue->setCheckable(true);
    setFixedLength(100);

    /* 暂停/继续 */
    connect(ui->btnPause2Continue, &QPushButton::clicked, this, [ = ]()
    {
        if(!m_timer)
        {
            return;
        }
        bool isCheckable = ui->btnPause2Continue->isCheckable();
        if(isCheckable)
        {
            m_timer->stop();
            ui->btnPause2Continue->setText(QStringLiteral("继续"));
        }
        else
        {
            m_timer->start(OSCILLOSCOPE_UPDATE_MSEC);
            ui->btnPause2Continue->setText(QStringLiteral("暂停"));
        }
        ui->btnPause2Continue->setCheckable(!isCheckable);
    });

    /* 左移 */
    connect(ui->btnLeftMove, &QPushButton::clicked, this, [ = ]()
    {
        m_customPlot->xAxis->setRange(m_customPlot->xAxis->range().lower - ui->spbStep->value(),
                                      m_customPlot->xAxis->range().upper - ui->spbStep->value());
        m_customPlot->replot();
    });

    /* 右移 */
    connect(ui->btnRightMove, &QPushButton::clicked, this, [ = ]()
    {
        m_customPlot->xAxis->setRange(m_customPlot->xAxis->range().lower  + ui->spbStep->value(),
                                      m_customPlot->xAxis->range().upper  + ui->spbStep->value());
        m_customPlot->replot();
    });

    /* 显示表格 */
    connect(ui->chkGrid, &QCheckBox::toggled, this, [ = ](bool checked)
    {
        m_customPlot->xAxis->grid()->setVisible(checked);
        m_customPlot->yAxis->grid()->setVisible(checked);
        m_customPlot->replot();
    });

    auto updateData = [ & ]()
    {
        if(m_controller)
        {
            int axis = ui->cmbAxisId->currentText().toInt();
            T_AxisStatus status;
            int ec = m_controller->readAxisStatus(axis, &status);
            if(0 == ec)
            {
                ui->lblActVel->setText(QString::number(status.dEncVel));
                ui->lblPrfVel->setText(QString::number(status.dPrfVel));
                ui->lblActPos->setText(QString::number(status.dEncPos));
                ui->lblPrfPos->setText(QString::number(status.dPrfPos));
                if(m_actPos != status.dEncPos)
                {
                    m_actPos = status.dEncPos;
                    addData(m_count, status.dEncVel, status.dPrfVel);
                    m_count ++;
                }
            }
            else
            {
                ui->lblActVel->setText("error " + QString::number(ec));
                ui->lblPrfVel->setText("error " + QString::number(ec));
                ui->lblActPos->setText("error " + QString::number(ec));
                ui->lblPrfPos->setText("error " + QString::number(ec));
            }
        }
    };

    m_timer = new QTimer();
    connect(m_timer, &QTimer::timeout, updateData);
    m_timer->start(OSCILLOSCOPE_UPDATE_MSEC);

    connect(m_customPlot, SIGNAL(mouseMove(QMouseEvent *)), this,
            SLOT(plotMouseMoveEvent(QMouseEvent *)));

    for(int i = 0; i < 500; i++)
    {
        double x = qDegreesToRadians((double)i);
        addData(i, sin(x), cos(x));
    }
}

OscilloscopeFrame::~OscilloscopeFrame()
{
    m_timer->stop();
    delete m_timer;
    m_timer = nullptr;
    delete ui;
}

void OscilloscopeFrame::setFixedLength(double length)
{
    /* 显示固定长度 */
    m_fixedLength = length;
}

void OscilloscopeFrame::addData(double key, double actVel, double prfVel)
{
    m_customPlot->graph(0)->addData(key, actVel);
    m_customPlot->graph(1)->addData(key, prfVel);

    m_customPlot->xAxis->rescale();
    m_customPlot->graph(0)->rescaleValueAxis(false, true);
    m_customPlot->graph(1)->rescaleValueAxis(false, true);

    m_customPlot->xAxis->setRange(m_customPlot->xAxis->range().upper,
                                  m_fixedLength, Qt::AlignRight);
    m_customPlot->replot(QCustomPlot::rpQueuedReplot);  /* 实现重绘 */
}

void OscilloscopeFrame::installController(AbstractRobot *controller)
{
    m_controller = controller;
}

void OscilloscopeFrame::plotMouseMoveEvent(QMouseEvent *event)
{
    if ( Qt::ControlModifier == event->modifiers())
    {
        int x_pos = event->pos().x();
        int x_val = m_customPlot->xAxis->pixelToCoord(x_pos);
        float y = m_customPlot->graph(0)->data()->at(x_val)->value;
        QString strToolTip = QString("%1,%2").arg(x_val).arg(y);
        QToolTip::showText(cursor().pos(), strToolTip, m_customPlot);
    }
}

到了这里,关于QT实现固高运动控制卡示波器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Dell R710 iDRAC6 远程控制卡设置_服务器如何配置远程控制网卡(1)

    设置串口重定向 COM1就是服务器接显示器的串口,我们需要将 COM1 的输入重定向到 COM2 接口,观察控制台的输出。 重新启动服务器,按F2 进入 BIOS 设置菜单: 选择 “Serial Communication ”,按图示设置串口重定向参数: 注意:如果telnet/SSH连接时出现乱码,可以设置 Remote Termin

    2024年04月26日
    浏览(26)
  • PyVISA使用——用python控制TEK示波器源码实现

    项目上提出自动化测试需求,要求能够对板级信号使用示波器等仪器做自动化测量 使用PyVISA 方案实现。 VISA (Virtual Instrument Software Architecture) 是一个用于访问测量仪器和控制计算机之间的接口标准,由美国国家仪器公司(National Instruments)推出,用于实现仪器之间的通信和控

    2024年02月10日
    浏览(31)
  • FPGA实现AD9708和AD9280波形收发输出HDMI模拟示波器,串口协议帧控制显示,提供工程源码和技术支持

    AD9708 很简单,8 位分辨率,125MSPS 采样率,输入参考电压3~5V,内置 1.2V 参考电压,8bit数字信号输入,差分电流输出;芯片操作不需要软件配置,给个时钟信号就工作,简单得很,根据官方手册,内部结构如下: SLEEP引脚提供芯片休眠功能,当不需要使用该芯片时可拉高SLEEP以

    2024年02月02日
    浏览(41)
  • 分享一款开源的QT的串口示波器

    分享一款开源的QT的串口示波器,完全开源,支持串口、TCP、波形显示、通信协议。 支持传统的串口调试助手的基本收发功能,同时可以刷新大量的数据而不卡顿 支持保存接收的数据 支持最大200条可编辑指令的设置,并用于多条发送 支持定时器发送 支持换行符替换时间戳功

    2024年02月07日
    浏览(25)
  • Qt应用开发(拓展篇)——示波器/图表 QCustomPlot

             QCustomPlot 是一个用于绘图和数据可视化的Qt C++小部件。它没有进一步的依赖关系,提供友好的文档帮助。这个绘图库专注于制作好看的,出版质量的2D绘图,图形和图表,以及为实时可视化应用程序提供高性能。         QCustomPlot可以导出各种格式,如矢量化

    2024年02月11日
    浏览(29)
  • 【数字示波器设计】——基于FPGA的数字示波器实现

    【数字示波器设计】——基于FPGA的数字示波器实现 数字示波器是电子技术领域中非常重要的仪器之一,可以用来观察电信号的波形,是电子工程师必备的工具。而基于FPGA的数字示波器则具有高速、高精度和可编程性强等优势,成为了现代电子工程师常用的示波器。 本文将介

    2024年01月20日
    浏览(35)
  • stm32毕设 示波器设计与实现(源码+硬件+论文)

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月06日
    浏览(36)
  • 智能车竞赛·通过虚拟示波器实现电机PID调参

    本文主要针对智能车小白,大佬可以浅看一下,如有错误希望大家多多指正。 引入: 刚入门智能车的朋友们可能都知道备赛时要对电机进行PID调试,看了一大堆资料,了解了什么是位置式PID,什么是增量式PID,kuakua一顿乱写,写好了电机PID控制代码。写好代码之后,诶!我

    2024年02月05日
    浏览(28)
  • C# 使用 ScottPlot.WinForms 实现示波器的波形显示

    灵活使用C# 的部分图表组件,可以快速搭建一个【示波器】波形显示的界面 这里使用: ScottPlot.WinForms ,通过官方描述是开源的 下载地址:https://github.com/ScottPlot/ScottPlot.git visual studio 可以使用: NuGet 安装管理 ScottPlot.WinForms ScottPlot 支持:WPF 与 WinForms等多种实现方法 官方介绍

    2023年04月08日
    浏览(92)
  • ThunderScope开源示波器

    4CH,1GSa/S 开源示波器。前端很简洁,BUF802+LMH6518,ADC是HMCAD1511,用Xilinx A7 FPGA进行控制,数据通过PCIE总线传输到上位机处理。目前这个项目已经被挂到了Xilinx官网,强。 设计日志:https://hackaday.io/project/180090-thunderscope 开源地址:https://github.com/EEVengers/ThunderScope discord讨论组:

    2024年02月16日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包