小工具知识网

当前位置: 首页 > 行业知识 > C#和低功耗蓝牙BLE通讯

行业知识

C#和低功耗蓝牙BLE通讯

2026-11-08 07:54:43 来源:互联网转载

@TOC

前言

以前都是用手机APP和蓝牙设备通信,现在在一个项目中需要更改为用电脑端上位机与蓝牙通讯的需求,在此记录自己走过的坑和积攒的经验。

特别感谢

未曾接触过的东西,首先就是在网上搜索资料,站在巨人的肩膀上好办事。在此特别感谢以下几个博客,就是参考大神们的博客写出来的。

1 C# ble 4.0 低能耗 蓝牙交互 : https://blog.csdn.net/code_long/article/details/105636398

这篇文章给出了完整的示例代码,也有70+的讨论,对一些搜索缓慢的问题做了修复。以及一些dll引用的问题和路径。

2 Win10 平台C#与低功耗蓝牙BLE设备通信案例 https://blog.csdn.net/shengfakun1234/article/details/110928783

第二篇文章对于获取不到蓝牙服务特征列表的问题进行了修复

3 MSDN有关蓝牙的介绍

1 通用 Windows 平台应用中的低能耗蓝牙: https://learn.microsoft.com/zh-cn/windows/uwp/devices-sensors/bluetooth-low-energy-overview

2 DeviceInformation.CreateWatcher 方法: https://learn.microsoft.com/zh-cn/uwp/api/windows.devices.enumeration.deviceinformation.createwatcher?view=winrt-22621

3 Bluetooth 硬件: https://learn.microsoft.com/zh-cn/windows-hardware/design/component-guidelines/bluetooth?redirectedfrom=MSDN

4 蓝牙调试助手 https://github.com/shijianoo/BluetoothLEAssistant/blob/master/%E8%93%9D%E7%89%99%E8%B0%83%E8%AF%95%E5%8A%A9%E6%89%8B/ViewModel/WatcherViewModel.cs

踩过的坑

1 使用的dll

需要注意的是我们使用的低功耗蓝牙BLE,如果使用一些库32feet.NET、InTheHand等,是搜索不到低功耗蓝牙的,只能搜索到经典蓝牙。

我们需要用MSDN自带的库:System.Runtime.WindowsRuntime.dll和 Windows.winmd。路径如下,自己安装在不同磁盘路径可能稍微有点不同:

C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETCore\v4.5\System.Runtime.WindowsRuntime.dll

C:\Program Files (x86)\Windows Kits\10\UnionMetadata\10.0.18362.0\Windows.winmd

2 上位机运行环境

必须是win10系统, win7系统不支持BLE通信,win8没有尝试过。 笔记本自带蓝牙,台式电脑没有蓝牙,可以买个蓝牙适配器插在电脑上用。

3 如何过滤蓝牙

现象是这样子的:第一次搜索到蓝牙A之后,关闭蓝牙A的电源,再次搜索还能搜索到蓝牙A,这是不科学的。 https://www.icode9.com/content-3-288234.html 同一个问题,它这个答案我这儿也不适用,感兴趣的可以看看。

这种不可学的情况是我在使用DeviceWatcher类搜索蓝牙的时候发现的,无论怎么设置过滤条件,都不起作用。

“System.Devices.Aep.DeviceAddress”,

“System.Devices.Aep.IsConnected”,

“System.Devices.Aep.Bluetooth.Le.IsConnectable” ,

“System.Devices.Aep.SignalStrength”,

“System.Devices.Aep.IsPresent”

最后是换了BluetoothLEAdvertisementWatcher类去搜索蓝牙,就解决了上述问题。参考这篇博文Win10 平台C#与低功耗蓝牙BLE设备通信案例的蓝牙搜索部分即可。

4 搜索不到蓝牙的服务和特征值

这一种方法在我电脑上是搜索不到服务的。

/// /// 获取蓝牙服务/// public async void FindService(){   var GattServices = this.CurrentDevice.GattServices;   foreach (GattDeviceService ser in GattServices)   {       this.GattDeviceServiceAdded(ser);   }}                     

