@Loole

系统概述

基于前端芯片心率传感器ADS1292,温度传感器LMT70,加速度传感器mpu6050,蓝牙通信模块和stm32f103ZET6设计制作无线运动传感节点,能够稳定采集使用者的心电信息、体表温度和运动信息,并且采用微信小程序开发,将数据实时显示在手机或pad端。

具体实现

(一)通信模块:

  1. 采用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、+++:退出透传模式

  1. 采用HC-08蓝牙通信模块
    (1)引脚说明:
    两模块共地,两模块共VCC(VCC取5V);蓝牙模块的RX接转换模块的TX,蓝牙模块的TX接转换模块的RX
    (2)模块介绍:
    具有两种工作模式:命令响应工作模式和自动连接工作模式
    当模块处于自动连接工作模式时,将自动根据事先设定的方式连接的数据传输;
    当模块处于命令响应工作模式时能执行AT命令,用户可向模块发送各种AT指令,微模块设定控制参数或发布控制命令
    进入命令响应工作模式方法:
    模块上电,未配对情况下就是AT模式,波特率为模块本身的波特率,默认:9600,发送一次AT指令需要置高一次PIO11;
    PIO11置高电平后,再给模块上电,此时模块进入AT模式,波特率固定为:38400,可以直接发送AT指令。

(二)微信小程序端

  1. 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连接打开失败!');
  })
  }
  1. 蓝牙通信
    根据微信小程序所给出的蓝牙模块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. 微信小程序界面端
    首页界面:

    监测数据界面:

    心电图界面:
    由于一直在做滤波算法,导致小程序端的心电图没有展示,所以这里展示电脑调试时获取的心电图

    心电图实时更新:
    哦,不能上传视频,所以…,下一项

思考与总结

  1. 遇到的问题及解决方案:
    (1)微信小程序所支持的蓝牙设备为4.0BLE低功耗蓝牙设备(也就是说HC-05蓝牙模块是不支持的)
    (2)微信小程序对蓝牙模块的参数进行获取时,切记要把所有service下的characteristic中特征值全部查看,只要有一个支持监听,就可以监听相应services下的characteristic服务
    (3)我们当时看到的题目要求是将温度,心率等实时数据显示在(除电脑外)手机、ipad等设备,于是便自己做了一个微信小程序的开发,但是当时验收时,老师说“你们怎么没有用显示屏(单片机上的显示屏),没有显示屏,怎么知道你们的数据正不正确(茫然…)”,在此想和各位同学说,一定要看清题目和重点(“等设备”),切记切记。
  2. 总结:
    经历这次电赛,虽然没有达到预期的期望,但是也在短短的时间内,经过三个人的艰苦奋斗(嗯,没错,就是艰苦奋斗,三天时间,两个晚上在实验室度过),将部分功能实现了(并且也成功入手了一个小程序),所以想找个机会把这次经历记录下来。