uniapp 調用藍牙接收數據、發送指令后接收返回結果


一、連接藍牙設備

1.初始化藍牙

先判斷本機的藍牙是否打開

           initBle() {
				console.log('--------------------初始化藍牙----------------');
				this.bleDevs = [];
				uni.openBluetoothAdapter({
					success: (res) => { //已打開
						uni.getBluetoothAdapterState({ //藍牙的匹配狀態
							success: (row) => {
								console.log(row)
								// 開始搜索藍牙設備
								this.startBluetoothDeviceDiscovery()
							},
							fail(error) {
								uni.showToast({
									icon: 'none',
									title: '查看手機藍牙是否打開'
								});
							}
						});

					},
					fail: err => { //未打開 
						uni.showToast({
							icon: 'none',
							title: '查看手機藍牙是否打開'
						});
					}
				})
			},

2.搜索藍牙

// 開始搜索藍牙設備
			startBluetoothDeviceDiscovery() {
				let _this = this
				uni.startBluetoothDevicesDiscovery({
					success: (res) => {
						console.log('搜索藍牙外圍設備完成', res)
						_this.timer1 = setTimeout(() => { //加個延遲、目的是為了設備搜索完畢再獲取列表,不然獲取為空列表
							// 獲取設備列表
							_this.onBluetoothDeviceFound()

						}, 1000)

					},
					fail: (err)=> {
						console.log(err)
					}
				})
			},

3.獲取設備列表

// 獲取設備列表
			onBluetoothDeviceFound() {
				let that = this
				uni.getBluetoothDevices({
					success: function(res) {
						//過濾掉name為空的設備
						var bluetoothArr = res.devices.filter(function(obj) {
							return obj.name != ""
						})
						that.bleDevs = bluetoothArr
					},
					fail: function() {
						console.log("搜索藍牙設備失敗");
						uni.showToast({
							title: '搜索藍牙設備失敗或附件暫無開啟的藍牙設備',
							icon: 'none',
							duration: 2000
						})
					},
					complete: function() {
						console.log('搜索完成')
						//設備獲取完成之后  停止搜索
						uni.stopBluetoothDevicesDiscovery({
							success(res) {
								console.log('停止搜索藍牙', res)
							}
						})
					}
				})
			},

4.連接設備

//選擇設備連接把deviceId傳進來
			createBLEConnection(deviceId) {
				let that = this
				this.deviceId = deviceId
				this.pageLoading = true
				//連接藍牙
				uni.createBLEConnection({
					// 這里的 deviceId 需要已經通過 createBLEConnection 與對應設備建立鏈接
					deviceId: this.deviceId,
					success(res) {
					console.log("藍牙連接成功", res)
						that.timer2 = setTimeout(() => {
							// 設置最大傳輸字節  這里根據情況自己設置
							uni.setBLEMTU({
								deviceId: that.deviceId,
								mtu: 500,//傳輸字節數
								success() {
									// 獲取已連接設備列表
									that.getConnectedBluetoothDevices()
									// 連接成功之后  把已連接的設備從設備列表中刪除
									let index = ''
									that.bleDevs.forEach((i, key) => {
										if (i.deviceId == that.deviceId) {
											index = key

										}
									})
									if (index !== '') {
										that.bleDevs.splice(index, 1)
									}
									
									that.pageLoading = false
									//獲取服務 
									// that.getBLEDeviceServices()
								}
							})
						}, 1000)

					},
					fail(res) {
						console.log("藍牙連接失敗", res)
						uni.showToast({
							icon: 'none',
							title: '藍牙連接失敗'
						})
					}
				})
			},

二、接收數據

只有設備的特征值支持notify 才能接收數據

1. 獲取設備服務列表

//獲取藍牙的所有服務
			getBLEDeviceServices(deviceId) {
				let that = this
				uni.getBLEDeviceServices({
					deviceId: deviceId,
					success: (res) => {
						console.log("獲取服務成功",res)
						//這里會獲取到好多個services  uuid  根據實際情況選擇自己需要的服務
						console.log("services", res.services)
						if (res.services.length > 0) {
							let serviceId = res.services[2].uuid //根據我們的設備  使用的是第三個服務
							that.serviceId=res.services[2].uuid
							//獲取服務特征
							this.getBLEDeviceCharacteristics(deviceId, serviceId)
						}

					},
					fail(res) {
						console.log("獲取藍牙失敗", res)
					}
				})
			},