改成下面的这种写法才能获取服务,特征值也是一样的道理。

        ///         /// 获取蓝牙服务        ///          public async void FindService()        {            this.CurrentDevice.GetGattServicesAsync().Completed = async (asyncInfo, asyncStatu) =>            {                if(asyncStatu == AsyncStatus.Completed)                {                    var sevices = asyncInfo.GetResults().Services;                    foreach(GattDeviceService ser in sevices)                    {                        this.GattDeviceServiceAdded(ser);                    }                }            };        }

5 如何收发蓝牙数据

如果还是刚刚接触到蓝牙,什么都不懂的,可以先看看蓝牙通讯协议,可参考该博文:经典蓝牙与低功耗蓝牙BLE开发基础知识:服务、特征、属性、UUIDhttps://blog.csdn.net/weixin_51484460/article/details/124906595

简单来说就是,Service是服务,Characteristic则是特征值。一般来说,蓝牙里面有多个Service,一个Service里面包括多个Characteristic。

一个蓝牙协议里面包含的Service和Characteristic是比较多的 ,那么这么多的同名属性用什么来区分呢?

就是UUID,每个Service或者Characteristic都有一个 128 bit 的UUID来标识。

Service可以理解为一个功能集合,而Characteristic比较重要,蓝牙设备正是通过Characteristic来进行设备间的交互的,这些Characteristic又包含一些属性Property,如读、写、订阅等操作。

我们得按照自己的需求更改SetOpteron(GattCharacteristic gattCharacteristic)这个函数,而不能照搬这个函数。

蓝牙包含哪些服务,服务下有含有哪些特征值,这个特征值的属性是可读,可写还是可订阅,这些可以通过蓝牙厂商获取,或如果是自己公司开发的话,那问相关的开发人员会更清楚。

效果图

