@Loole
系统概述
基于前端芯片心率传感器ADS1292,温度传感器LMT70,加速度传感器mpu6050,蓝牙通信模块和stm32f103ZET6设计制作无线运动传感节点,能够稳定采集使用者的心电信息、体表温度和运动信息,并且采用微信小程序开发,将数据实时显示在手机或pad端。
具体实现
(一)通信模块:
- 采用ESP8266wifi通信模块
(1)引脚说明
VCC连接正极(有些是3.3v,有些是5v,),GND连接负极
RXD:数据的接收端(连接单片机或者USB转TTL模块的TXD)
TXD:数据的发送端(连接单片机或者USB转TTL模块的RXD)
RST:复位,低电平有效
IO_0:用于进入固件烧写模式,低电平->烧写,高电平->运行模式(默认)
(2)模块介绍
ESP8266支持3中工作模式“STA”、“AP”、“STA+AP”模式:
STA模式:该模块通过路由器连接网络,手机或电脑实现该设备的远程控制。
AP模式:该模块作为热点,手机或者电脑连接wifi与该模块进行通信,实现局域网的无线控制。
STA+AP模式:两种模式共存,既可以路由器连接到互联网,也可以作为wifi热点,使其他设备连接到这个模块,实现广域网与局域网的无缝切换。
(3)AT指令
在使用USB转TTL模块与电脑连接之后,就可以使用串口调试助手进行wifi模块的调试,AT指令不区分大小写,均以回车、换行结尾
指令名 | 含义 |
AT | 测试指令 |
AT+CWMODE= | 设置应用模式 |
AT+CWMODE? | 获得当前应用模式 |
AT+CWLAP | 返回目前的AP列表 |
AT+CWJAP= | 加入某一AP |
AT+CWJAP? | 返回当前加入的AP |
AT+CWQAP | 退出当前加入的AP |
AT+CIPSTART=,, | 建立TCP/UDP连接 |
AT+CIPMUX= | 是否启用多连接 |
AT+CIPSEND= | 发送数据 |
AT+CIPMODE= | 是否进入透传模式 |
*透传模式:指不需要关系wifi协议是如何实现的,所需要做的就是A通过串口发送数据,B通过串口接收数据,整个过程中A串口和B串口就像是用导线直接连接起来了一样,对于开发人员来看,就是完全透明的。
(4)ESP8266wifi模块的使用
1、AT+CWMODE=1:设置工作模式(STA模式)
2、AR+RST:模块重启(生效工作模式)
3、AT+CWJAP=“111”,“111111111”:连接当前环境的WIFI热点(热点名,密码)
4、AT+CIPMUX=0:设置单路连接模式
5、AT+CIPSTART=“TCP”,“xxx.xxx.xxx.xxx”:建立TCP连接
6、AT+CIPMODE=1:开启透传模式
7、AT+CIPSEND:透传模式下,传输数据
8、+++:退出透传模式
- 采用HC-08蓝牙通信模块
(1)引脚说明:
两模块共地,两模块共VCC(VCC取5V);蓝牙模块的RX接转换模块的TX,蓝牙模块的TX接转换模块的RX
(2)模块介绍:
具有两种工作模式:命令响应工作模式和自动连接工作模式
当模块处于自动连接工作模式时,将自动根据事先设定的方式连接的数据传输;
当模块处于命令响应工作模式时能执行AT命令,用户可向模块发送各种AT指令,微模块设定控制参数或发布控制命令
进入命令响应工作模式方法:
模块上电,未配对情况下就是AT模式,波特率为模块本身的波特率,默认:9600,发送一次AT指令需要置高一次PIO11;
PIO11置高电平后,再给模块上电,此时模块进入AT模式,波特率固定为:38400,可以直接发送AT指令。
(二)微信小程序端
- wifi通信:
局域网内通信:手机连接WiFi模块热点后,向wifi模块的IP地址及对应端口号发送请求,接收wifi模块发送数据
外网通信:通过向服务器发送websocket通信请求,获取服务器返回的数据,
//建立连接
wx.connectSocket({
url: "ws://192.168.43.100:8081",
header: {
'content-type': 'application/json'
},
// protocols: ['protocol1'],
success:function(){
console.log("websocket打开成功")
},fail:function(){
console.log("websocket打开失败")
}
})
let socketOpen = false
//连接成功
wx.onSocketOpen(function () {
socketOpen = true
console.log("websocket连接打开成功")
})
//发送消息
function sendSocketMessage(msg){
if(socketOpen){
wx.sendSocketMessage({
data: msg,
success: function () {
console.log("消息发送成功")
}, fail: function () {
console.log("消息发送失败")
}
})
}else{
console.log("没有连接打开成功")
}
}
//接收数据
wx.onSocketMessage(function (data) {
var objData = JSON.parse(data.data);
console.log("消息接收成功"+data);
})
},
//连接失败
onSocketError:function(){
wx.onSocketError(function () {
console.log('websocket连接打开失败!');
})
}
- 蓝牙通信
根据微信小程序所给出的蓝牙模块API,获取蓝牙模块的参数信息,在可允许情况下对蓝牙模块进行监听,一旦蓝牙模块发送数据,接收至小程序后端内,将其处理后显示
//初始化蓝牙模块
openBluetoothAdapter(){
wx.openBluetoothAdapter({
success:(res) =>{
console.log('初始化蓝牙设备成功')
this.startBluetoothDeviceDiscovery()
},
fail:(res) =>{
if(res.errCode == 10001){
wx.onBluetoothAdapterStateChange(function(res){
console.log("打开蓝牙适配器状态变化",res)
if(res.available){
this.startBluetoothDeviceDiscovery()
}
})
}
}
})
},
//检测本地蓝牙是否可用
getBluetoothAdapterState(){
wx.getBluetoothAdapterState({
success: function(res) {
console.log('获取蓝牙适配器状态',res)
if(res.discovering){
this.onBluetoothDeviceFound()
} else if(res.available){
this.startBluetoothDeviceDiscovery()
}
},
fail:function(res){
console.log("本地蓝牙不可用,未打开")
wx.showToast({
title: '蓝牙未打开',
})
}
})
},
//开始搜索蓝牙设备
startBluetoothDeviceDiscovery(){
wx.startBluetoothDevicesDiscovery({
success: function(res) {
console.log("开始搜索蓝牙设备",res)
},
})
this.onBluetoothDeviceFound()
},
//停止搜索蓝牙设备
stopBluetoothDevicesDiscovery(){
wx.stopBluetoothDevicesDiscovery({
success: function(res) {
console.log("停止搜索蓝牙设备")
},
})
},
//监听寻找到新设备的事件
onBluetoothDeviceFound() {
wx.onBluetoothDeviceFound((res) => {
res.devices.forEach(device => {
if (!device.name && !device.localName) {
return
}
const foundDevices = this.data.devices
const idx = inArray(foundDevices, 'deviceId', device.deviceId)
const data = {}
if (idx === -1) {
data[`devices[${foundDevices.length}]`] = device
} else {
data[`devices[${idx}]`] = device
}
this.setData(data)
})
})
},
//连接蓝牙
createBLEConnection(e){
const ds = e.currentTarget.dataset
this.setData({
_deviceId:ds.deviceId,
_name:ds.name
})
console.log("蓝牙连接的deviceID:"+this.data._deviceId)
console.log("蓝牙连接的名称:"+this.data._name)
wx.createBLEConnection({
deviceId: this.data._deviceId,
success: function(res) {
wx.showLoading({
title: '蓝牙连接中',
})
this.setData({
connected:true
})
this.getBLEDeviceServices(_deviceId)
},
})
this.stopBluetoothDevicesDiscovery()
},
//关闭蓝牙连接
closeBLEConnection(){
wx.closeBLEConnection({
deviceId: this.data._deviceId,
success: function(res) {
console.log("蓝牙关闭成功")
},
})
this.setData({
connected:false
})
},
//获取蓝牙的service服务,获取的serviceid有多个,要试着连接最终确定哪个稳定版本的
//service服务,之后获取特征值
getBLEDeviceService(deviceId){
wx.getBLEDeviceServices({
deviceId: deviceId,
success: function(res) {
for(let i = 0; i < res.services.length;i++){
if(res.services[i].isPrimary){
console.log("蓝牙服务的信息:"+res.services[i])
this.getBLEDeviceCharacteristics(deviceId,res.services[i].uuid)
return
}
}
},
fail:function(res){
console.log("获取蓝牙的service服务失败")
}
})
},
//获取蓝牙设备的特征值,并启动notify蓝牙监听功能,然后
//使用onBLECharacteristicValueChange用来监听蓝牙设备传递的数据信息
//接收数据和发送数据需为二进制数据,页面展示的时候进行转换
getBLEDeviceCharacteristics(deviceId,serviceId){
wx.getBLEDeviceCharacteristics({
deviceId: deviceId,
serviceId: serviceId,
success: function(res) {
console.log("获取的蓝牙设备服务的特征值:",res.characteristics)
for(let i=0;i<res.characteristics.length;i++){
let item = res.characteristics[i]
if(item.properties.read){
wx.readBLECharacteristicValue({
deviceId: deviceId,
serviceId: serviceId,
characteristicId: item.uuid,
success: function(res) {
console.log("可读蓝牙设备的具体信息:"+item.properties)
},
})
}
if(item.properties.write){
console.log("可写蓝牙设备的具体信息:"+item.properties)
}
if(item.properties.notify || item.properties.indicate){
console.log("可监听蓝牙设备的具体信息:"+item.properties)
this.data._characteristicId = item.uuid
this.writeBLECharacteristicValue()
//启动监听蓝牙功能
wx.notifyBLECharacteristicValueChange({
deviceId: this.data._deviceId,
serviceId: this.data._serviceId,
characteristicId: this.data._characteristicId,
state: true,
success: function(res) {
console.log("成功监听的蓝牙设备信息:"+res.errMsg)
//监听蓝牙设备传递数据,保证第一时间获取数据
wx.onBLECharacteristicValueChange(function (res) {
console.log("监听到的数据:"+this.buf2String(res.value))
})
},
fail:function(res){
console.log("监听失败的蓝牙设备信息:"+res)
}
})
}
}
},
})
},
//向蓝牙设备发送数据
writeBLECharacteristicValue(){
//向蓝牙设备发送一个数据
let buffer = new ArrayBuffer(1)
let dataView = new DataView(buffer)
dataView.setUint8(0, Math.random() * 255 | 0)
wx.writeBLECharacteristicValue({
deviceId: this._deviceId,
serviceId: this._deviceId,
characteristicId: this._characteristicId,
value: buffer,
})
},
//关闭蓝牙模块
closeBluetoothAdapter(){
wx.closeBluetoothAdapter({
success: function(res) {
console.log("关闭蓝牙成功")
},
})
}
- 微信小程序界面端
首页界面:
监测数据界面:
心电图界面:
由于一直在做滤波算法,导致小程序端的心电图没有展示,所以这里展示电脑调试时获取的心电图
心电图实时更新:
哦,不能上传视频,所以…,下一项
思考与总结
- 遇到的问题及解决方案:
(1)微信小程序所支持的蓝牙设备为4.0BLE低功耗蓝牙设备(也就是说HC-05蓝牙模块是不支持的)
(2)微信小程序对蓝牙模块的参数进行获取时,切记要把所有service下的characteristic中特征值全部查看,只要有一个支持监听,就可以监听相应services下的characteristic服务
(3)我们当时看到的题目要求是将温度,心率等实时数据显示在(除电脑外)手机、ipad等设备,于是便自己做了一个微信小程序的开发,但是当时验收时,老师说“你们怎么没有用显示屏(单片机上的显示屏),没有显示屏,怎么知道你们的数据正不正确(茫然…)”,在此想和各位同学说,一定要看清题目和重点(“等设备”),切记切记。 - 总结:
经历这次电赛,虽然没有达到预期的期望,但是也在短短的时间内,经过三个人的艰苦奋斗(嗯,没错,就是艰苦奋斗,三天时间,两个晚上在实验室度过),将部分功能实现了(并且也成功入手了一个小程序),所以想找个机会把这次经历记录下来。