2. 獲取藍牙特征

如果 notify:true 或indicate :true 支持接收數據 write:true 支持發送數據 read:true 支持讀取數據

//獲取藍牙特征
			getBLEDeviceCharacteristics(deviceId, serviceId) {
				console.log("------------------進入特征------------------");
				let that = this
				uni.getBLEDeviceCharacteristics({
					deviceId: deviceId,
					serviceId: serviceId,
					success: (res) => {
						console.log("res.characteristics.", res.characteristics)
						that.characteristics = res.characteristics
						// 這里哪個特征支持notify或indicate  就選擇哪個
						that.characteristicId = res.characteristics[0].uuid // 接收數據的特征uuid
						that.characteristicId2 = res.characteristics[1].uuid  //發送數據的特征uuid
						that.notifyBLECharacteristicValueChange(deviceId,serviceId,that.characteristicId)
					},
					fail: (res) => {
						console.log(res)
					}
				})
			},

3. 接收設備數據

// 啟用 notify 功能
			notifyBLECharacteristicValueChange(deviceId,serviceId,characteristicId) {
				let that = this
				uni.notifyBLECharacteristicValueChange({
					state: true, // 啟用 notify 功能
					deviceId: deviceId,
					serviceId: serviceId,
					characteristicId: characteristicId,
					success: (res) => {
						//監聽設備發送數據
						uni.onBLECharacteristicValueChange((res) => {
							console.log("監聽成功", res.value)
							// ArrayBuffer
							//res.value是ArrayBuffer類型的,轉換成需要的格式,我們再進行操作
							//這是轉換成ASCII碼
							let str =that.ab2ascii(res.value)
							//轉換后的數據
							that.data = str
						})
					},
					fail: (res) => {
						console.log('啟用 notify 功能失敗', res)
						uni.showToast({
							icon:'none',
							title:'設備暫不支持接收數據',
							duration:3000
						})
					}
				})
			},
			// 二進制流轉ascii
			ab2ascii(buffer) {
				var str = Array.prototype.map.call(
					new Uint8Array(buffer),
					function(bit) {
						return String.fromCharCode(bit);
					}
				)
				return str.join('');
			},
			

三、向設備發送數據,並接收返回數據

發送數據和接收數據的操作類似 先獲取服務和支持write的藍牙特征,支持write的特征寫入數據 、支持notify 接收數據

// 向藍牙寫入數據
			BleWrite(instruction) {
				//instruction  寫入的數據
				let _this = this
				let serviceId = _this.serviceId
				//characteristicId2  是支持write 特征uuid
				let characteristicId = _this.characteristicId2

				let deviceId = _this.deviceId
				//轉換數據格式
				const buffer = _this.asciiToArrayBuffer(instruction);
				uni.writeBLECharacteristicValue({
					deviceId, // 藍牙設備 deviceId
					serviceId, // 藍牙服務uuid,即第二個uuid
					characteristicId, // 藍牙特征值的 (即 writeId)
					value: buffer, // 這里的value是ArrayBuffer類型
					writeType: 'write',
					success(res) {
						console.log('指令下發成功==', res)
						//寫入成功之后  如需接收數據   在上面的接收數據處獲取返回的結果
					},
					fail(err) {
						console.log('指令發送失敗', err)
						uni.showToast({
							icon: "none",
							title: "指令發送失敗",
							duration: 3000
						})
					}
				})
			},
			// ascii  轉  二進制流
			asciiToArrayBuffer(str) {
				if (!str) {
					return new ArrayBuffer(0);
				}
				var buffer = new ArrayBuffer(str.length);
				// let dataView = new DataView(buffer)
				var bufView = new Uint8Array(buffer);
				for (var i = 0, strLen = str.length; i < strLen; i++) {
					bufView[i] = str.charCodeAt(i);
				}
				return buffer;
			},

原創文章:https://blog.csdn.net/weixin_45581505/article/details/123565761


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM