使用Unity开发在PC端连接并接收蓝牙数据

您所在的位置:网站首页 蓝牙连接怎么做成文件形式 使用Unity开发在PC端连接并接收蓝牙数据

使用Unity开发在PC端连接并接收蓝牙数据

2024-07-13 00:07:08| 来源: 网络整理| 查看: 265

在开发前,以为蓝牙这块已经很成熟了,基本信手拈来。

蛋是!搜索一圈下来,发现unity支持蓝牙开发的寥寥无几,找下来就发现一个BLE的插件和一个arduino的插件。然而...我要做的是通过PC的蓝牙模块来连接并取得蓝牙传感器数据,开始方了...

由于我是一个unity钉子户,.Net的winform不会写,网上找到的窗体应用也无法复用,又没有开发过蓝牙,项目又催得紧,只能抓紧时间各种找资料。

功夫不负有心人,在stack上找到一个国外大牛的发言,他自己做了一套unity可以调用BLE的库,果断请教。

后来去大佬的github down下来,(末尾已贴链接)本地打开测试后已经可以连接,但是会遇到身份验证无法通过的一个问题,问过硬件厂商说没有加身份验证。

然后偶然发现是我在电脑的蓝牙上需要先连接匹配上传感器,然后在项目内在扫描蓝牙设备,找到自己需要的service name和特征码,点击订阅,就可以接收到传感器的数据了,贴下我自己修改的部分代码,基本没啥大改。

