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

序言

序言不会写,怎么简单怎么来,主要讲蓝牙向手机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 Slave

Serial.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>					
					<button
						class="btn_sty"
						:loading="loading"
						  :plain='true' 
						 :hover-class="'hover-class'"
						@click="createBLEConnection(item)">连接蓝牙
					 </button>
					 <button
					 	class="btn_sty"
					 	  :plain='true' 
					 	 :hover-class="'hover-class'"
					 	@click="closeBletoohConnection()">断开连接
					  </button>
					  <!--下面的代码测试用的-->
					<!--  <button
					  	class="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存储了this
						thit.stopBluetoothDevicesDiscovery()
						console.log(res)
						console.log("蓝牙连接成功")
						thit.getBLEDeviceServices();
						
					  },fail(res) {
						console.log("蓝牙连接失败",res)
					  }
					})
				},
				// 停止搜寻蓝牙设备
				stopBluetoothDevicesDiscovery(){ 
					uni.stopBluetoothDevicesDiscovery({ 
						success: e => {
							this.loading = false
							console.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.characteristics
					console.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)已经能正常监听值的改变了

在这里插入图片描述

给你们看一下我的个性化接线
在这里插入图片描述

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

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值