备注:该程序在串口解析时偶尔还会出现问题
.pro
#-------------------------------------------------
#
# Project created by QtCreator 2021-03-09T09:33:42
#
#-------------------------------------------------
QT += core gui serialport printsupport
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = untitled
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
CONFIG += c++11
SOURCES += \
graph.cpp \
main.cpp \
mainwindow.cpp \
qcustomplot.cpp \
resolver.cpp \
serial.cpp
HEADERS += \
fftw3.h \
graph.h \
mainwindow.h \
qcustomplot.h \
resolver.h \
serial.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
LIBS += -L$$PWD/./ -llibfftw3-3
INCLUDEPATH += $$PWD/.
DEPENDPATH += $$PWD/.
fftw3.h是fftw的自带头文件,工程中需要包含
graph.h
#ifndef GRAPH_H
#define GRAPH_H
#include <QMainWindow>
#include "qcustomplot.h"
#endif // GRAPH_H
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "serial.h"
#include "graph.h"
#include "resolver.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
QVector<double> x,y0,y1;
signals:
void start_resolver();
public slots:
void slot_graph();
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
void readyRead_slot(QByteArray data);
void on_actionserial_triggered(bool checked);
void on_dockWidget_visibilityChanged(bool visible);
void on_pushButton_3_clicked();
private:
Ui::MainWindow *ui;
serial *myserial;
resolver *m_resolver;
QThread *m_thread;
void graph_init();
void customplot1_add_graph(void);
void customplot2_add_graph(void);
};
#endif // MAINWINDOW_H
qcustomplot.h是Qt中用来显示波形的外部库qcustomplot的头文件
resolver.h
#ifndef RESOLVER_H
#define RESOLVER_H
#include <QObject>
#include <QThread>
#include "fftw3.h"
#define N 256
#define UART_BUF_SIZE 200
class resolver : public QObject
{
Q_OBJECT
public:
explicit resolver(QObject *parent = nullptr);
~resolver();
signals:
void start_graph();
public slots:
void do_resolver();
private:
void do_fft();
void do_resolver2(char *char_data,uint8_t len);
};
struct channel_data
{
uint16_t average_value;
uint16_t current_value;
uint16_t power;
uint16_t Shredded;
};
#endif // RESOLVER_H
serial.h
#ifndef SERIAL_H
#define SERIAL_H
#include <QObject>
#include <QSerialPort>
#include <QSerialPortInfo>
#include "qserialport.h"
#include "QString"
class serial:public QObject
{
Q_OBJECT
public:
serial(QObject *o=0);
~serial();
bool openPort(QString portName,qint32 baudRate,QSerialPort::DataBits dataBits,
QSerialPort::Parity parity,QSerialPort::StopBits stopBits,
QSerialPort::FlowControl flowControl);
bool isOpen();
void closePort();
QStringList getAvailablePortNameList();
void write(QString str);
void write(const char *data, qint64 len);
QString ByteArrayToHexString(QByteArray data);
signals:
void readyRead(QByteArray data);
private:
QSerialPort *m_port;
void readyRead_slot();
};
#endif // SERIAL_H
graph.cpp
#include "graph.h"
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QVector>
#include <stdio.h>
extern fftw_complex *in, *out;
/*-------------------------------------------*/
//画动态曲线时,传入数据采用addData,通过定时器多次调用,并在之后调用ui->widget->replot();
//动态曲线可以通过另一种设置坐标的方法解决坐标问题:
//setRange ( double position, double size, Qt::AlignmentFlag alignment )
//参数分别为:原点,偏移量,对其方式,有兴趣的读者可自行尝试,欢迎垂询
/*-------------------------------------------*/
void MainWindow::graph_init()
{
x.resize(N);
for(int i=0;i<N;i++)
{
x[i]=i;
}
y0.resize(N);
y1.resize(N);
//设定背景为黑色
//ui->widget->setBackground(QBrush(Qt::black));
//设置X轴文字标注
ui->widget->xAxis->setLabel("time");
ui->widget_2->xAxis->setLabel("time");
//设置Y轴文字标注
ui->widget->yAxis->setLabel("short HbO2");
ui->widget_2->yAxis->setLabel("short HbO2");
//设置X轴坐标范围
ui->widget->xAxis->setRange(0,N);
ui->widget_2->xAxis->setRange(0,N/2);
//设置Y轴坐标范围
ui->widget->yAxis->setRange(0,3000);
ui->widget_2->yAxis->setRange(0,3000);
//在坐标轴右侧和上方画线,和X/Y轴一起形成一个矩形
//ui->widget->axisRect()->setupFullAxesBox();
//设置基本坐标轴(左侧Y轴和下方X轴)可拖动、可缩放、曲线可选、legend可选、设置伸缩比例,使所有图例可见
ui->widget->setInteractions(QCP::iRangeDrag|QCP::iRangeZoom| QCP::iSelectAxes |
QCP::iSelectLegend | QCP::iSelectPlottables);
ui->widget_2->setInteractions(QCP::iRangeDrag|QCP::iRangeZoom| QCP::iSelectAxes |
QCP::iSelectLegend | QCP::iSelectPlottables);
//设定右上角图形标注可见
//ui->widget->legend->setVisible(true);
//设定右上角图形标注的字体
//ui->widget->legend->setFont(QFont("Helvetica", 9));
/*曲线0*/
customplot1_add_graph();
customplot2_add_graph();
//draw test
// for(int i=0;i<100;i++)
// {
// y0[0] = 2*i+1;
// ui->widget->graph(0)->addData(x,y0);
// x[0]=i;
// }
}
void MainWindow::customplot1_add_graph()
{
//添加图形
ui->widget->addGraph();
//设置画笔
QPen pen0(Qt::red, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
ui->widget->graph(0)->setPen(pen0);
//ui->widget->graph(0)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ScatterShape::ssPlus,5));
//设置画刷,曲线和X轴围成面积的颜色
//ui->widget->graph(0)->setBrush(QBrush(QColor(255,255,0)));
//设置右上角图形标注名称
ui->widget->graph(0)->setName("曲线");
//传入数据,setData的两个参数类型为double
//ui->widget->graph(0)->setLineStyle(QCPGraph::lsLine);//lsNone/lsLine/lsStepLeft/lsStepRight/lsStepCenter/lsImpulse
//ui->widget->graph(0)->addData(x,y);
// y0[0]=0;
// ui->widget->graph(0)->setData(x,y0);
//根据图像最高点最低点自动缩放坐标轴
//Y轴
//ui->widget->graph(0)->rescaleValueAxis(true);
//X轴
//ui->widget->graph(0)->rescaleKeyAxis(true);
//X、Y轴
//ui->widget->graph(0)->rescaleAxes(true);
}
void MainWindow::customplot2_add_graph()
{
//添加图形
ui->widget_2->addGraph();
//设置画笔
QPen pen0(Qt::blue, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
ui->widget_2->graph(0)->setPen(pen0);
//ui->widget->graph(0)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ScatterShape::ssPlus,5));
//设置画刷,曲线和X轴围成面积的颜色
//ui->widget->graph(0)->setBrush(QBrush(QColor(255,255,0)));
//设置右上角图形标注名称
ui->widget_2->graph(0)->setName("曲线");
}
void MainWindow::slot_graph()
{
for(int i=0;i<N;i++)
{
y0[i]=in[i][0];
y1[i]=out[i][0];
}
ui->widget->graph(0)->setData(x,y0);
ui->widget->replot();
ui->widget_2->graph(0)->setData(x,y1);
ui->widget_2->replot();
}
main.cpp不做解释
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "QDebug"
char uart_buf[UART_BUF_SIZE];
uint16_t uart_buf_point=0;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
myserial(new serial)
{
ui->setupUi(this);
QStringList baudRate;
baudRate<<"115200"<<"9600";
ui->comboBox_2->addItems(baudRate);
m_thread=new QThread;
connect(m_thread,&QThread::started,this,
[this]
{
qDebug()<<"thread started";
},Qt::UniqueConnection);
connect(m_thread,&QThread::finished,this,
[this]
{
qDebug()<<"thread finished";
},Qt::UniqueConnection);
connect(m_thread,&QThread::destroyed,this,
[this]
{
qDebug()<<"thread destroyed";
},Qt::UniqueConnection);
m_resolver=new resolver();
m_resolver->moveToThread(m_thread);
connect(m_thread, &QThread::finished, this, &QObject::deleteLater,Qt::UniqueConnection);
connect(m_thread, &QThread::finished, m_thread, &QObject::deleteLater,Qt::UniqueConnection);
connect(this,&MainWindow::start_resolver,m_resolver,&resolver::do_resolver,Qt::UniqueConnection);
connect(m_resolver,&resolver::start_graph,this,&MainWindow::slot_graph,Qt::UniqueConnection);
m_thread->start();
emit start_resolver();
//初始化graph
graph_init();
}
MainWindow::~MainWindow()
{
delete ui;
delete myserial;
delete m_resolver;
m_thread->quit();
m_thread->wait();
delete m_thread;
}
/*搜索串口*/
void Main