<template>
<v-sheet
:elevation="24"
:height="1000"
:width="500"
border
color="info"
rounded
>
<v-sheet :elevation="24" border
color="info"
rounded
>
{{ bluetoothState.isSupported ? "当前浏览器支持蓝牙 Web API" : "您的浏览器不支持蓝牙 Web API" }}
</v-sheet>
<v-sheet class="direction-card" color="info">
<v-btn class="d-flex align-center justify-center" size="x-large"
@click="send('a', '前进')"
>
前进
</v-btn>
<div class="side-buttons">
<v-btn class="d-flex align-center justify-center"
size="x-large"
@click="send('l', '左转')"
>
左
</v-btn>
<v-btn class="d-flex align-center justify-center"
size="x-large"
@click="send('r', '右转')"
>
右
</v-btn>
</div>
<v-btn class="d-flex align-center justify-center" size="x-large"
@click="send('s', '停止')"
>
停止
</v-btn>
</v-sheet>
<v-btn @click="read">test</v-btn>
</v-sheet>
</template>
<script lang="ts" name="bluetooh" setup>
import {onMounted, reactive} from "vue";
let characteristicUuid = "0000ffe2-0000-1000-8000-00805f9b34fb";
// let characteristicRx = "6e400002-b5a3-f393-e0a9-e50e24dcca9e";
const options = {
filters: [
{services: ['heart_rate']}, // 标准心率服务
{services: [0xffe0]}, // 两个16位服务ID
{services: ['00001800-0000-1000-8000-00805f9b34fb','0000ffe0-0000-1000-8000-00805f9b34fb','10001000-0000-1000-8000-00805f9b34fb']}, // 一个专有的128位UUID服务ID
{name: 'BT04-E'}, // 名称为 "ExampleName "的蓝牙设备
{name: 'XLBLE'}, // 名称为 "ExampleName "的蓝牙设备
// {namePrefix: 'Prefix'} // 名称为 "Prefix " 开头的蓝牙设备
],
optionalServices: ['battery_service'], // 接收服务ids;不会添加任何设备,但它确实会影响网站可以从用户选择的设备中使用哪些服务。
// acceptAllDevices: true // 设置为 true 时忽略所有的过滤器,它将只能使用optionalServices中列出的服务。
}
const bluetoothState = reactive({
isConnected: false,
activeDevice: null,
gattServer: null,
service: null,
characteristic: null,
isSupported: false,
})
// 当设备连接成功后,缓存相关对象
async function cacheGattObjects(device: any) {
try {
const gattServer = await device.gatt?.connect();
const service = await gattServer?.getPrimaryService(0xffe0);
// const characteristic = await service?.getCharacteristic(0xffe2);
const characteristic = await service?.getCharacteristic(0xffe1);
bluetoothState.isSupported = true;
bluetoothState.isConnected = true;
bluetoothState.activeDevice = device;
bluetoothState.gattServer = gattServer;
bluetoothState.service = service;
bluetoothState.characteristic = characteristic;
} catch (error) {
console.error('缓存蓝牙对象失败:', error);
}
}
async function send(data: string, actionName: string) {
if (!bluetoothState.isConnected) {
// @ts-ignore
const selectedDevice = await navigator.bluetooth.requestDevice(options);
await cacheGattObjects(selectedDevice);
}
if (bluetoothState.characteristic) {
try {
// @ts-ignore
await bluetoothState.characteristic.writeValue(new TextEncoder().encode(data));
console.log(`${actionName} 指令已发送`);
} catch (error) {
console.error(`${actionName} 指令发送失败:`, error);
}
} else {
console.error('无法发送指令:未找到有效的特征值');
}
}
async function read() {
if (!bluetoothState.isConnected) {
// @ts-ignore
const selectedDevice = await navigator.bluetooth.requestDevice(options);
await cacheGattObjects(selectedDevice);
}
if (bluetoothState.characteristic) {
try {
const value = await bluetoothState.characteristic
console.log('读取到的数据:', value);
} catch (error) {
console.error('读取数据失败:', error);
}
} else {
console.error('无法读取数据:未找到有效的特征值');
}
}
onMounted(() => {
})
</script>
<style scoped>
.direction-card {
margin-top: 30%;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
}
.side-buttons {
display: flex;
justify-content: space-between;
width: 100%;
}
</style>
web bluetooth 小车 蓝牙写入
最新推荐文章于 2024-07-19 18:32:48 发布