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

相关文章

Java根据IP地址实现归属地获取

《Java根据IP地址实现归属地获取》Ip2region是一个离线IP地址定位库和IP定位数据管理框架,这篇文章主要为大家详细介绍了Java如何使用Ip2region实现根据IP地址获取归属地,感兴趣... 目录一、使用Ip2region离线获取1、Ip2region简介2、导包3、下编程载xdb文件4、J

PyQt5+Python-docx实现一键生成测试报告

《PyQt5+Python-docx实现一键生成测试报告》作为一名测试工程师,你是否经历过手动填写测试报告的痛苦,本文将用Python的PyQt5和python-docx库,打造一款测试报告一键生成工... 目录引言工具功能亮点工具设计思路1. 界面设计:PyQt5实现数据输入2. 文档生成:python-

Android实现一键录屏功能(附源码)

《Android实现一键录屏功能(附源码)》在Android5.0及以上版本,系统提供了MediaProjectionAPI,允许应用在用户授权下录制屏幕内容并输出到视频文件,所以本文将基于此实现一个... 目录一、项目介绍二、相关技术与原理三、系统权限与用户授权四、项目架构与流程五、环境配置与依赖六、完整

浅析如何使用xstream实现javaBean与xml互转

《浅析如何使用xstream实现javaBean与xml互转》XStream是一个用于将Java对象与XML之间进行转换的库,它非常简单易用,下面将详细介绍如何使用XStream实现JavaBean与... 目录1. 引入依赖2. 定义 JavaBean3. JavaBean 转 XML4. XML 转 J

Flutter实现文字镂空效果的详细步骤

《Flutter实现文字镂空效果的详细步骤》:本文主要介绍如何使用Flutter实现文字镂空效果,包括创建基础应用结构、实现自定义绘制器、构建UI界面以及实现颜色选择按钮等步骤,并详细解析了混合模... 目录引言实现原理开始实现步骤1:创建基础应用结构步骤2:创建主屏幕步骤3:实现自定义绘制器步骤4:构建U

SpringBoot中四种AOP实战应用场景及代码实现

《SpringBoot中四种AOP实战应用场景及代码实现》面向切面编程(AOP)是Spring框架的核心功能之一,它通过预编译和运行期动态代理实现程序功能的统一维护,在SpringBoot应用中,AO... 目录引言场景一:日志记录与性能监控业务需求实现方案使用示例扩展:MDC实现请求跟踪场景二:权限控制与

Android实现定时任务的几种方式汇总(附源码)

《Android实现定时任务的几种方式汇总(附源码)》在Android应用中,定时任务(ScheduledTask)的需求几乎无处不在:从定时刷新数据、定时备份、定时推送通知,到夜间静默下载、循环执行... 目录一、项目介绍1. 背景与意义二、相关基础知识与系统约束三、方案一:Handler.postDel

使用Python实现IP地址和端口状态检测与监控

《使用Python实现IP地址和端口状态检测与监控》在网络运维和服务器管理中,IP地址和端口的可用性监控是保障业务连续性的基础需求,本文将带你用Python从零打造一个高可用IP监控系统,感兴趣的小伙... 目录概述:为什么需要IP监控系统使用步骤说明1. 环境准备2. 系统部署3. 核心功能配置系统效果展

Python实现微信自动锁定工具

《Python实现微信自动锁定工具》在数字化办公时代,微信已成为职场沟通的重要工具,但临时离开时忘记锁屏可能导致敏感信息泄露,下面我们就来看看如何使用Python打造一个微信自动锁定工具吧... 目录引言:当微信隐私遇到自动化守护效果展示核心功能全景图技术亮点深度解析1. 无操作检测引擎2. 微信路径智能获

Python中pywin32 常用窗口操作的实现

《Python中pywin32常用窗口操作的实现》本文主要介绍了Python中pywin32常用窗口操作的实现,pywin32主要的作用是供Python开发者快速调用WindowsAPI的一个... 目录获取窗口句柄获取最前端窗口句柄获取指定坐标处的窗口根据窗口的完整标题匹配获取句柄根据窗口的类别匹配获取句