蓝牙类的代码

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using Windows.Devices.Bluetooth;using Windows.Devices.Bluetooth.Advertisement;using Windows.Devices.Bluetooth.GenericAttributeProfile;using Windows.Devices.Enumeration;using Windows.Foundation;using Windows.Security.Cryptography;namespace Bluetoolth{    public enum MsgType     {        NotifyTxt,        BleDevice,        BleSendData,        BleRecData,    }   public class BleCore    {        private bool asyncLock = false;        ///         /// 搜索蓝牙设备对象        ///         private DeviceWatcher deviceWatcher;          ///         /// 当前连接的服务        ///         public GattDeviceService CurrentService { get; set; }        ///         /// 当前连接的蓝牙设备        ///         public BluetoothLEDevice CurrentDevice { get; set; }        ///         /// 写特征对象        ///         public GattCharacteristic CurrentWriteCharacteristic { get; set; }        ///         /// 写名称特征对象        ///         public GattCharacteristic CurrentNameCharacteristic { get; set; }        ///         /// 通知特征对象        ///         public GattCharacteristic CurrentNotifyCharacteristic { get; set; }        ///         /// 特性通知类型通知启用        ///         private const GattClientCharacteristicConfigurationDescriptorValue            CHARACTERSITIC_NOTIFICATION_TYPE = GattClientCharacteristicConfigurationDescriptorValue.Notify;        ///         /// 存储检测到的设备        ///         private List DevicesList = new List();        ///         /// 定义搜索蓝牙设备委托        ///         ///         ///         public delegate void DevicewatcherChangedEvent(MsgType type, BluetoothLEDevice bluetoothLEDevice);        ///         /// 搜索蓝牙事件        ///         public event DevicewatcherChangedEvent DevicewatcherChanged;        ///         /// 获取服务委托        ///         ///         public delegate void GattDeviceServiceAddedEvent(GattDeviceService gattDeviceService);        ///         /// 获取服务事件        ///         public event GattDeviceServiceAddedEvent GattDeviceServiceAdded;        ///         /// 获取特征委托        ///         ///         public delegate void CharacteristicAddedEvent(GattCharacteristic gattCharacteristic);        ///         /// 获取特征事件        ///         public event CharacteristicAddedEvent CharacteristicAdded;        ///         /// 提示信息委托        ///         ///         ///         ///         public delegate void MessageChangedEvent(MsgType type, string message, byte[] data = null);               ///         /// 提示信息事件        ///         public event MessageChangedEvent MessageChanged;        ///         /// 当前连接蓝牙的Mac        ///         private string CurrentDeviceMAC { get; set; }        public BleCore()        {        }               ///         /// 搜索蓝牙设备 方法1        ///         public void StartBleDevicewatcher_1()        {                       string[] requestedProperties = {                "System.Devices.Aep.DeviceAddress",                "System.Devices.Aep.IsConnected",                 "System.Devices.Aep.Bluetooth.Le.IsConnectable" ,                "System.Devices.Aep.SignalStrength",                "System.Devices.Aep.IsPresent"           };            string aqsAllBluetoothLEDevices = "(System.Devices.Aep.ProtocolId:=\"{bb7bb05e-5972-42b5-94fc-76eaa7084d49}\")";            string Selector = "System.Devices.Aep.ProtocolId:=\"{bb7bb05e-5972-42b5-94fc-76eaa7084d49}\"";            string selector = "(" + Selector + ")" + " AND (System.Devices.Aep.CanPair:=System.StructuredQueryType.Boolean#True OR System.Devices.Aep.IsPaired:=System.StructuredQueryType.Boolean#True)";            this.deviceWatcher =                DeviceInformation.CreateWatcher(                 //  aqsAllBluetoothLEDevices,                 //  BluetoothLEDevice.GetDeviceSelectorFromPairingState(false),                 selector,                    requestedProperties,                    DeviceInformationKind.AssociationEndpoint);            //在监控之前注册事件            this.deviceWatcher.Added += DeviceWatcher_Added;            this.deviceWatcher.Stopped += DeviceWatcher_Stopped;            this.deviceWatcher.Updated += DeviceWatcher_Updated; ;            this.deviceWatcher.Start();            string msg = "自动发现设备中..";            this.MessageChanged(MsgType.NotifyTxt, msg);        }               BluetoothLEAdvertisementWatcher watcher;        ///         /// 搜索蓝牙设备 方法2        ///         public void StartBleDevicewatcher()        {            watcher = new BluetoothLEAdvertisementWatcher();            watcher.ScanningMode = BluetoothLEScanningMode.Active;            // only activate the watcher when we're recieving values >= -80            watcher.SignalStrengthFilter.InRangeThresholdInDBm = -80;            // stop watching if the value drops below -90 (user walked away)            watcher.SignalStrengthFilter.OutOfRangeThresholdInDBm = -90;            // register callback for when we see an advertisements            watcher.Received += OnAdvertisementReceived;            watcher.Stopped += Watcher_Stopped;            // wait 5 seconds to make sure the device is really out of range            watcher.SignalStrengthFilter.OutOfRangeTimeout = TimeSpan.FromMilliseconds(5000);            watcher.SignalStrengthFilter.SamplingInterval = TimeSpan.FromMilliseconds(2000);            // starting watching for advertisements            watcher.Start();            string msg = "自动发现设备中..";            this.MessageChanged(MsgType.NotifyTxt, msg);        }        private void Watcher_Stopped(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementWatcherStoppedEventArgs args)        {            DevicesList.Clear();            string msg = "自动发现设备停止";            this.MessageChanged(MsgType.NotifyTxt, msg);        }        private void OnAdvertisementReceived(BluetoothLEAdvertisementWatcher watcher, BluetoothLEAdvertisementReceivedEventArgs eventArgs)        {            BluetoothLEDevice.FromBluetoothAddressAsync(eventArgs.BluetoothAddress).Completed = async (asyncInfo, asyncStatus) =>            {                if (asyncStatus == AsyncStatus.Completed)                {                    if (asyncInfo.GetResults() == null)                    {                        //this.MessAgeChanged(MsgType.NotifyTxt, "没有得到结果集");                    }                    else                    {                        BluetoothLEDevice currentDevice = asyncInfo.GetResults();                        if (currentDevice.Name.StartsWith("Bluetooth"))                        {                            return;                        }                        Boolean contain = false;                        foreach (BluetoothLEDevice device in DevicesList)//过滤重复的设备                        {                            if (device.DeviceId == currentDevice.DeviceId)                            {                                contain = true;                            }                        }                        if (!contain)                        {                            byte[] _Bytes1 = BitConverter.GetBytes(currentDevice.BluetoothAddress);                            Array.Reverse(_Bytes1);                            this.DevicesList.Add(currentDevice);                            this.MessageChanged(MsgType.NotifyTxt, "发现设备:" + currentDevice.Name + "  address:" + BitConverter.ToString(_Bytes1, 2, 6).Replace('-', ':').ToLower());                            this.DevicewatcherChanged(MsgType.BleDevice, currentDevice);                        }                    }                }            };        }            ///         /// 停止搜索        ///         public void StopBleDeviceWatcher()        {            if(deviceWatcher != null)            this.deviceWatcher.Stop();            if (watcher != null && watcher.Status == BluetoothLEAdvertisementWatcherStatus.Started)                watcher.Stop();        }       ///        /// 获取发现的蓝牙设备       ///        ///        ///         private void DeviceWatcher_Added(DeviceWatcher sender, DeviceInformation args)        {                       this.MessageChanged(MsgType.NotifyTxt, "发现设备:" + args.Id);            this.Matching(args.Id, args);        }        private void DeviceWatcher_Updated(DeviceWatcher sender, DeviceInformationUpdate args)        {        }        ///         /// 停止搜索蓝牙设备        ///         ///         ///         private void DeviceWatcher_Stopped(DeviceWatcher sender, object args)        {            string msg = "自动发现设备停止";            this.MessageChanged(MsgType.NotifyTxt, msg);        }              ///         /// 匹配        ///         ///         public void StartMatching(BluetoothLEDevice device)        {            this.CurrentDevice = device;        }               ///         /// 获取蓝牙服务        ///          public async void FindService()        {            /*var gattServices = this.CurrentDevice.GattServices;            foreach(GattDeviceService ser in gattServices)            {                this.GattDeviceServiceAdded(ser);            }*/                        this.CurrentDevice.GetGattServicesAsync().Completed = async (asyncInfo, asyncStatu) =>            {                if(asyncStatu == AsyncStatus.Completed)                {                    var sevices = asyncInfo.GetResults().Services;                    foreach(GattDeviceService ser in sevices)                    {                        this.GattDeviceServiceAdded(ser);                      //  FindCharacteristic(ser);                    }                }            };        }        public async void FindCharacteristic(GattDeviceService gattDeviceService)        {            /* this.CurrentService = gattDeviceService;             foreach(var c in gattDeviceService.GetAllCharacteristics())             {                 this.CharacteristicAdded(c);             }*/            gattDeviceService.GetCharacteristicsAsync().Completed = async (asyncInfo, asyncStatu) =>            {                if (asyncStatu == AsyncStatus.Completed)                {                    var chara = asyncInfo.GetResults().Characteristics;                    foreach (GattCharacteristic c in chara)                    {                        this.CharacteristicAdded(c);                    }                }            };        }        ///         /// 获取操作        ///         ///         ///         public async Task SetOpteron(GattCharacteristic gattCharacteristic)        {            if(gattCharacteristic.CharacteristicProperties == GattCharacteristicProperties.WriteWithoutResponse)            {                this.CurrentWriteCharacteristic = gattCharacteristic;            }            if (gattCharacteristic.CharacteristicProperties == GattCharacteristicProperties.Notify)            {                this.CurrentNotifyCharacteristic = gattCharacteristic;                this.CurrentNotifyCharacteristic.ProtectionLevel = GattProtectionLevel.Plain;                this.CurrentNotifyCharacteristic.ValueChanged += Characteristic_ValueChanged;                await this.EnableNotifications(CurrentNotifyCharacteristic);            }                       if (gattCharacteristic.CharacteristicProperties == ( GattCharacteristicProperties.Read | GattCharacteristicProperties.Write))            {                this.CurrentNameCharacteristic = gattCharacteristic;            }            this.Connect();        }        private async Task Connect()        {            byte[] _Bytes1 = BitConverter.GetBytes(this.CurrentDevice.BluetoothAddress);            Array.Reverse(_Bytes1);            this.CurrentDeviceMAC = BitConverter.ToString(_Bytes1, 2, 6).Replace('-', ':').ToLower();            string msg = "正在连接设备 ..";            this.MessageChanged(MsgType.NotifyTxt, msg);            this.CurrentDevice.ConnectionStatusChanged += CurrentDevice_ConnectionStatusChanged;                   }        private void CurrentDevice_ConnectionStatusChanged(BluetoothLEDevice sender, object args)        {           if(sender.ConnectionStatus == BluetoothConnectionStatus.Disconnected &&                 CurrentDeviceMAC != null)            {                string msg = "设备已断开,自动重连";                MessageChanged(MsgType.NotifyTxt, msg);                if(!asyncLock)                {                    asyncLock = true;                    this.CurrentDevice.Dispose();                    this.CurrentDevice = null;                    this.CurrentNotifyCharacteristic = null;                    this.CurrentWriteCharacteristic = null;                    SelectDeviceFromIdAsync(CurrentDeviceMAC);                }            }else            {                string msg = "设备已连接";                MessageChanged(MsgType.NotifyTxt, msg);            }        }        ///         /// 搜索到的蓝牙设备        ///         ///         ///         private async Task Matching(string id, DeviceInformation args = null)        {                        try            {                BluetoothLEDevice.FromIdAsync(id).Completed = async (asyncInfo, asyncStatus) =>                {                    if (asyncStatus == AsyncStatus.Completed)                    {                        BluetoothLEDevice bleDevice = asyncInfo.GetResults();                        if (bleDevice.Name.StartsWith("Bluetooth"))                        {                            return;                        }                        BluetoothLEDevice tmp = this.DevicesList.Where(p => p.Name == bleDevice.Name).FirstOrDefault();                        if(tmp == null)                        {//没有添加过                          //  bool state = IsConnectable(bleDevice.DeviceInformation);                            this.DevicesList.Add(bleDevice);                                                       this.DevicewatcherChanged(MsgType.BleDevice, bleDevice);                        }                    }                };            }            catch(Exception e)            {                string msg = "没有发现设备" + e.ToString();                this.MessageChanged(MsgType.NotifyTxt, msg);                this.StopBleDeviceWatcher();            }        }        ///         /// 主动断开连接        ///         public void Dispose()        {            CurrentDeviceMAC = null;            CurrentService?.Dispose();            CurrentDevice?.Dispose();            CurrentDevice = null;            CurrentService = null;            CurrentWriteCharacteristic = null;            CurrentNotifyCharacteristic = null;            this.MessageChanged(MsgType.NotifyTxt, "主动断开连接");        }        ///         /// 按MAC地址直接组装设备ID查找设备        ///         ///         ///         public async  Task SelectDeviceFromIdAsync(string MAC)        {            CurrentDeviceMAC = MAC;            CurrentDevice = null;            BluetoothAdapter.GetDefaultAsync().Completed = async (asyncInfo, asyncStatus) =>            {                if (asyncStatus == AsyncStatus.Completed)                {                    BluetoothAdapter bluetoothAdapter = asyncInfo.GetResults();                    // ulong 转为byte数组                    byte[] _Bytes1 = BitConverter.GetBytes(bluetoothAdapter.BluetoothAddress);                    Array.Reverse(_Bytes1);                    string macAddress = BitConverter.ToString(_Bytes1, 2, 6).Replace('-', ':').ToLower();                    string Id = "BluetoothLe#BluetoothLe" + macAddress + "-" + MAC;                    await Matching(Id);                }            };        }              ///         /// 设置特征对象为接收通知对象        ///         ///         ///         public async Task EnableNotifications(GattCharacteristic characteristic)        {            string msg = "收通知对象=" + CurrentDevice.ConnectionStatus;            this.MessageChanged(MsgType.NotifyTxt, msg);            characteristic.WriteClientCharacteristicConfigurationDescriptorAsync(CHARACTERSITIC_NOTIFICATION_TYPE).Completed = async (asyncInfo, asyncStatus) =>            {                if (asyncStatus == AsyncStatus.Completed)                {                    GattCommunicationStatus status = asyncInfo.GetResults();                    if (status == GattCommunicationStatus.Unreachable)                    {                        msg = "设备不可用";                        this.MessageChanged(MsgType.NotifyTxt, msg);                        if (CurrentNotifyCharacteristic != null && !asyncLock)                        {                            await this.EnableNotifications(CurrentNotifyCharacteristic);                        }                    }                    asyncLock = false;                    msg = "设备连接状态" + status;                    this.MessageChanged(MsgType.NotifyTxt, msg);                }            };        }        ///         /// 接受到蓝牙数据        ///         private void Characteristic_ValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args)        {            byte[] data;            CryptographicBuffer.CopyToByteArray(args.CharacteristicValue, out data);            string str = BitConverter.ToString(data);            this.MessageChanged(MsgType.BleRecData, str, data);        }        ///         /// 发送数据接口        ///         ///         public async Task Write(byte[] data)        {            if (CurrentWriteCharacteristic != null)            {                CurrentWriteCharacteristic.WriteValueAsync(CryptographicBuffer.CreateFromByteArray(data), GattWriteOption.WriteWithResponse);                string str = "发送数据:" + BitConverter.ToString(data);                this.MessageChanged(MsgType.BleSendData, str, data);            }        }        ///         /// 发送数据接口        ///         ///         public async Task WriteName(byte[] data)        {            if (CurrentNameCharacteristic != null)            {                CurrentNameCharacteristic.WriteValueAsync(CryptographicBuffer.CreateFromByteArray(data), GattWriteOption.WriteWithResponse);                string str = "发送数据:" + BitConverter.ToString(data);                this.MessageChanged(MsgType.BleSendData, str, data);            }        }    }}

调用类

using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;using Windows.Devices.Bluetooth;using Windows.Devices.Bluetooth.Advertisement;using Windows.Devices.Bluetooth.GenericAttributeProfile;using Windows.Devices.Enumeration;using Windows.Foundation;using System.Net.NetworkInformation;namespace HPBluetoolth{    public partial class BlueForm : Form    {        BleCore bleCore = new BleCore();        ///         /// 存储检测到的设备        ///         List DeviceList = new List();        ///         /// 当前蓝牙服务列表        ///         List GattDeviceServices = new List();        ///         /// 当前蓝牙服务特征列表        ///         List GattCharacteristics = new List();        public BlueForm()        {            InitializeComponent();                        CheckForIllegalCrossThreadCalls = false;            this.bleCore.MessageChanged += BleCore_MessAgeChanged;            this.bleCore.DevicewatcherChanged += BleCore_DeviceWatcherChanged;            this.bleCore.GattDeviceServiceAdded += BleCore_GattDeviceServiceAdded;           this.bleCore.CharacteristicAdded += BleCore_CharacteristicAdded;            this.Init();        }       private void Init()        {            this.Load += BlueForm_Load;            //开始            btnStart.Click += BtnStart_Click;            //搜索蓝牙            this.btnSearch.Click += btnSearch_Click;            this.btnConnect.Click += BtnConnect_Click;            //获取服务            this.btnServes.Click += BtnServes_Click;            //获取特征            this.btnFeatures.Click += BtnFeatures_Click;            //获取操作             this.btnOpt.Click += BtnOpt_Click;            //读取            this.btnRead.Click += BtnRead_Click;            //发送            this.btnWrite.Click += BtnWrite_Click;            this.FormClosing += BlueForm_FormClosing;        }        private void BlueForm_Load(object sender, EventArgs e)        {                             }        private void BtnStart_Click(object sender, EventArgs e)        {            string str = tbCode.Text;            byte[] buffer = Encoding.UTF8.GetBytes(str);            this.bleCore.WriteName(buffer);        }        bool Closing = false;        private void BlueForm_FormClosing(object sender, FormClosingEventArgs e)        {            Closing = true;            bleCore.Dispose();        }        // 异步线程        public static void RunAsync(Action action)        {            ((Action)(delegate ()            {                action.Invoke();            })).BeginInvoke(null, null);        }        ///         /// 搜索蓝牙        ///         ///         ///         private void btnSearch_Click(object sender, EventArgs e)        {            try            {                if (this.btnSearch.Text == "查找")                {                    this.listboxMessage.Items.Clear();                    this.listboxBleDevice.Items.Clear();                    this.bleCore.StartBleDevicewatcher();                    this.btnSearch.Text = "停止";                }                else                {                    this.bleCore.StopBleDeviceWatcher();                    this.btnSearch.Text = "查找";                }            }catch(Exception ex)            {                MessageBox.Show(ex.Message);            }        }        ///         /// 提示消息        ///         private void BleCore_MessAgeChanged(MsgType type, string message, byte[] data)        {            if (Closing) return;            RunAsync(() =>            {                this.listboxMessage.Items.Add(message);            });        }        ///         /// 搜索蓝牙设备列表        ///         private void BleCore_DeviceWatcherChanged(MsgType type, Windows.Devices.Bluetooth.BluetoothLEDevice bluetoothLEDevice)        {            if (Closing) return;            RunAsync(() =>            {                                this.listboxBleDevice.Items.Add(bluetoothLEDevice.Name);                this.DeviceList.Add(bluetoothLEDevice);                         });        }        ///         /// 连接蓝牙        ///         ///         ///         private void BtnConnect_Click(object sender, EventArgs e)        {            if(this.listboxBleDevice.SelectedItem == null)            {                MessageBox.Show("请选择连接的蓝牙");                return;            }            string deviceName = this.listboxBleDevice.SelectedItem.ToString();            Windows.Devices.Bluetooth.BluetoothLEDevice bluetoothLEDevice =                this.DeviceList.Where(u => u.Name == deviceName).FirstOrDefault();            if(bluetoothLEDevice == null)            {                MessageBox.Show("没有发现此蓝牙,请重新搜索");                return;            }            //两个蓝牙进行匹配            bleCore.StartMatching(bluetoothLEDevice);        }        ///         /// 获取服务        ///         ///         ///         private void BtnServes_Click(object sender, EventArgs e)        {            this.cmbServer.Items.Clear();            this.bleCore.FindService();        }        ///         /// 获取服务列表        ///         ///         private void BleCore_GattDeviceServiceAdded(GattDeviceService gattDeviceService)        {           // RunAsync(() =>          //  {                this.cmbServer.Items.Add(gattDeviceService.Uuid.ToString());                this.GattDeviceServices.Add(gattDeviceService);                this.btnFeatures.Enabled = true;         //   });        }        ///         /// 获取特征        ///         ///         ///         private void BtnFeatures_Click(object sender, EventArgs e)        {              this.cmbFeatures.Items.Clear();            if(this.cmbServer.SelectedItem == null)            {                MessageBox.Show("选择蓝牙服务");                return;            }else            {                var item = this.GattDeviceServices.Where(u => u.Uuid ==                new Guid(this.cmbServer.SelectedItem.ToString())).FirstOrDefault();                //获取蓝牙特征                this.bleCore.FindCharacteristic(item);            }        }        ///         /// 获取特征列表        ///         ///         private void BleCore_CharacteristicAdded(GattCharacteristic gattCharacteristic)        {           // RunAsync(() =>          //  {                this.cmbFeatures.Items.Add(gattCharacteristic.Uuid);                this.GattCharacteristics.Add(gattCharacteristic);                this.btnOpt.Enabled = true;          //  });        }        ///         /// 获取操作        ///         ///         ///         private void BtnOpt_Click(object sender, EventArgs e)        {            if(this.cmbFeatures.SelectedItem == null)            {                MessageBox.Show("请选择蓝牙服务");                return;            }            var item = this.GattCharacteristics.Where(u => u.Uuid ==            new Guid(this.cmbFeatures.SelectedItem.ToString())).FirstOrDefault();            //获取操作            this.bleCore.SetOpteron(item);            if(item.CharacteristicProperties == (GattCharacteristicProperties.Read                 | GattCharacteristicProperties.Write))            {                this.btnRead.Enabled = true;                this.btnWrite.Enabled = true;            }        }        ///         /// 读取        ///         ///         ///         private void BtnRead_Click(object sender, EventArgs e)        {            string str = tbReadWriteInfo.Text;            string[] arr = str.Split(' ');             byte[] buffer = new byte[7];             for(int i=0; i                buffer[i] = Convert.ToByte(arr[i], 16);            }            //CRC校验            ushort crc = CRC(buffer, 5);                     buffer[5] = (byte)((crc & 0xFF00) > 8);            buffer[6] = (byte)((crc & 0x00FF));              this.bleCore.Write(buffer);        }        ///         /// 写入        ///         ///         ///         private void BtnWrite_Click(object sender, EventArgs e)        {            string str = tbReadWriteInfo.Text;            string[] arr = str.Split(' ');            byte[] buffer = new byte[9];            for (int i = 0; i > 8);            buffer[8] = (byte)((crc & 0x00FF));            this.bleCore.Write(buffer);        }        ///         /// CRC校验        ///         ///         ///         ///         public static ushort CRC(byte[] data, int length)        {            ushort tempCrcResult = 0xffff;            for (int i = 0; i > 1) ^ 0xa001);                    else tempCrcResult = (ushort)(tempCrcResult >> 1);                }            }            return (tempCrcResult = (ushort)(((tempCrcResult & 0xff) > 8)));        }          }}

结尾

至此,低功耗蓝牙的搜索和通讯就完成了,感谢大神们贴的博文。

如何正常的关闭(断开)蓝牙连接

因工作上的进一步需要,我也遇到了这个问题,今天调试了一个上午,终于可以正常断开了。特此记录一下,

想直接在评论区写的,奈何写的比较啰嗦,给的字数不够用,就加在后文了。

也是根据这篇“The BLE Device Disconnection not working on UWP C#” 问答的思路写的,总的来说就是将一切引用到当前BluetoothLEDevice对象都要释放掉,否则是不能正常断开蓝牙的。

我因为BluetoothLEDevice对象在三个地方都存着有,一个是BluetoothLEDevice对象列表(List),还有两个类(BleCore,BlueForm)之中也有引用这个对象,所以找起来还是有点费劲的。GATT通道也务必要关闭哈。

BLE蓝牙正常断开的方法,请执行以下步骤,不分先后:

1 关闭GATT服务通道:

                //关闭该蓝牙的所有服务             foreach(var sev in GattDeviceServices)              {                  sev.Dispose();              }

2 移除事件监听器:(非必要,不移除也行,但可能会有内存泄漏啥的)

  if(CurrentDevice != null)      CurrentDevice.ConnectionStatusChanged -= CurrentDevice_ConnectionStatusChanged;

3 释放BluetoothLEDevice对象:(包括存储在 List DeviceList中的,或者指向当前BluetoothLEDevice对象的,都要释放)。

                //找到在蓝牙列表里面执行当前蓝牙的对象            string deviceName = this.listboxBleDevice.SelectedItem.ToString();            Windows.Devices.Bluetooth.BluetoothLEDevice bluetoothLEDevice =                this.DeviceList.Where(u => u.Name == deviceName).FirstOrDefault();            if (bluetoothLEDevice != null)            {//从列表中移除                this.DeviceList.Remove(bluetoothLEDevice);            }          if (bluetoothLEDevice != null)            {//关闭列表中的蓝牙                bluetoothLEDevice.Dispose();            }            bluetoothLEDevice = null;            //蓝牙类的关闭            this.bleCore.DisConnect();

完整断开蓝牙连接代码,如下:

        //断开        private void BtnDisConent_Click(object sender, EventArgs e)        {            //找到在蓝牙列表里面执行当前蓝牙的对象            string deviceName = this.listboxBleDevice.SelectedItem.ToString();            Windows.Devices.Bluetooth.BluetoothLEDevice bluetoothLEDevice =                this.DeviceList.Where(u => u.Name == deviceName).FirstOrDefault();            if (bluetoothLEDevice != null)            {//从列表中移除                this.DeviceList.Remove(bluetoothLEDevice);            }            //关闭该蓝牙的所有服务             foreach(var sev in GattDeviceServices)              {                  sev.Dispose();              }             //并清空            GattDeviceServices.Clear();            GattCharacteristics.Clear();            if (bluetoothLEDevice != null)            {//关闭列表中的蓝牙                bluetoothLEDevice.Dispose();            }            bluetoothLEDevice = null;            //蓝牙类的关闭            this.bleCore.DisConnect();            //释放内存            GC.Collect();        }

bleCore.DisConnect方法:

         ///         /// 主动断开连接        ///         public void Dispose()        {            IsConnect = false;            CurrentDeviceMAC = null;                       //使用到的服务 (我这里仅仅使用了一个服务)            CurrentService?.Dispose();             //蓝牙            if(CurrentDevice != null)                CurrentDevice.ConnectionStatusChanged -= CurrentDevice_ConnectionStatusChanged;            //关闭            CurrentDevice?.Dispose();            CurrentDevice = null;            CurrentService = null;            //特征值            CurrentNameCharacteristic = null;            CurrentWriteCharacteristic = null;            CurrentNotifyCharacteristic = null;        }

上一篇:怎么架服务器开私服?

下一篇:揭秘微赞人人分销设置全攻略,轻松开启你的赚钱之旅!