Qt 线程串口

文章目录

  • ui设置
  • 创建线程函数
  • 初始串口
  • run函数接收发送数据
    • 读取数据
    • 处理读取的数据
    • 写入数据
    • 写入启动的命令
  • 主线程

在这里插入图片描述

ui设置

在这里插入图片描述

创建线程函数

#include <QObject>
#include <QThread>
#include <QSerialPort>
#include <QSerialPortInfo>class SerialPort : public QThread
{Q_OBJECT
public:SerialPort();~SerialPort();public:void InitPort(QString PortName);void wirteData();//写入数据void ProcessReceivedData(QByteArray);//处理数据quint8  CalculateChecksum(const QByteArray& data);//计算校验和
signals:void SendData(float m_fVol[10]);//发送数据protected:void run();public slots:void readData();void handleBytesWritten(quint64 bytes);public:QSerialPort* port;QStringList serialPortNameList;//串口列表float m_fVol[10];//电压QByteArray m_receivedBuffer[4096];QByteArray receivedData;//接收到的数据
};

初始串口

void SerialPort::InitPort(QString PortName)
{// 查询所有串口设备
//    QList<QSerialPortInfo> serialList = QSerialPortInfo::availablePorts();//    foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
//    {
//        serialPortNameList << info.portName();
//        qDebug()<<"serialPortName: "<<info.portName();
//    }//qDebug()<<PortName;port->setPortName(PortName);port->setBaudRate(19200, QSerialPort::AllDirections);//波特率port->setDataBits(QSerialPort::Data8);             // 数据位为8位port->setFlowControl(QSerialPort::NoFlowControl);  // 无流控制port->setParity(QSerialPort::NoParity);            // 无校验位port->setStopBits(QSerialPort::OneStop);           // 一位停止位if (port->open(QIODevice::ReadWrite)){qDebug() << "Port have been opened";wirteData();}else{qDebug() << "open it failed";return;}
}

run函数接收发送数据

void SerialPort::run()
{connect(port, &QSerialPort::bytesWritten, this, &SerialPort::handleBytesWritten);//向串口写数据connect(port, &QSerialPort::readyRead, this, &SerialPort::readData);//向串口读数据exec();
}

读取数据

