Qt实现安卓手机蓝牙通信并控制stm32f103c8t6驱动VFD屏

2023-10-28 06:20

本文主要是介绍Qt实现安卓手机蓝牙通信并控制stm32f103c8t6驱动VFD屏,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、Qt建立蓝牙通信

Qt具有跨平台的特性所以非常适合写通信的demo,但是在这个例程中Qt蓝牙部分不支持Windows平台,安卓平台使用没问题。
Qt蓝牙主要涉及到三个类的使用:
QBluetoothDeviceDiscoveryAgent //扫描周围蓝牙设备
QBluetoothLocalDevice //扫描本地蓝牙
QBluetoothSocket //建立蓝牙的socket读写

安卓不支持低功耗蓝牙,但是socket既可以使用经典蓝牙也可以使用低功耗蓝牙,本例程使用经典蓝牙socket收发数据

1、在.pro工程文件添加

Qt                   +=bluetooth

2、主要代码Widget.h和Widget.c

#ifndef WIDGET_H
#define WIDGET_H
#pragma execution_character_set("utf-8")   //解决中文乱码#include <QWidget>
#include <QObject>
#include <QtBluetooth/qbluetoothlocaldevice.h>
#include <qbluetoothaddress.h>
#include <qbluetoothdevicediscoveryagent.h>
#include <qbluetoothlocaldevice.h>
#include <qbluetoothsocket.h>
#include <QMap>
#include <QTimer>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();void model2_Init();
public slots:void addBlueToothDevicesToList(const QBluetoothDeviceInfo&);void readBluetoothDataEvent();void bluetoothConnectedEvent();void bluetoothDisconnectedEvent();void onError(QBluetoothSocket::SocketError error);void open_BLE();void close_BLE();void scanFinished();
private:QBluetoothDeviceDiscoveryAgent *discoveryAgent;QBluetoothLocalDevice *localDevice;QBluetoothSocket *socket;QByteArray blueArray;QMap<QString,QBluetoothAddress>m;QBluetoothDeviceInfo remoteDeviceInfo;float ff;//随机数缓存float div;//每次下降数float sx;//上限float t;//时间QString ss;//字符判断是模式1还是模式2QTimer *time;private slots:void on_pushButton_clicked();void on_pushButton_2_clicked();void on_pushButton_4_clicked();void on_pushButton_5_clicked();void on_pushButton_3_clicked();void on_pushButton_7_clicked();void on_pushButton_8_clicked();void on_pushButton_9_clicked();void on_pushButton_6_clicked();void timeProcess();void on_pushButton_10_clicked();void on_label_7_linkActivated(const QString &link);private:Ui::Widget *ui;
};
#endif // WIDGET_H
## Widget.c
#include "widget.h"
#include "ui_widget.h"
#include <QRandomGenerator>
#include <QLowEnergyController>//这个UUID要根据自己的使用情况来确定,我使用的是串口类的UUID,具体可https://www.jianshu.com/p/eb85cb690e86
static const QLatin1String serviceUuid("00001101-0000-1000-8000-00805F9B34FB");
//static const QLatin1String serviceUuid("FDA50693A4E24FB1AFCFC6EB07647825");
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);ui->plainTextEdit->setDisabled(1);discoveryAgent = new QBluetoothDeviceDiscoveryAgent(this);localDevice = new QBluetoothLocalDevice(this);socket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol);time = new QTimer(this);connect(time,SIGNAL(timeout()),this,SLOT(timeProcess()));discoveryAgent->start();ui->pushButton_4->setDisabled(1);connect(discoveryAgent, SIGNAL(finished()), this, SLOT(scanFinished()));//搜索结束connect(discoveryAgent,SIGNAL(deviceDiscovered(QBluetoothDeviceInfo)),this,SLOT(addBlueToothDevicesToList(QBluetoothDeviceInfo)));connect(socket,SIGNAL(readyRead()),this,SLOT(readBluetoothDataEvent()));connect(socket,SIGNAL(connected()),this,SLOT(bluetoothConnectedEvent()));connect(socket,SIGNAL(disconnected()),this,SLOT(bluetoothDisconnectedEvent()));connect(socket,SIGNAL(error(QBluetoothSocket::SocketError)),this,SLOT(onError(QBluetoothSocket::SocketError)));}Widget::~Widget()
{delete ui;delete discoveryAgent;delete localDevice;delete socket;delete time;
}void Widget::onError(QBluetoothSocket::SocketError error)
{QString str;if(QBluetoothSocket::UnknownSocketError == error){str = "UnknownSocketError";}else if(QBluetoothSocket::NoSocketError == error){str = "NoSocketError";}else if(QBluetoothSocket::HostNotFoundError == error){str = "HostNotFoundError";}else if(QBluetoothSocket::ServiceNotFoundError == error){str = "ServiceNotFoundError";}else if(QBluetoothSocket::NetworkError == error){str = "NetworkError";}else if(QBluetoothSocket::UnsupportedProtocolError == error){str = "UnsupportedProtocolError";}else if(QBluetoothSocket::OperationError == error){str = "OperationError";}else if(QBluetoothSocket::RemoteHostClosedError == error){str = "RemoteHostClosedError";}qDebug()<<error;//emit backendRunMesgPost(str);//emit backendRunMesgPost("SocketError");
}void Widget::addBlueToothDevicesToList( const QBluetoothDeviceInfo &info )
{remoteDeviceInfo = info;qDebug()<<"进入addBlueToothDevicesToList函数!";QString label = QString("%1 %2").arg(info.address().toString()).arg(info.name());qDebug()<<label;ui->comboBox->addItem(info.name());if(label.contains("BT04-A")){//找到需要连接的蓝牙名字int index = label.indexOf(' ');if(index == -1){qDebug()<<"index";return;}QBluetoothAddress address(label.left(index));m[info.name()] = address;//关联蓝牙名字和addressQString name(label.mid(index + 1));qDebug() << "You has choice the bluetooth address is " << address<<name<<endl;//qDebug() << "The device is connneting.... ";//ui->plainTextEdit_2->setPlainText("You has choice the bluetooth address is "+name);//ui->plainTextEdit_2->setPlainText("The device is connneting.... ");//emit backendRunMesgPost("The device is connneting");//socket->connectToService(address, QBluetoothUuid(serviceUuid) ,QIODevice::ReadWrite);}
}void Widget::readBluetoothDataEvent()
{static int cnt = 0;QByteArray line = socket->readAll();if(line.startsWith("y") || line.startsWith("r"))ss = line;if(ss.startsWith("y")){//ss = "d";if(!line.startsWith('y')){blueArray.append(line);}if(cnt < 4){ui->plainTextEdit->appendPlainText(QString(blueArray));cnt++;}else{cnt = 0;ui->plainTextEdit->clear();}//ui->plainTextEdit->setPlainText(QString(blueArray));ui->plainTextEdit_2->setPlainText("模式1");emit ui->pushButton_3->clicked(1);}else if(ss.startsWith("r")){ss = "d";ui->plainTextEdit_2->setPlainText("模式2");model2_Init();emit ui->pushButton_10->clicked(1);emit ui->pushButton_7->clicked(1);ss = "d";}else if(line.startsWith("Flash")){ui->plainTextEdit_2->setPlainText(QString(line));ss = "d";}
}void Widget::bluetoothConnectedEvent()
{qDebug() << "The android device has been connected successfully!";ui->plainTextEdit_2->setPlainText("The android device has been connected successfully!");
}void Widget::bluetoothDisconnectedEvent()
{qDebug() << "The android device has been disconnected successfully!";
}void Widget::open_BLE()
{if( localDevice->hostMode() == QBluetoothLocalDevice::HostPoweredOff)//开机没有打开蓝牙{localDevice->powerOn();//调用打开本地的蓝牙设备discoveryAgent->start();//开始扫描蓝牙connect(discoveryAgent,SIGNAL(deviceDiscovered(QBluetoothDeviceInfo)),this,SLOT(addBlueToothDevicesToList(QBluetoothDeviceInfo)));ui->plainTextEdit_2->setPlainText("手机蓝牙已成功打开!");}else{qDebug() << "手机蓝牙已成功打开!";ui->plainTextEdit_2->setPlainText("手机蓝牙已成功打开!");}
}void Widget::close_BLE()
{socket->close();ui->plainTextEdit_2->setPlainText("蓝牙已断开!");
}void Widget::on_pushButton_clicked()//模式一
{//ui->plainTextEdit->clear();ui->pushButton_2->setDisabled(1);ui->pushButton_7->setDisabled(1);socket->write("y");
}void Widget::on_pushButton_2_clicked()//模式二
{model2_Init();ui->pushButton->setDisabled(1);ui->pushButton_3->setDisabled(1);if(socket->state() == QAbstractSocket::ConnectedState){socket->write("r");}
}void Widget::on_pushButton_4_clicked()//连接蓝牙
{discoveryAgent->stop();if(ui->comboBox->currentText().startsWith("BT04-A")){//低功耗蓝牙连接方式/*QLowEnergyController *lowBtControl = QLowEnergyController::createCentral(remoteDeviceInfo);lowBtControl->connectToDevice();*///经典蓝牙连接方式qDebug() << "连接到的蓝牙是" << m[ui->comboBox->currentText()]<<ui->comboBox->currentText();socket->connectToService(m[ui->comboBox->currentText()],QBluetoothUuid(serviceUuid) ,QIODevice::ReadWrite);ui->plainTextEdit_2->setPlainText("The device is connneting.... ");if(socket->state() == QAbstractSocket::ConnectedState)ui->plainTextEdit_2->setPlainText("蓝牙连接成功!");}else{ui->plainTextEdit_2->setPlainText("没有找到目标蓝牙!");}
}void Widget::on_pushButton_5_clicked()//断开连接
{close_BLE();
}void Widget::on_pushButton_3_clicked()//模式一修改数字
{if(socket->write("v")){QString str;str = ui->lineEdit_6->text();str.append('z');socket->write(str.toUtf8());ui->plainTextEdit_2->setPlainText("成功发送一条数据!v");}
}void Widget::on_pushButton_7_clicked()
{if(socket->write("s"))//发送随机数{QString str = QString("%1").arg(sx);if(str.length() > 4)str = str.left(4);str.append('x');socket->write(str.toUtf8());}
}void Widget::on_pushButton_8_clicked()//切换模式
{ui->pushButton->setEnabled(1);ui->pushButton_2->setEnabled(1);ui->pushButton_7->setEnabled(1);ui->pushButton_3->setEnabled(1);ui->plainTextEdit->setEnabled(1);ui->plainTextEdit->clear();ui->plainTextEdit->setDisabled(1);time->stop();
}void Widget::on_pushButton_9_clicked()
{open_BLE();
}void Widget::on_pushButton_6_clicked()
{this->close();
}void Widget::scanFinished()
{ui->pushButton_4->setEnabled(1);
}void Widget::timeProcess()
{sx = sx - div;QString str;str = QString("%1").arg(sx);qDebug()<<"sx is " + str<<endl;if(sx <= ff){sx = ff;time->stop();}ui->plainTextEdit_2->setPlainText("成功发送一条数据!s"+str);str = QString("%1").arg(div);qDebug()<<"div is " + str<<endl;emit ui->pushButton_7->clicked(1);
}void Widget::model2_Init()
{sx = ui->lineEdit_3->text().toUInt();t = ui->lineEdit_4->text().toUInt();div = (sx - ff)/(t*10);
}void Widget::on_pushButton_10_clicked()
{if(ui->lineEdit->text().isEmpty() == false && ui->lineEdit_2->text().isEmpty() == false ){std::uniform_real_distribution<float> dist(ui->lineEdit->text().toUInt(), ui->lineEdit_2->text().toUInt());ff = dist(*QRandomGenerator::global());ui->lineEdit_5->setText(QString::number(ff));QString str = ui->lineEdit_5->text();if(str.length() > 4)str = str.left(4);ff = str.toFloat();ui->lineEdit_5->setText(QString::number(ff));if(ui->lineEdit_3->text().isEmpty() == false && ui->lineEdit_4->text().isEmpty() == false){time->start(6000);}}}

在这里插入图片描述

二、通过蓝牙模块控制stm32f103c8t6驱动VFD

蓝牙模块选择BT08B蓝牙串口模块兼容HC-06,只需连接四个引脚 VCC 、GND、TX、RX即可

下面为VFD模块驱动程序,采用带驱动芯片的模块,直流5V供电即可,stm32可直接驱动模块引出引脚

1、VFD_Drive.h

#ifndef _VFD_DRIVE_H
#define _VFD_DRIVE_H#include "stm32f10x.h"void VFD_GPIOInit(void);//GPIO初始化void WriteCMD(u8 cmd);//写命令
void WriteDATA(u8 data);//写数据void Clear(void);//清屏
void Cursor_home(void);//光标归位
/*
该指令选择在每次DDRAM或CGRAM访问后AC(游标位置)是递增还是递减,并确定在每次DDRAM写入后显示信息的移动方向。
该指令还在每次DDRAM写入后启用或禁用显示移位。
*/
void IncCursor(void);//光标递增(向右)
void DecCursor(void);//光标递减(向左)void DisplayOFForON(u8 i,u8 j,u8 n);//光标显示还是不显示,i = 1显示i = 0不显示,并指定是否闪烁j = 1闪烁,j = 0闪烁,n=1开光标,n=0关光标
/*
该指令增加或减少AC(光标位置),并将显示信息向左或向右移动一个字符的位置
*/
void CharLeft(void);//字符和光标左移
void CharRight(void);//字符和光标右移
void CursorLeft(void);//光标左移
void CursorRight(void);//光标右移/*
设置并行口模式DL = 0为4位模式,DL = 1为8位模式
设置单行显示还是两行显示,N = 0,单行显示,N = 1两行显示
设置亮度BR = 0  100%亮度,BR = 1   75%亮度,BR = 2   50%亮度,BR = 3    25%亮度
*/
void FunSet(u8 DL,u8 N,u8 BR);//这里固定为两行显示,亮度100%,如需更改请查看手册重写函数/*该指令将DB5-DB0指定的6位CGRAM地址放入AC(光标位置)。后续的数据写入(读取)将会指向(从)CGRAM。*/
u8 CGRAM_addrSet(u8 addr);//返回传入addr后的命令/*该指令将DB6-DB0指定的7位DDRAM地址放入AC(光标位置)。后续的数据写入(读取)将从DDRAM写入(从DDRAM读取)。*/
u8 DDRAM_addrSet(u8 addr);//返回传入addr后的命令/*该指令将DB7-DB0上的8位数据字节写入AC寻址的DDRAM或CGRAM位置。
最近的DDRAM或CGRAM地址集指令决定是写入DDRAM还是CGRAM。
该指令还根据输入模式设置(Entry 

这篇关于Qt实现安卓手机蓝牙通信并控制stm32f103c8t6驱动VFD屏的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/291287

相关文章

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

安卓链接正常显示,ios#符被转义%23导致链接访问404

原因分析: url中含有特殊字符 中文未编码 都有可能导致URL转换失败,所以需要对url编码处理  如下: guard let allowUrl = webUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {return} 后面发现当url中有#号时,会被误伤转义为%23,导致链接无法访问

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount

Kubernetes PodSecurityPolicy:PSP能实现的5种主要安全策略

Kubernetes PodSecurityPolicy:PSP能实现的5种主要安全策略 1. 特权模式限制2. 宿主机资源隔离3. 用户和组管理4. 权限提升控制5. SELinux配置 💖The Begin💖点点关注,收藏不迷路💖 Kubernetes的PodSecurityPolicy(PSP)是一个关键的安全特性,它在Pod创建之前实施安全策略,确保P