序言

序言不会写,怎么简单怎么来,主要讲蓝牙向手机app传递数据怎么爬坑

概括

Ble蓝牙和uniapp数据互传的玩法,一般都是以下几步
1、初始化蓝牙 uni.openBluetoothAdapter(OBJECT)
2、开始搜索蓝牙设备 uni.startBluetoothDevicesDiscovery(OBJECT)/
3、发现外围设备 uni.onBluetoothDeviceFound(CALLBACK)
4、停止搜寻附近的蓝牙外围设备 uni.stopBluetoothDevicesDiscovery(OBJECT)
5、连接低功耗蓝牙设备 uni.createBLEConnection(OBJECT)
6、获取蓝牙设备所有服务 uni.getBLEDeviceServices(OBJECT)
7、获取蓝牙特征 uni.getBLEDeviceCharacteristics(OBJECT)
8、启用蓝牙设备特征值变化时的 notify 功能uni.notifyBLECharacteristicValueChange(OBJECT)
9、监听低功耗蓝牙设备的特征值变化 uni.onBLECharacteristicValueChange(CALLBACK)

一点点讲的话内容有点多,我贴一个大佬的代码,会用vue的应该在uniapp中写一个小程序问题不是很大,如果不会vue开发,后面我会把我自己的代码打包给大家的,只要你按照概括里面的流程就能玩起来,坑不在这里,顺便提一嘴坑也不在uni.readBLECharacteristicValue(OBJECT),ble低功耗蓝牙只是一个透传模块,不用考虑太多具体的细节

主要内容
终于正文了~,相信大家玩蓝牙通信都是看过太极创客这个网站的,第一块蓝牙买HC-06的不知道多不多,我的第一块蓝牙就是HC-06,踩坑的绝大部分人应该都是因为看过这个HC-06的教程,为啥又买HM-10,原因必然是BLE蓝牙太过任性,HM-10的参数相信大家都看过,里面有这样一段讲的是

保护蓝牙RX引脚的方法,这1-2K大家有没有注意啊,调试大家应该都是用的串口监视器,能正常连接蓝牙HM-10,串口监视器也有输出,这里的前提是你选择的特征值notify:true,并且在uni.onBLECharacteristicValueChange(CALLBACK)这个监听方法调用前你已经调用了uni.notifyBLECharacteristicValueChange(OBJECT),change方法可以放在notify方法的成功回调中调用,成功连接后,无论在串口监视器中怎么输入数据蓝牙的就是不能回传数据,无法触发uni.onBLECharacteristicValueChange(CALLBACK)方法,这是太极创客为保护HC-06提供的一种分压接线方式
不知道有没有大佬照搬接线方式在HM-10上面的?官方文档说的很清楚1-2k电阻直接接入电路,分压电路可能会导致高电平无法达到蓝牙RX引脚需要的电压,所以蓝牙接收模块无法接收到Arduino发送来的数据,有条件的发烧友可以买HM-15,工作电压和Arduino引脚高电平完美匹配,就不用每次去分压了,我是直接接的,还是建议接一个保护电阻。

为了不让没有获取准入的用户无法获取数据,我想检测手机发过来的指定秘钥,通过才开始推数据,但是下面这段代码让我必须手动在串口监视器输入数据,uni端才能检测到数据变化,太裂开了,挖个槽后面慢慢解决吧

