# data_visual_bluetooth **Repository Path**: jiaqinbi/data_visual_bluetooth ## Basic Information - **Project Name**: data_visual_bluetooth - **Description**: 微信小程序,功能包含蓝牙扫描连接、数据可视化(echarts)。仅供个人交流学习使用。 - **Primary Language**: JavaScript - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 3 - **Forks**: 3 - **Created**: 2021-07-09 - **Last Updated**: 2024-05-16 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README 以下文档为开发指南,请点击[使用指南](user_guide.md) # 一、准备工作 ## 1、注册开发者账号(小程序) 1. 首先进入微信公众平台进行注册,网址如下:https://mp.weixin.qq.com/ ![image-20210423154455886](pic/id creator1.png) 2. 使用邮箱进行注册,邮箱必须是没有在微信公众平台注册过的。如下所示: image-20210423155212861 3. 收到激活邮件,进行激活,如下所示: ![image-20210423160350759](pic/id creator3.png) 4. 主题选择个人时需要填写主体信息(包括姓名、身份证号码、手机号码),填写完成后需使用手机号绑定的微信号扫码确认,并进一步弹窗确认。如下所示: ![image-20210423160629125](pic/id creator4.png) 5. 确定后,进入微信公众平台-小程序首页,可以看见小程序发布流程,如下所示: ![image-20210423160753724](pic/id creator5.png) ## 2、下载开发工具 下载网址:https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html 一般选择稳定版,如下所示: ![image-20210423162007246](pic/software.png) ## 3、总结 1和2做完之后用户便拥有了自己`AppID`和开发者工具,在第二章中会进行小程序创建和配置的介绍。 # 二、创建工程 打开微信开发者工具,微信扫描进行账号登录。 ## 1、创建步骤 新建工程,如下所示: ![image-20210423162459512](pic/cre prj1.png) 在上图中填入项目名称、路径、第一章第一节中申请到的`AppID`。后端服务选择本地开发,使用`javascript`。使用云开发与不使用云开发的区别此处不做介绍。 创建完成之后,首页如下所示: ![image-20210423162944453](pic/cre prj2.png) 顶部工具栏可以选择编译以及调试模式,使用`windows`开发蓝牙小程序必须使用手机进行调试。 ![image-20210423163215890](pic/cre prj3.png) ## 2、预览与真机调试的区别 预览与真机调试的区别: - 预览直接在手机上预览使用,电脑上无法查看输出信息; - 真机调试时手机上的输出可以在电脑上显示,同时可以命令交互,但是与电脑模拟的区别就是手机调试时可能出现卡顿延迟。 ## 3、工程结构介绍 ```python 工程名/ | -- pages/ #页面文件 | | -- index/ #页面1---index | | |-- index.js #index页面的后台函数文件 | | |-- index.json #inedx页面的配置文件 | | |-- index.wxml #index页面的UI设计标签文件 | | |-- index.wxss #index页面的渲染文件 | | -- log/ #页面2---log | | |-- log.js | | |-- log.json | | |-- log.wxml | | |-- log.wxss | -- utils/ #自动生成 | | -- utils.js #公用的工具相关代码文件 | -- app.js #全局js文件 | -- app.json #全局配置文件 | -- app.wxss #全局页面渲染文件 | -- project.config.json #工程配置文件,包括AppID | -- sitemap.json #基本没用到 ``` ## 4、工程配置 在`app.json`中的`appid`属性中可以配置自己的`AppID`,如果前期创建的工程使用的是测试号就可以通过此属性进行绑定。 其它配置属性较多,用到时再进行相关介绍,也可参考官网[全局与页面配置](https://developers.weixin.qq.com/miniprogram/dev/framework/config.html) ## 5、新建页面 1. 方式一 在全局`app.json`中的pages属性中按照格式填写需要添加的页面,首页放在最开始,填写完成保存之后会自动创建添加页面的所有文件。 如创建一个data页面放在首页,代码如下所示: ```json "pages":[ "pages/data/data", "pages/index/index", "pages/logs/logs" ], ``` 添加完成之后保存会自动编译运行,也可以点击顶部编译按钮运行,可以看到默认页面效果和添加的文件。如下所示: ![image-20210423170015851](pic/cre prj4.png) 2. 方式二(不推荐) 手动在`pages`文件夹下一一创建文件。 **注**:后续所有新建的页面都保存在pages目录下(当然也可以自己新建,但为了清晰的目录结构一般新建的页面都保存在`pages`下)。 注意小程序开发过程中使用真机模拟时需保持电脑联网。 ## 6、语言介绍 1. 页面布局:页面布局使用的标签语言,与`HTML`(超文本标记语言)类似; 语法参考官网[WXML语法参考](https://developers.weixin.qq.com/miniprogram/dev/reference/wxml/) 2. 页面样式:页面的样式表使用的也是层叠样式表,与`CSS`类似; 语法参考官网[WXS语法参考](https://developers.weixin.qq.com/miniprogram/dev/reference/wxs/) 3. 功能函数:写功能函数的语言是`javascript`,是脚本语言; 语法通用,可参考菜鸟教程[菜鸟javascript教程](https://www.runoob.com/js/js-tutorial.html) # 三、TabBar的使用 ## 1、TabBar的介绍 `tabBar`可以实现类似微信底部的菜单显示和切换效果。 ## 2、 自定义 TabBar 自定义 `tabBar `可以让开发者更加灵活地设置 `tabBar `样式,以满足更多个性化的场景。开发步骤如下: 1. 在 `app.json` 中的 `tabBar` 项指定 `custom` 字段,同时其余 `tabBar` 相关配置也补充完整。 2. 所有 tab 页的 json 里需声明 `usingComponents` 项,也可以在 `app.json` 全局开启。 **==注意==**:自行编写时将`custom`修改为true时不显示`tabbar`,所以本次采用2中的前一个方法,局部开启。 效果如下所示: ![image-20210406144013605](pic/image-20210406144013605.png) ## 3、TabBar的升级 一般有些底部工具栏中间的一部分会凸起,比如本项目中的蓝牙设备连接,先看例子 ![image-20210406153121996](pic/image-20210406153121996.png) 开发步骤如下: 1. 复制网上提供的`custom-tab-bar`自定义工具栏代码至到项目根目录。 2. `app.json中tabBar`不变,打开`custom-tab-bar/index.js`,按照格式修改`list`下的列表文件,注意最中间显示的需要凸起的项中`text`删去,加入配置`bulge:true`。 3. 依次打开每个`tabBar`列表中的`js`文件,从左往右数,下标第一个是0,第二个是1,依次往后(4中需要用到)。 4. 每个`tabBar`列表中的js文件中的生命周期函数`onShow`中加入如下代码(下标为3中提到的下标): ```javascript /** * 生命周期函数--监听页面显示 */ onShow: function () { if (typeof this.getTabBar === 'function' && this.getTabBar()) { this.getTabBar().setData({ selected: 下标 }) } }, ``` 5. 至此修改结束 # 四、蓝牙连接 ## 1、官方demo 请点击[官方demo](https://developers.weixin.qq.com/s/pQU51zmz7a3K)进行预览(需安装微信开发者工具)。 ## 2、方法介绍 ### openBluetoothAdapter **功能**:初始化蓝牙模块。 代码如下所示: ```js /** * 打开蓝牙适配器 */ openBluetoothAdapter() { wx.openBluetoothAdapter({ //判断蓝牙是否打开 success: (res) => { console.log('蓝牙适配器已打开', res) this.startBluetoothDevicesDiscovery() }, fail: (res) => { if(res) wx.showModal({ showCancel: false, //不显示取消按钮 content: '请先开启手机蓝牙,然后重试!' }) } }) } ``` ### startBluetoothDevicesDiscovery **功能**:扫描附近的蓝牙外围设备。此操作比较耗费系统资源,连接到设备后可即刻停止搜索。 代码如下所示: ```js /** * 蓝牙扫描 */ startBluetoothDevicesDiscovery() { if (this._discoveryStarted) { return } this._discoveryStarted = true //第一次点击扫描之后设置为true,防止重复点击 wx.startBluetoothDevicesDiscovery({ allowDuplicatesKey: true, //允许重复上报同一设备 interval:0, //上报设备的间隔。0 表示找到新设备立即上报,其他数值根据传入的间隔上报 powerLevel: "high", //扫描模式,越高扫描越快,且越耗电 success: (res) => { console.log('开始搜寻蓝牙设备', res) this.setData({ scan_status: true, btn_scan_name: '正在扫描', btn_kill_service_status: false, }) this.onBluetoothDeviceFound() }, }) } ``` ### onBluetoothDeviceFound **功能**:监听寻找到新设备的事件。 代码如下所示: ```js /** * 监听蓝牙设备 并回调 */ onBluetoothDeviceFound() { wx.onBluetoothDeviceFound((res) => { //将查找到的蓝牙名称加入到数组中 res.devices.forEach(device => { all_devices[device.deviceId] = device.name 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) this.setData({ bluetooth_list: all_devices, }) }) }) } ``` ### createBLEConnection **功能**:连接低功耗蓝牙设备。若小程序在之前已有搜索过某个蓝牙设备,并成功建立连接,可直接传入之前搜索获取的 `deviceId `直接尝试连接该设备,无需进行搜索操作。 代码如下所示: ```js /** * 蓝牙连接 * @param {*} e */ createBLEConnection(e) { const ds = e.currentTarget.dataset const deviceId = ds.deviceId //uuid const name = ds.name wx.createBLEConnection({ deviceId, success: (res) => { wx.showToast({ title: '连接成功', duration:500, //提示延迟时间 }) app.globalData.bluet_conn_flag = true, this.getBLEDeviceServices(deviceId) //获取 Service UUID this.setData({ bluet_conn_flag: true, //蓝牙连接成功 name, deviceId, //改变按钮状态 btn_scan_status: true, btn_stop_scan_status: true, btn_conn_status: false, }) this.stopBluetoothDevicesDiscovery() //连接之后停止蓝牙搜索 }, fail(e) { ... //省略 } }) } ``` ### getBLEDeviceServices **功能**:获取蓝牙设备所有服务(service),即`服务UUID`。 代码如下所示: ```js /** * 获取 service UUID * @param {*} deviceId */ getBLEDeviceServices(deviceId) { wx.getBLEDeviceServices({ deviceId, success: (res) => { let serviceUUIDs = new Array() //存储服务UUID console.log('deviceId:'+deviceId) console.log('res.services.length:'+res.services.length) //3个service uuid for (let i = 0; i < res.services.length; i++) { console.log('res.services['+i+'].uuid: '+res.services[i].uuid) if (res.services[i].isPrimary) { //判断服务是否为主服务 serviceUUIDs.push(res.services[i]) } } this.setData({ serviceUUIDs: serviceUUIDs }) //监听特性值,通过服务UUID选择监听 this.getBLEDeviceCharacteristics(deviceId, res.services[this.data.leftPosition].uuid,this.data.leftPosition) }, fail: (res) => { ...//省略 } }) } ``` ### getBLEDeviceCharacteristics **功能**:获取蓝牙设备某个服务中所有特征值(characteristic),即`特性UUID`。 代码如下所示: ```js /** * 获取蓝牙特性UUID信息 * @param {*} deviceId * @param {*} serviceId * @param {*} lastPosition */ getBLEDeviceCharacteristics(deviceId, serviceId, lastPosition) { wx.getBLEDeviceCharacteristics({ deviceId, serviceId, success: (res) => { let characteristicUUIDs = new Array() //将某个服务下的特性UUID添加到数组中 for (let i = 0; i < res.characteristics.length; i++) { let item = res.characteristics[i] characteristicUUIDs.push(item) } this.setData({ characteristicUUIDs: characteristicUUIDs }) }, fail(res) { ... //省略 } }) } ``` ### onBLECharacteristicValueChange **功能**:监听低功耗蓝牙设备的特征值变化事件。必须先启用 `notifyBLECharacteristicValueChange` 接口才能接收到设备推送的 `notification`。 代码如下: ```js //判断本次监听的特性值是否支持读写 if (properties.indicate || (properties.notify && properties.read && properties.write)) { app.globalData.characterRWN_conn_flag = true that.setData({ canWrite: true, characterRWN_conn_flag: true, characterRWN_UUID: characteristicId, serviceRWN_UUID: serviceId, }) wx.notifyBLECharacteristicValueChange({ deviceId, serviceId, characteristicId, state:true, success(res) { console.log('notifyBLECharacteristicValueChange success', res.errMsg) } }) }else{ wx.showToast({ title: '此服务不支持读写!', icon:'error', duration:1500, //提示延迟时间 }) } //notifyBLECharacteristicValueChange函数监听之后就可以接收数据 wx.onBLECharacteristicValueChange(function (res) { let hexStr = ab2hex(res.value) //ab2hex函数是将接收到数据转化成十六进制 that.setData({ receive_data: that.hexCharCodeToStr(hexStr), }) } ``` ### wx.closeBluetoothAdapter **功能**:关闭蓝牙模块。调用该方法将断开所有已建立的连接并释放系统资源。建议在使用蓝牙流程后,与 wx.openBluetoothAdapter 成对调用。 代码如下: ```js wx.closeBluetoothAdapter({ success (res) { //关闭蓝牙的一些处理 } }) ``` ## 3、连接流程 1. 打开蓝牙 2. 扫描蓝牙设备 3. 连接蓝牙,保存`设备ID`和`服务UUID` 4. 根据每个`服务UUID`监听其对应的`特性UUID` 5. 判断每个`特性UUID`的属性是否支持读写 6. 功能建立能够读写的设备之后便可以进行设备的`特征值`监听。 # 五、数据可视化(ECharts) ## 1、准备工作 1、[ECharts官网](https://echarts.apache.org/zh/tutorial.html#%E5%9C%A8%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F%E4%B8%AD%E4%BD%BF%E7%94%A8%20ECharts) 2、[插件下载](https://github.com/ecomfe/echarts-for-weixin) 3、复制`\ec-canvas`文件夹到微信小程序项目的根文件目录 ## 2、配置 在对应需要引入`echart`的`page`下的`json`文件中加入配置项,如下 ```json "usingComponents": { "ec-canvas": "../../ec-canvas/ec-canvas" } ``` **注意**:此配置项只能在对应需要引入`echart`的`page`中的`json`文件中加入,在全局的`app.json`中加入无效! ## 3、简单示例 **注意**:以下例子以`pages/data/data`页面为例 1、`wxml`文件中 页面布局代码如下 ```html ``` 2、`wxss`文件中 样式表代码如下 ```css .container { position: absolute; top: 0; bottom: 0; left: 0; right: 0; display: flex; flex-direction: column; align-items: center; justify-content: space-between; box-sizing: border-box; } ec-canvas { width: 100%; height: 100%; } ``` 3、`js`文件中 脚本如下 ```js //1 引入echarts import * as echarts from '../../ec-canvas/echarts'; const app = getApp(); //2 初始化图表函数 function initChart(canvas, width, height, dpr) { const chart = echarts.init(canvas, null, { width: width, height: height, devicePixelRatio: dpr // new }); canvas.setChart(chart); var option = { title: { text: '测试下面legend的红色区域不应被裁剪', left: 'center' }, color: ["#37A2DA", "#67E0E3", "#9FE6B8"], legend: { data: ['A', 'B', 'C'], top: 50, left: 'center', backgroundColor: 'red', z: 100 }, grid: { containLabel: true }, tooltip: { show: true, trigger: 'axis' }, xAxis: { type: 'category', boundaryGap: false, data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'], // show: false }, yAxis: { x: 'center', type: 'value', splitLine: { lineStyle: { type: 'dashed' } } // show: false }, series: [{ name: 'A', type: 'line', smooth: true, data: [18, 36, 65, 30, 78, 40, 33] }, { name: 'B', type: 'line', smooth: true, data: [12, 50, 51, 35, 70, 30, 20] }, { name: 'C', type: 'line', smooth: true, data: [10, 30, 31, 50, 40, 20, 10] }] }; chart.setOption(option); return chart; } Page({ onShareAppMessage: function (res) { return { title: 'ECharts 可以在微信小程序中使用啦!', path: '/pages/data/data', success: function () { }, fail: function () { } } }, data: { ec: { onInit: initChart } }, onReady() { } }); ``` 4、效果如下所示 ![image-20210416104829785](pic/image-20210416104829785.png) ## 4、**==引入动态数据==** ### 思路 大体上采用定时器实现 1. 考虑需要显示的数据点的个数 2. 创建一个定长数组,采用队列的形式存入最新的数值 3. 创建一个定时器,定时更新数据 4. 定时更新曲线上的数据 ### 具体实现 1、创建数组,代码如下所示 ```js /* * 以下代码均写在Page外面,以保证最先执行 */ var length = 7 //坐标轴上数据点的个数 var array_data1 = [length]; //长度为7的数组 ``` 2、创建更新数组的函数,代码如下所示 ```js /* * 以下代码均写在Page外面,以保证最先执行 */ function addData(shift) { //加入数据 array_data1.push(Math.random()*30 + 0); if (shift) { array_data1.shift();//删除当前数组第一个数据 } } //首次初始化填充数组 for (var i = 0; i < length; i++) { addData(); } ``` 3、创建定时器更新数据,代码如下所示 ```js /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { setInterval(() => { addData(true) chart.setOption({ series: { data: array_data1 }, }); },1000) }, ``` 在生命周期中进行更新,当然也可以在`onShow`等其它函数中定时更新,但是必须保证此函数在页面首次加载时会执行一次。 4、更新数据 - 将例子中的`initChart()`函数中的`chart`修改成全局变量,保证定时器可得到此变量 - 修改`series`中的`data`属性值为`array_data1`,如下所示 ```js series: [{ name: 'A', type: 'line', smooth: true, //data:[12, 50, 51, 35, 70, 30, 20] data: array_data1 }] ``` ### 总结与演示 至此,动态数据添加完毕,然后横坐标需要动态修改和上面类似。效果如下所示 折线图动态数据 ## 5、样式表的使用 ### 横坐标45°显示以及间隔显示 ```js axisLabel: { interval:0, //X轴不间隔显示,没有此属性的时候间隔显示是因为X轴每个点的名称太长,设置为1则表示间隔一个显示,以此类推 rotate:45, //代表逆时针旋转45度 } ``` ### 横坐标不从零刻度开始 在`xAxis`中加入`boundaryGap`属性,并设置为`true` ### 曲线上显示数据点 在`series`中加入`itemStyle`属性,如下所示 ```js //折线图上显示数据点 itemStyle: { normal: { label: { show: true } } } ``` 柱状图和上面一样。 ### 修改图表样式 如曲线图修改为柱状图,只需修改`series`中的`type`属性为`bar`即可。 line为折线图,bar为柱状图,具体的可以进[echart官网](https://echarts.apache.org/zh/index.html)查询。 ### 修改曲线上数据点圆圈的大小 在`series`中加入`symbolSize: 10`,10表示折线点上小圆圈的大小 ### 图例修改 ```js legend: { // icon: 'rect', //提供'circle', 'rect', 'roundRect', 'triangle', 'diamond', 'pin', 'arrow', 'none' itemWeight: 7, //修改icon图形大小 textStyle: { fontSize: 13, color: '#000' }, show:true, //是否显示图例 type:"plain", //图例样式 data: array_dataName, // top: '3%', right:'7%', // left: 'right', orient: 'vertical', z: 100 }, ``` ## 6、问题以及解决方法 ### 真机模拟时画面不清晰 此问题在苹果7上测得发现! 可以通过获取像素比的方法清晰化,代码如下所示 ```js //获取像素比 const getPixelRatio = () => { let pixelRatio = 0 wx.getSystemInfo({ success: function (res) { pixelRatio = res.pixelRatio }, fail: function () { pixelRatio = 0 } }) return pixelRatio } ``` 然后在`echarts.init`中给属性`devicePixelRatio`设置像素比,代码如下所示 ```js var dpr = getPixelRatio() const chart = echarts.init(canvas, null, { width: width, height: height, devicePixelRatio: dpr }); ``` ### EChart层级过高覆盖其它组件 通过修改`Echart `所在`view`的`top`或者`bottom`来调整距离。 # 六、Picker与showToast ## 1、picker组件 picker组件为从底部弹起的滚动选择器。 [官方picker](https://developers.weixin.qq.com/miniprogram/dev/component/picker.html) [博客园picker参考](https://www.cnblogs.com/mibear/p/8051370.html) 效果如下,点击按钮时从底部弹出选择器: image-20210417161333075 ## 2、消息提示组件 1. showToast [showToast官方文档](https://developers.weixin.qq.com/miniprogram/dev/api/ui/interaction/wx.showToast.html) # 七、蓝牙开发知识 ## 1、UUID `UUID`可以简单理解为编号,唯一的编号,用于区分不同的个体。服务和特性都有各自的UUID。 ![image-20210417155942996](pic/image-20210417155942996.png) 上图中的`Read`, `Notify`,`Write_Without_Response`为该`Characteristic UUID`所具有的属性 ## 2、服务UUID(Service UUID) 服务(Service)可以理解为组长,一个组里面至少有一个或多个特性(Characteristic),特性(Characteristic)可以理解为组员。不同的服务(Service)应该有不同的编号(UUID),用以区分不同的服务(Service)。 ## 3、特性UUID(Characteristic UUID) 特性(Characteristic)是依附于某个服务(Service)的,可以理解为组员,每个组员至少要有一个编号(UUID)以及一个或多个属性(Property)每个特性(Characteristic)可以同时有一个或多个属性。 ## 4、属性(Property) **==Read==**: 读属性,具有该属性的UUID 是可读的,也就是说这个属性允许手机来读取一些信息。手机可以发送这个指令来读取某个具有读属性UUID的信息,华茂的模块在读取的时候,会返回模块的蓝牙地址。 **==Notify==**: 通知属性, 具有该属性的 UUID是可以发送通知的,也就是说具有这个属性的特性(Characteristic)可以主动发送信息给手机。举个栗子,华茂蓝牙模块发送数据给手机,就是通过这个属性。 **==Write==**: 写属性, 具体该属性的 UUID 是可以接收写入数据的。通常手机发送数据给蓝模块就是通过这个属性完成的。这个属性在Write 完成后,会发送写入完成结果给手机,然后手机再可以写入下一包,这个属性在写入一包数据后,需要等待应用层返回写入结果,速度比较慢。 **==WriteWithout Response==**:写属性,从字面意思上看,只是写,不需要返回写的结果,这个属性的特点是不需要应用层返回,完全依靠协议层完成,速度快,但是写入速度超过协议处理速度的时候,会丢包。华茂的蓝牙模块,Read(读)和Notify(通知)是固定的属性,不能移除和修改,您可以根据需要配置Write(写)的属性。 ## 5、错误码 | 错误码 | 错误信息 | 说明 | | :----- | :------------------- | :-------------------------------------------- | | 0 | ok | 正常 | | -1 | already connet | 已连接 | | 10000 | not init | 未初始化蓝牙适配器 | | 10001 | not available | 当前蓝牙适配器不可用 | | 10002 | no device | 没有找到指定设备 | | 10003 | connection fail | 连接失败 | | 10004 | no service | 没有找到指定服务 | | 10005 | no characteristic | 没有找到指定特征值 | | 10006 | no connection | 当前连接已断开 | | 10007 | property not support | 当前特征值不支持此操作 | | 10008 | system error | 其余所有系统上报的异常 | | 10009 | system not support | Android 系统特有,系统版本低于 4.3 不支持 BLE | | 10012 | operate time out | 连接超时 | | 10013 | invalid_data | 连接 deviceId 为空或者是格式不正确 | 在`devConn.js`中的`item.properties.notify || item.properties.indicate`会进行判断特征值是否支持数据通信。 # 八、问题及解决方法 ## 1、Cannot read property 'xxx' of null 有些函数在调用的时候会出现题中错误,如果是用this调用的话,则通过`var that=this`,然后用`that.函数名`调用。 ## 2、不支持空格` ` 设置`decode ="true"`,默认为false ## 3、禁止页面整体上下滚动 在需要禁止的页面的page下的json配置文件中加入`disableScroll":true`,如在data.json下 ```json { "navigationBarTitleText": "实时数据", "disableScroll":true } ``` ## 4、页面切换后自动刷新数据 ```js setInterval(() => { this.setData({ bluet_conn_flag: app.globalData.bluet_conn_flag,//蓝牙连接状态 receive_data: app.globalData.receive_data, //接收的数据 }) },1000) ``` 使用定时器实现,可在`onLoad`或者`onShow`函数中加入上述代码(较为合理的位置,当然其它进入页面时触发的函数也都可以)。 ## 5、Failed to fetch ![image-20210417114717742](pic/image-20210417114717742.png) 遇到上述情况请检查网络连接状态! # 九、小程序发布 1. 编译之后点击右上角上传按钮进行上传; 2. 弹窗填写版本号和备注点击上传按钮即可; 3. 打开微信公众平台使用之前创建的账号登录,选择左边菜单栏的版本管理; 4. 在版本管理最下面可以看到自己提交的内容,可以点击提交审核,填写如下内容 ![uplode3](pic/uplode3.png) 5. 点击提交审核即可; 6. 提交审核至审核成功前会在审核版本中进行显示,此时若需要开发者之外的用户使用,可将开发版本设为体验版; 7. 审核成功后会在线上版本中显示。 8. 点击设置可以进行小程序码的下载。