using System; using System.Collections; using System.Collections.Generic; using System.Text; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; public class Demo : MonoBehaviour { public GameManager manager; public bool isScanningDevices = false; public bool isScanningServices = false; public bool isScanningCharacteristics = false; public bool isSubscribed = false; public Text deviceScanButtonText; public Text deviceScanStatusText; public GameObject deviceScanResultProto; public Button serviceScanButton; public Text serviceScanStatusText; public Dropdown serviceDropdown; public Button characteristicScanButton; public Text characteristicScanStatusText; public Dropdown characteristicDropdown; public Button subscribeButton; public Text subcribeText; public Button writeButton; public InputField writeInput; public Text errorText; Transform scanResultRoot; public string selectedDeviceId; public string selectedServiceId; Dictionary characteristicNames = new Dictionary(); public string selectedCharacteristicId; Dictionary devices = new Dictionary(); string lastError; // Start is called before the first frame update void Start() { scanResultRoot = deviceScanResultProto.transform.parent; deviceScanResultProto.transform.SetParent(null); } GameObject g = null; // Update is called once per frame void Update() { BleApi.ScanStatus status; if (isScanningDevices) { BleApi.DeviceUpdate res = new BleApi.DeviceUpdate(); do { status = BleApi.PollDevice(ref res, false); if (status == BleApi.ScanStatus.AVAILABLE) { if (!devices.ContainsKey(res.id)) { devices[res.id] = new Dictionary() { { "name", "" }, { "isConnectable", "False" } }; } if (res.nameUpdated) devices[res.id]["name"] = res.name; if (res.isConnectableUpdated) devices[res.id]["isConnectable"] = res.isConnectable.ToString(); // consider only devices which have a name and which are connectable if (devices[res.id]["name"] != "" && devices[res.id]["isConnectable"] == "True") { // add new device to list GameObject g = Instantiate(deviceScanResultProto, scanResultRoot); g.name = res.id; g.transform.GetChild(0).GetComponent().text = devices[res.id]["name"]; g.transform.GetChild(1).GetComponent().text = res.id; } } else if (status == BleApi.ScanStatus.FINISHED) { isScanningDevices = false; deviceScanButtonText.text = "扫描设备"; deviceScanStatusText.text = "finished"; } } while (status == BleApi.ScanStatus.AVAILABLE); //isScanningDevices = false; } if (isScanningServices) { BleApi.Service res = new BleApi.Service(); do { status = BleApi.PollService(out res, false); if (status == BleApi.ScanStatus.AVAILABLE) { serviceDropdown.AddOptions(new List { res.uuid }); // first option gets selected if (serviceDropdown.options.Count == 1) SelectService(serviceDropdown.gameObject); } else if (status == BleApi.ScanStatus.FINISHED) { isScanningServices = false; serviceScanButton.interactable = true; serviceScanStatusText.text = "finished"; } } while (status == BleApi.ScanStatus.AVAILABLE); } if (isScanningCharacteristics) { BleApi.Characteristic res = new BleApi.Characteristic(); do { status = BleApi.PollCharacteristic(out res, false); if (status == BleApi.ScanStatus.AVAILABLE) { string name = res.userDescription != "no description available" ? res.userDescription : res.uuid; characteristicNames[name] = res.uuid; characteristicDropdown.AddOptions(new List { name }); // first option gets selected if (characteristicDropdown.options.Count == 1) SelectCharacteristic(characteristicDropdown.gameObject); } else if (status == BleApi.ScanStatus.FINISHED) { isScanningCharacteristics = false; characteristicScanButton.interactable = true; characteristicScanStatusText.text = "finished"; } } while (status == BleApi.ScanStatus.AVAILABLE); } if (isSubscribed) { BleApi.BLEData res = new BleApi.BLEData(); while (BleApi.PollData(out res, false)) { subcribeText.text = BitConverter.ToString(res.buf, 0, res.size); subcribeText.text= Hex2Ten(subcribeText.text); string[] TenArray = subcribeText.text.Split(' '); //manager.currentturnCount = manager.totalturnCount -lastCount ; manager.totalturnCount = int.Parse(TenArray[18]); } } { // log potential errors BleApi.ErrorMessage res = new BleApi.ErrorMessage(); BleApi.GetError(out res); if (lastError != res.msg) { Debug.LogError(res.msg); errorText.text = res.msg; lastError = res.msg; } } //lastCount = manager.totalturnCount; //Debug.Log("lastCount" + lastCount); //Debug.Log("currentturnCount" + manager.currentturnCount); } int lastCount = 0; public static string Hex2Ten(string hex) { string[] array = hex.Split('-'); string str = ""; for (int k = 0; k < array.Length; k++) { int ten= Convert.ToInt32(array[k], 16); str += ten.ToString() + " "; } return str.ToString(); } private void OnApplicationQuit() { BleApi.Quit(); } public void StartStopDeviceScan() { if (!isScanningDevices) { // start new scan for (int i = scanResultRoot.childCount - 1; i >= 0; i--) Destroy(scanResultRoot.GetChild(i).gameObject); BleApi.StartDeviceScan(); isScanningDevices = true; deviceScanButtonText.text = "停止扫描"; deviceScanStatusText.text = "scanning"; } else { // stop scan isScanningDevices = false; BleApi.StopDeviceScan(); deviceScanButtonText.text = "扫描设备"; deviceScanStatusText.text = "stopped"; } } public void SelectDevice(GameObject data) { for (int i = 0; i < scanResultRoot.transform.childCount; i++) { var child = scanResultRoot.transform.GetChild(i).gameObject; child.transform.GetChild(0).GetComponent().color = child == data ? Color.red : deviceScanResultProto.transform.GetChild(0).GetComponent().color; } selectedDeviceId = data.name; serviceScanButton.interactable = true; } public void StartServiceScan() { if (!isScanningServices) { // start new scan serviceDropdown.ClearOptions(); BleApi.ScanServices(selectedDeviceId); isScanningServices = true; serviceScanStatusText.text = "scanning"; serviceScanButton.interactable = false; } } public void SelectService(GameObject data) { selectedServiceId = serviceDropdown.options[serviceDropdown.value].text; characteristicScanButton.interactable = true; } public void StartCharacteristicScan() { if (!isScanningCharacteristics) { // start new scan characteristicDropdown.ClearOptions(); BleApi.ScanCharacteristics(selectedDeviceId, selectedServiceId); isScanningCharacteristics = true; characteristicScanStatusText.text = "scanning"; characteristicScanButton.interactable = false; } } public void SelectCharacteristic(GameObject data) { string name = characteristicDropdown.options[characteristicDropdown.value].text; selectedCharacteristicId = characteristicNames[name]; subscribeButton.interactable = true; writeButton.interactable = true; } public void Subscribe() { // no error code available in non-blocking mode BleApi.SubscribeCharacteristic(selectedDeviceId, selectedServiceId, selectedCharacteristicId, false); isSubscribed = true; } public void Write() { byte[] payload = Encoding.ASCII.GetBytes(writeInput.text); BleApi.BLEData data = new BleApi.BLEData(); data.buf = new byte[512]; data.size = (short)payload.Length; data.deviceId = selectedDeviceId; data.serviceUuid = selectedServiceId; data.characteristicUuid = selectedCharacteristicId; for (int i = 0; i < payload.Length; i++) data.buf[i] = payload[i]; // no error code available in non-blocking mode BleApi.SendData(in data, false); } }

中间做了一个取值和进制转换,就可以渠道自己想要的数据了。

https://github.com/adabru/BleWinrtDll

再次感谢大佬,希望有用到的朋友可以给他点个star。

ok,分享就到这了。

下载不了的私信我。

下载地址:BleWinrtDll-main.zip-互联网文档类资源-CSDN下载



【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