问题代码块:

  if (Serial.available()){delay(10); // The DELAY!bluetooth.print(sensors.getTempCByIndex(0));}

导致问题的原因官方说了

我这里用到的模块我讲讲

Arduino UNO板子,注意芯片是 ATMEGA328克隆版,买官配准没错,温度检测模块蓝牙RX引脚接个1-2k的电阻保护一下,DS18B20接线我给个图,电阻4.7k-10k之间都可以,作用是作为上拉电阻拉升电压这很重要,不然中间的输出引脚就一直输出-127,接线按下面这个图接,端口啥的选自己喜欢的就行

以下代码贴上就能跑

相关代码
Arduino代码

//我蓝牙用的3和5别搞错了
#include <SoftwareSerial.h>
#include<OneWire.h>
#include<DallasTemperature.h>
SoftwareSerial bluetooth(3, 5); // RX, TX
OneWire onewire(7);
DallasTemperature sensors(&onewire);
void setup()
{// Start the hardware serial port
Serial.begin(9600);
sensors.begin();
//pinMode(13, OUTPUT); // onboard LED
//digitalWrite(13, LOW); // switch OFF LED
bluetooth.begin(9600);
// un REM this to set up a Master and connect to a SlaveSerial.println("BLE CC41A Bluetooth");
Serial.println("----------------------------------");
Serial.println("");
Serial.println("Trying to connect to Slave Bluetooth");
delay(1000);//Serial.println("AT");// just a check
//  bluetooth.write("AT");
}
void loop()
{sensors.requestTemperatures();Serial.write("温度:");Serial.print(sensors.getTempCByIndex(0));Serial.println("摄氏度");delay(1000);
bluetooth.listen();
//这里我直接发数据,不甄别用户
bluetooth.print(sensors.getTempCByIndex(0));
//下面的代码有点问题,必须从串口监视器输入手机端才能出发uni.change方法否则挂起不动
//后续解决,必须手机端给个指定秘钥才能获取数据,数据裸奔肯定是不行的,先裸奔一会儿
//  if (Serial.available()){//  delay(10); // The DELAY!
//  bluetooth.print(sensors.getTempCByIndex(0));
//  }
while(bluetooth.available() > 0) {char inByte = bluetooth.read();
Serial.write(inByte);
}
delay(1000);}

uniapp代码文件,但是为毛不能导整个项目

//特征值我写死了的,只是为了测试,如果是其它ble最好遍历一下特征值,取出notify:true的特征值作为数据载体,请务必打开蓝牙和定位功能
<template><view>蓝牙连接信息:<br><view class="btn_con"><view v-if="this.list.length>0"><ol><li v-if=tem style="color:gold">当前温度:{{tem}}℃</li><li v-for="item in list"><view>deviceId: {{item.deviceId}}</view><view>name: {{item.name}}</view><view>RSSI: {{item.RSSI}}</view><view>localName: {{item.localName}}</view><view>advertisServiceUUIDs: {{item.advertisServiceUUIDs}}</view><view>advertisData: {{item.advertisData}}</view>                 <buttonclass="btn_sty":loading="loading":plain='true' :hover-class="'hover-class'"@click="createBLEConnection(item)">连接蓝牙</button><buttonclass="btn_sty":plain='true' :hover-class="'hover-class'"@click="closeBletoohConnection()">断开连接</button><!--下面的代码测试用的--><!--  <buttonclass="btn_sty":plain='true' :hover-class="'hover-class'"@click="getReadValue()">获取数据</button> --></li></ol></view></view></view>
</template><script>export default {data() {return {list:[],loading:false,deviceId:"",serviceId:"",shiliu:"",characteristics:[],tem:""}},onLoad() {uni.openBluetoothAdapter({success:(res)=> { //已打开uni.getBluetoothAdapterState({//蓝牙的匹配状态success:(res1)=>{console.log(res1,'“本机设备的蓝牙已打开”')   // 开始搜索蓝牙设备this.startBluetoothDeviceDiscovery()},fail(error) {uni.showToast({icon:'none',title: '查看手机蓝牙是否打开'    });}});},fail:err=>{ //未打开 uni.showToast({icon:'none',title: '查看手机蓝牙是否打开'});}})},methods:{//此方法用于向蓝牙写数据checkTem(){let thit=this;if(thit.deviceId&&thit.serviceId)uni.writeBLECharacteristicValue({// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接deviceId:thit.deviceId,// 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取serviceId:thit.serviceId,// 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取characteristicId:"0000FFE1-0000-1000-8000-00805F9B34FB",value:thit.string2buffer("1"),success:(res)=> {uni.showToast({icon:'none',title: '已开启数据监测'   });},fail:(er)=> {console.log(er)uni.showToast({icon:'none',title: '启动失败,请重试'    });}})else uni.showToast({icon:'none',title: '请先连接蓝牙设备' });},//此方法用于将字符串转为arraybuffer数据string2buffer(str) {var buf = new ArrayBuffer(str.length); // 可以str.length * 2,两个字节存一个字符,但是测试好像没啥影响,可能就是长度不同,没细测var bufView = new Uint8Array(buf);//new Uint16Array(buf)按照16读取后端传来的数据for (var i = 0, strLen = str.length; i < strLen; i++) {bufView[i] = str.charCodeAt(i);}console.log(buf)return buf;},//8位存一个字符读取数据并转字符串ab2str(buf) {return String.fromCharCode.apply(null, new Uint8Array(buf));},// 开始搜索蓝牙设备startBluetoothDeviceDiscovery(){uni.startBluetoothDevicesDiscovery({success: (res) => {console.log('startBluetoothDevicesDiscovery success', res)// 发现外围设备this.onBluetoothDeviceFound()},fail:err=>{console.log(err,'错误信息')}})},// 发现外围设备onBluetoothDeviceFound() {// console.log("zhixing")uni.onBluetoothDeviceFound((res) => {console.log(res)// ["name", "deviceId"]// 吧搜索到的设备存储起来,方便我们在页面上展示if(res.devices.length>0){res.devices.forEach(item=>{this.list.push(item)})}})},createBLEConnection(item){let thit = this//data里面建立一个deviceId,存储起来this.deviceId = item.deviceId//连接蓝牙uni.createBLEConnection({// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接deviceId:this.deviceId,success(res) {//防止在这里面取不到this,古在外面用thit存储了thisthit.stopBluetoothDevicesDiscovery()console.log(res)console.log("蓝牙连接成功")thit.getBLEDeviceServices();},fail(res) {console.log("蓝牙连接失败",res)}})},// 停止搜寻蓝牙设备stopBluetoothDevicesDiscovery(){ uni.stopBluetoothDevicesDiscovery({ success: e => {this.loading = falseconsole.log('停止搜索蓝牙设备:' + e.errMsg); },fail: e => {console.log('停止搜索蓝牙设备失败,错误码:' + e.errCode);}});},//获取蓝牙的所有服务getBLEDeviceServices(){setTimeout(()=>{uni.getBLEDeviceServices({// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接deviceId:this.deviceId,success:(res)=>{// console.log("成功",res)console.log('device services:', res)res.services.forEach((item)=>{if(item.uuid==="0000FFE0-0000-1000-8000-00805F9B34FB"){this.serviceId = item.uuid;//存储到状态//this.$store.commit("upserviceId",item.uuid)console.log(this.serviceId)// 这里获取回调,读取成功就的值就会在这个地方接收到!!!this.getBLEDeviceCharacteristics()}})}})},1000)},//获取蓝牙特征getBLEDeviceCharacteristics(){console.log("进入特征");setTimeout(()=>{uni.getBLEDeviceCharacteristics({// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接deviceId:this.deviceId,// 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取serviceId:this.serviceId,success:(res)=>{console.log(res,'特征getBLEDeviceCharacteristics')this.characteristics = res.characteristicsconsole.log(this.characteristics)this.notifyBLECharacteristicValueChange("0000FFE1-0000-1000-8000-00805F9B34FB")},fail:(res)=>{console.log(res)}})},1000);},// 启用 notify 功能notifyBLECharacteristicValueChange(characteristicId){let thit=this;uni.readBLECharacteristicValue({deviceId:thit.deviceId,// 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取serviceId:thit.serviceId,// 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取characteristicId:"0000FFE1-0000-1000-8000-00805F9B34FB",success:res=>{console.log("读取特征值成功:"+res)},fail:err=>{console.log("读取特征值失败:"+err)}})console.log(characteristicId,'characteristicId')uni.notifyBLECharacteristicValueChange({state: true, // 启用 notify 功能// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接deviceId:thit.deviceId,// 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取serviceId:thit.serviceId,// 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取characteristicId:characteristicId,success:(res)=> {console.log(res)// console.log(this.characteristicId)console.log('notifyBLECharacteristicValueChange success', res.errMsg)},fail:(res)=> {console.log('notifyBLECharacteristicValueChange success2', res.errMsg)}});thit.onBLECharacteristicValueChange();},onBLECharacteristicValueChange(){let thit=this;uni.onBLEConnectionStateChange(res => {// 该方法回调中可以用于处理连接意外断开等异常情况console.log(`device ${res.deviceId} state has changed, connected: ${res.connected}`)if (res.connected == false) {// this.dklj();                                                                                                            // this.createBLEConnection()}})uni.onBLECharacteristicValueChange(function(re){//console.log(re.value);thit.tem=thit.ab2str(re.value);console.log(thit.ab2str(re.value))//res.value是ArrayBuffer类型的,官方给了一个方法转16进制,我们再进行操作//console.log(thit.ab2hex(re.value));})},getReadValue(){let thit=this;uni.readBLECharacteristicValue({deviceId:thit.deviceId,// 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取serviceId:thit.serviceId,// 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取characteristicId:"0000FFE1-0000-1000-8000-00805F9B34FB",success:res=>{console.log("读取特征值成功:"+res)// thit.receiveCharacterValue();},fail:err=>{console.log("读取特征值失败:"+err)}});},closeBletoohConnection(){uni.closeBLEConnection({deviceId:this.deviceId,success:res=>{uni.showToast({icon:'none',title: '连接已断开...'});},fail:err=>{uni.showToast({icon:'none',title: '连接断开失败'});}});}},}</script><style scoped>.btn_con{/* margin-top:20px; */display:flex;flex-direction:row ;justify-content:flex-start;align-items:center;align-content:space-around;flex-wrap:wrap; }.hover-class{color:#ed080c;}.btn_sty{flex:1;display: inline-block;margin: 10px;color:#ee696b;border: none;}
</style>

以下是运行结果

手机上的效果

Arduino串口监视器传值,这里这是模拟,真实场景可以使用各种传感器采集的数据作为输入

uni.onBLECharacteristicValueChange(CALLBACK)已经能正常监听值的改变了

给你们看一下我的个性化接线

总结
硬件模块不正常工作的时候首先检查接入是否正确,串口是否占用、工作电压是否稳定,有条件最好别硬接,买个万用表测一下,一般模块的参数文档都不会很复杂,通过蓝牙模块把数据传输的问题解决了,就能在板子另一端加装各种传感器愉快玩耍了,最后如果这篇博客对您有帮助赶紧收藏,转载请注明转载地址,说得不对的地方请不吝指出,谢谢~

Arduino使用HM-10蓝牙模块向uniapp小程序推送数据采坑总结相关推荐

  1. uniapp苹果无法上架_uni-app开发小程序适配苹果端采坑总结

    不得不说,任何一个开发者遇到苹果手机都会或多或少需要做适配,在使用uni-app开发小程序时,我就发现不少需要兼容的地方,今天做个小结 1.由于页面大多数内容都是动态获取,当页面高度不给固定值时,让其 ...

  2. uniapp ajax数据库查询,uniapp小程序登录、数据请求方式

    index页面 手动授权按钮 exportdefault{ data() {return{ imgInfo:"",//头像 nickName:""//昵称 } ...

  3. uni-app小程序页面传值数据过长问题

    在通过url进行页面传值时,传递数据过长(如:base64图片数据)或数据包含特殊字符(如:?),这样传递的数据会不完整,而报错. 遇到这样的情况可以 转成编码格式传递 encodeURICompon ...

  4. uniapp开发小程序推送微信消息

    效果 //处理自己的逻辑freeClick() {this.getPushTempletes(()=> {this.$u.post('/fkmpPay/getExperiencePackage' ...

  5. 嵌入式单片机基础篇(二十七)之Stm32F103单片机给蓝牙模块发送AT指令程序

    Stm32F103单片机给蓝牙模块发送AT指令程序 #include "stm32f10x.h" #include "string.h" #include &q ...

  6. java基本微信小程序的快递代收派送系统 uniapp小程序

    随着时代的发展,人们生活的节奏越来越快,但是快递已经成为人们生活中的一个重要组成部分,基本每个人都会收发快递,如果这些事情全部都到快递站点进行处理,是很浪费时间和精力的一件事情.为了能够让快递代收和派 ...

  7. uniapp小程序商城开发thinkphp6积分商城、团购、秒杀 封装APP

    uniapp小程序商城开发thinkphp6积分商城.团购.秒杀 封装APP,后台是vue开发 需要源代码的可以联系我,找我要哦 <template><view v-if=" ...

  8. uniapp小程序迁移到TS

    uniapp小程序迁移到TS 我一直在做的小程序就是 山科小站 也已经做了两年了,目前是用uniapp构建的,在这期间也重构好几次了,这次在鹅厂实习感觉受益良多,这又得来一次很大的重构,虽然小程序功能 ...

  9. uniapp小程序适配异形屏

    uniapp小程序适配异形屏 App.vue写入 底部适配横线 小程序自定义顶部适配 App.vue写入 globalData: { // 适配刘海屏test: false,statusBarHeig ...

最新文章

  1. java memcached 存储对象_java – 从Memcache中获取低级别数据存储区实体对象时的慢速反序列化...
  2. 为什么放弃治疗_百度百科
  3. SecureCRT如何进入和退出全屏及调出菜单栏
  4. 输入一批整数,输出最大最小值,输入0结束
  5. linux 下 /dev和/sys/dev的区别
  6. 关于 activit 与 flowable 项目报错 --Cannot resolve the name ‘extension‘ to a (n) ‘element declaration‘ comp
  7. python调用windows aplication
  8. 开源软件生态:现状与趋势
  9. 视觉SLAM14讲笔记02:ch5针孔,双目相机模型
  10. 二清,是“担保支付”,还是“雁过拔毛”
  11. win7 IIS Web.config节点锁定问题
  12. 泰坦尼克号生存预测(超详细)
  13. 【CodeForces】Codeforces Round #686 (Div. 3) CEF
  14. 网站添加头部Meta property=og协议的使用方法详解教程
  15. 深入理解类加载机制:拨开迷雾见真章
  16. 在中国做企业要运用东方智慧--唐骏演讲
  17. iOS小技能:逆向的一般思路及入门工具
  18. [读书笔记] 哈佛最受欢迎的营销课——如何打造脱颖而出的品牌
  19. mysql 复制 错误 1007_mysql5.7.24Gtid下主从复制报错1007
  20. 面试官第一句话就把我轰出来了

热门文章

  1. java生成XML格式文件,导入MS Project生成甘特图
  2. java工程师详细工作内容_java工程师主要工作内容
  3. 张小龙近4年微信公开课演讲视频
  4. c语言 万能函数指针,C/C++编程笔记:C语言精华解析之void *指针,指针中的万能指针...
  5. 可以不用U盘一键迁移电脑软件吗
  6. java读取图片、PDF中图片上的文字
  7. 电脑系统开机就内存占用极高
  8. 矩阵中的特征值和奇异值,物理意义
  9. 苹果内购支付验签(php)
  10. 机房服务器的简单运维