void SerialPort::readData()
{if (port->bytesAvailable() > 0){qint64 nReadSize = 4096;if(port->isOpen()){QByteArray receivedData = port->read(nReadSize);//qDebug()<<receivedData.size();if (receivedData.size() >= 26){ProcessReceivedData(receivedData); // 处理接收到的数据}}}
}

处理读取的数据

void SerialPort::ProcessReceivedData(QByteArray receivedData)
{//qDebug()<<receivedData;//qDebug()<<receivedData.size();if(receivedData.size() >= 26){if (receivedData.at(0) == 'U' && receivedData.at(receivedData.length() - 1) == '\xAA'){// 检验校验和//qDebug()<<receivedData;QByteArray dataContent = receivedData.mid(1, 23);quint8 receivedChecksum = static_cast<quint8>(receivedData.at(24)); // 获取接收到的校验和quint8 calculatedChecksum = CalculateChecksum(dataContent); // 计算校验和if(receivedChecksum ==calculatedChecksum )//数据正确{quint16 wT;for (int j = 0; j < 10; ++j){wT = static_cast<quint8>(receivedData[j*2+2]);wT <<= 8;wT += static_cast<quint8>(receivedData[j*2+1]);m_fVol[j] = wT * 5000.0f / 1024;emit SendData(m_fVol);}}}else{receivedData.remove(0, 1);}}}quint8 SerialPort::CalculateChecksum(const QByteArray &data)
{quint8 checksum = 0;for (int i = 0; i < data.size(); ++i){checksum += static_cast<quint8>(data.at(i));}return checksum;
}

写入数据

void SerialPort::handleBytesWritten(quint64 bytes)
{if (bytes > 0){// 数据写入成功//qDebug()<<bytes;connect(port, &QSerialPort::readyRead, this, &SerialPort::readData);//向串口读数据} else {// 数据写入失败wirteData();//再次写入}
}

写入启动的命令

void SerialPort::wirteData()
{if (port->isOpen()){QByteArray data;data.append(char(0x55)); // 添加数据 0x55 到数组data.append(char(0x01)); // 添加数据 0x01 到数组data.append(char(0x01)); // 添加数据 0x01 到数组data.append(char(0x00)); // 添加数据 0x00 到数组data.append(char(0x00)); // 添加数据 0x00 到数组data.append(char(0x00)); // 添加数据 0x00 到数组data.append(char(0x02)); // 添加数据 0x02 到数组data.append(char(0xAA)); // 添加数据 0xAA 到数组//qDebug()<<char(0x55);port->clear(QSerialPort::Output); // 清除输出缓冲区port->write(data);                // 写入数据到串口}
}

主线程

#include <QWidget>
#include "serialport.h"QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private:Ui::Widget *ui;public slots:void ReadData(float m_fVol[10]);public:SerialPort* m_Port;private slots:void on_pushButton_clicked();
};
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);m_Port =new SerialPort();ui->comboBox->addItem("COM1");ui->comboBox->addItem("COM2");ui->comboBox->addItem("COM3");ui->comboBox->addItem("COM4");ui->comboBox->addItem("COM5");ui->comboBox->addItem("COM6");ui->comboBox->addItem("COM7");ui->comboBox->addItem("COM8");}Widget::~Widget()
{delete ui;
}void Widget::ReadData(float m_fVol[10])
{QTextCursor tc = ui->textBrowser->textCursor();tc.movePosition(QTextCursor::End);//qDebug()<<m_fovl;for(int i=0;i<10;i++){tc.insertText(QString::number(m_fVol[i])+"mv\n");tc.insertText("\n");}tc.insertText("----------\n");ui->textBrowser->moveCursor(QTextCursor::End);
}void Widget::on_pushButton_clicked()
{if(ui->pushButton->text() == "连接"){m_Port->InitPort(ui->comboBox->currentText());connect(m_Port,&SerialPort::SendData,this,&Widget::ReadData);m_Port->start();ui->pushButton->setText("断开连接");}else {m_Port->port->close();disconnect(m_Port, &SerialPort::SendData, this, &Widget::ReadData); // 断开连接ui->pushButton->setText("连接");}}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微信小程序广告banner、滚动屏怎么做?

使用滑块视图容器swiper和swiper-item可以制作滚动屏&#xff0c;代码如下&#xff1a; wxml: <swiper indicator-dots indicator-color"rgba(255,255,255,0.5)" indicator-active-color"white" autoplay interval"3000"><swiper-ite…

Unity Meta Quest 一体机开发(六):HandGrabInteractor 和 HandGrabInteractable 知识点

文章目录 &#x1f4d5;教程说明&#x1f4d5;HandGrabInteractor⭐HandGrabAPI⭐HandWristPoint⭐GripPoint⭐PinchPoint⭐PinchArea⭐HandGrabVisual⭐HandGrabGlow &#x1f4d5;HandGrabInteractable⭐Support Grab Type⭐Pinch Grab Rules 和 Palm Grab Rules⭐Unselect M…

【Java 进阶篇】JQuery 案例:全选全不选,为选择添彩

在前端的舞台上&#xff0c;用户交互是一场精彩的表演&#xff0c;而全选全不选的功能则是其中一段引人入胜的剧情。通过巧妙运用 JQuery&#xff0c;我们可以为用户提供便捷的全选和全不选操作&#xff0c;让页面更富交互性。本篇博客将深入探讨 JQuery 中全选全不选的实现原理…

pytorch tensor数据类型转换为python数据

一、item() input: x torch.tensor([1.0]) x.item()output: 1.0二、tolist() input: a torch.randn(2, 2) a.tolist() a[0,0].tolist()output: [[0.012766935862600803, 0.5415473580360413],[-0.08909505605697632, 0.7729271650314331]]0.012766935862600803

【论文阅读】(CTGAN)Modeling Tabular data using Conditional GAN

论文地址&#xff1a;[1907.00503] Modeling Tabular data using Conditional GAN (arxiv.org) 摘要 对表格数据中行的概率分布进行建模并生成真实的合成数据是一项非常重要的任务&#xff0c;有着许多挑战。本文设计了CTGAN&#xff0c;使用条件生成器解决挑战。为了帮助进行公…

IDEA如何打断点调试

目录 1. 设置断点2. 调试3. 调试的基本操作3.1 step over3.2 step into 跟 Force step into3.3 step out3.4 resume program3.5 mute breakpoints3.6 view breakpoints3.6 条件断点 编写代码的时候&#xff0c;有时候我们需要跟踪代码的运行情况&#xff0c;使用断点调试就是一…

Eclipse打包Springboot项目

首先&#xff0c;在pom.xml文件中添加配置&#xff0c;修改mainClass主函数&#xff1a; <build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configurat…

蓝桥杯每日一题2023.11.14

题目描述 题目分析 此题目的最终目标是将字母都填上数使等式符合条件&#xff0c;实际我们发现可以使用搜索将所有符合条件的进行判断&#xff08;答案&#xff1a;29&#xff09; 由于小数可能会出现错误故我们将其进行简单变化进行搜索 #include<bits/stdc.h> using…

Git常用指令以及常见问题解决

摘要&#xff1a;记录本人Git常用指令以及常见问题解决 1.Git流程 2.具体操作 git init&#xff1a;初始化目录&#xff08;一般直接git clone远端的工程&#xff0c;这一步都可以省略掉&#xff09;&#xff1b; 输入命令“git config --global user.name xxx”来配置你的用…

wpf devexpress设置行和编辑器

如下教程示范如何计算行布局&#xff0c;特定的表格单元编辑器&#xff0c;和格式化显示值。这个教程基于前一个文章 选择行显示 GridControl为所有字段生成行和绑定数据源&#xff0c;如果AutoGenerateColumns 属性选择AddNew。添加行到GridControl精确显示为特别的几行设置。…

【力扣题:循环队列】

文章目录 一.题目描述二. 思路解析三. 代码实现 一.题目描述 设计你的循环队列实现。 循环队列是一种线性数据结构&#xff0c;其操作表现基于 FIFO&#xff08;先进先出&#xff09;原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。 循环队列的一个好…

贪吃蛇小游戏代码

框架区 package 结果;import java.awt.Color; import java.awt.EventQueue; import java.awt.Font; import java.awt.Frame; import java.awt.Graphics; import java.awt.Image; import java.util.ArrayList; import java.util.List; import java.util.Random;import javax.s…

k8s之Helm

理论&#xff1a; 什么是 He lm 在没使用 helm 之前&#xff0c;向 kubernetes 部署应用&#xff0c;我们要依次部署 deployment、svc 等&#xff0c;步骤较繁琐。 况且随着很多项目微服务化&#xff0c;复杂的应用在容器中部署以及管理显得较为复杂&#xff0c;helm 通过打包…

参考意义大。4+巨噬细胞相关生信思路,简单易复现。

今天给同学们分享一篇生信文章“Angiogenesis regulators S100A4, SPARC and SPP1 correlate with macrophage infiltration and are prognostic biomarkers in colon and rectal cancers”&#xff0c;这篇文章发表在Front Oncol期刊上&#xff0c;影响因子为4.7。 结果解读&a…

[云原生案例2.3 ] Kubernetes的部署安装 【多master集群架构高可用 ---- (二进制安装部署)】

文章目录 1. Kubernetes多Master集群高可用方案1.1 多节点Master高可用的实现过程1.2 实现高可用方法 2. 新Master节点的部署2.1 前置准备2.2 系统初始化操作2.2.1 关闭防火墙、selinux和swap分区2.2.2 修改主机名&#xff0c;添加域名映射2.2.3 修改内核参数2.2.4 时间同步 2.…

如何在Windows 10中进行屏幕截图

本文介绍如何在Windows 10中捕获屏幕截图&#xff0c;包括使用键盘组合、使用Snipping Tool、Snipp&Sketch Tool或Windows游戏栏。 使用打印屏幕在Windows 10中捕获屏幕截图 在Windows 10中捕获屏幕截图的最简单方法是按下键盘上的PrtScWindows键盘组合。你将看到屏幕短暂…

做一个Springboot文件上传-阿里云

概述 这个模块是用来上传头像以及文章封面的&#xff0c;图片的值是一个地址字符串&#xff0c;一般存放在本地或阿里云服务中 1、本地文件上传 我们将文件保存在一个本地的文件夹下&#xff0c;由于可能两个人上传不同图片但是却同名的图片&#xff0c;那么就会一个人的图片就…

mac配置双网卡 mac同时使用内网和外网

在公司办公通常都会连内网&#xff0c;而连内网最大的限制就是不可以使用外网&#xff0c;那遇到问题也就不能google&#xff0c;而当连接无线的时候&#xff0c;内网的东西就不可以访问&#xff0c;也就不能正常办公&#xff0c;对于我这种小白来说&#xff0c;工作中遇到的问…

【C++】类和对象(3)--初始化列表(再谈构造函数)

目录 一 引入 二 初始化列表概念 三 初始化列表特性 1 引用和const 2 混合使用 3 自定义成员情况 四 初始化列表中的初始化顺序 五 总结 一 引入 构造函数体赋值 class Date { public:Date(int year, int month, int day){_year year;_month month;_day day;} priv…

初学UE5 C++①

游戏类 1.创建所需项的类 2.创建游戏模式类&#xff0c;在该类上实现所需项&#xff0c;引入头文件和构造函数时实例化 三种时间函数类型函数和提示类型 FName、FString、FText类型相互转化 FName用FName FString用ToString&#xff08;&#xff09; FText用FText&#xff1a;…