windows 蓝牙程序开发 ble低功耗蓝牙

该代码段展示了如何在C#中使用WindowsSDK进行蓝牙设备的搜索、选择特定名称的设备、连接及读写特征值。通过BluetoothLEAdvertisementWatcher类进行设备扫描,依据设备名筛选目标设备,然后使用BluetoothLEDevice类进行连接操作。同时,包含了连接状态监听、特征值读取和写入功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、需要使用到的动态库

Bluetooth
Microsoft.Windows.SDK.Contracts

2、需要使用到的命名控件

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;

3、创建蓝牙设备对象

      public BluetoothTools()
        {
            
            if (deviceWatcher == null)
            {
                deviceWatcher = new BluetoothLEAdvertisementWatcher();
                deviceWatcher.ScanningMode = BluetoothLEScanningMode.Active;//扫描模式
                deviceWatcher.SignalStrengthFilter.InRangeThresholdInDBm = -80;
                deviceWatcher.SignalStrengthFilter.OutOfRangeThresholdInDBm = -90;
                deviceWatcher.SignalStrengthFilter.OutOfRangeTimeout = TimeSpan.FromMilliseconds(5000);
                deviceWatcher.SignalStrengthFilter.SamplingInterval = TimeSpan.FromMilliseconds(2000);
                deviceWatcher.Received += DeviceWatcher_Received;
                deviceWatcher.Stopped += DeviceWatcher_Stopped;
            }
        }
/// <summary>
        /// 蓝牙搜索停止时触发事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void DeviceWatcher_Stopped(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementWatcherStoppedEventArgs args)
        {
            //搜索停止
            this.DeviceSearchComplete?.Invoke(this.BluetoothList);
        }

        /// <summary>
        /// 扫描到蓝牙设备时处理方法
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void DeviceWatcher_Received(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args)
        {
            BluetoothLEDevice.FromBluetoothAddressAsync(args.BluetoothAddress).Completed = async (asyncInfo, asyncStatus) =>
            {
                if (asyncStatus == AsyncStatus.Completed)
                {
                    if (asyncInfo.GetResults() != null)
                    {
                        BluetoothLEDevice currentDevice = asyncInfo.GetResults();
                        if (currentDevice.Name.ToUpper().StartsWith("FS"))
                        {
                            bool state = BluetoothList.Where(x => x.BluetoothDeviceId == currentDevice.DeviceId).ToList().Count > 0;
                            if (!state)
                            {
                                BluetoothInfo info = new BluetoothInfo()
                                {
                                    BluetoothName = currentDevice.Name,
                                    BluetoothDeviceId = currentDevice.DeviceId,
                                    BluetoothMac = currentDevice.DeviceId.Split('-')[1]
                                };
                                BluetoothList.Add(info); //添加设备到蓝牙列表
                               
                                DeviceWatcherChanged(info);
                            }
                        }
                        currentDevice.Dispose();//释放掉蓝牙设备
                    }
                }
            };

        }

4、开启蓝牙搜索,并在一定时间后停止蓝牙搜索操作

/// <summary>
        /// 搜索蓝牙设备
        /// </summary>
        public void Searching()
        {
            if (SearchingState)
            {
                return;
            }
            this.BluetoothList.Clear();

            try
            {
                deviceWatcher.Start();
                SearchingState = true;
                this.ReceivedMessage(MessageType.Info, "蓝牙搜索中...");
            }
            catch (Exception ex)
            {
                this.ReceivedMessage(MessageType.Error, "蓝牙搜索异常:"+ex.Message);
                return;
            }
            long time = Environment.TickCount +1000*5;
            Task.Factory.StartNew(() =>
            {
                while (SearchingState)
                {
                    if (Environment.TickCount > time)
                    {
                        if (SearchingState)
                        {
                            StopSearching();
                        }
                    }
                    else
                    {
                        Thread.Sleep(50);
                    }

                }

            });
        }
        /// <summary>
        /// 停止搜索
        /// </summary>
        public void StopSearching(bool isPassive=false)
        {
            SearchingState = false;
            this.ReceivedMessage(MessageType.Info, isPassive? "停止蓝牙搜索..." : "主动停止蓝牙搜索...");
            deviceWatcher.Stop();   
        }

5、连接指定蓝牙 指定读写特征

  /// <summary>
        /// 连接蓝牙
        /// </summary>
        /// <param name="bluetoothAddress"></param>
        public async Task ConnectAsync(string mac)
        {
            if (SearchingState)
            {
                StopSearching(true);//搜索中停止搜索...
            }
            if (IsConnect && mac == CurrentDeviceMAC)
            {
                this.ReceivedMessage(MessageType.Warning, $"已连接蓝牙:{CurrentDeviceMAC},无需重连!");
                return;
            }

            if (IsConnect)
            {
                this.ReceivedMessage(MessageType.Info, $"连接新的蓝牙:{mac},主动断开已连接蓝牙:{CurrentDeviceMAC}");
                CloseConnect();//断开当前的蓝牙连接
                Thread.Sleep(500);
            }
            BluetoothAdapter bluetoothAdapter = await BluetoothAdapter.GetDefaultAsync();
            if (bluetoothAdapter == null)
            {
                this.ReceivedMessage(MessageType.Error, "当前机器没有蓝牙模块");
                return;//没有蓝牙设备
            }


            //var itemList = BluetoothList.Where(x => x.BluetoothMac == mac).ToList();
            //if (itemList.Count < 1)
            //{
            //    this.ReceivedMessage(MessageType.Warning, "蓝牙列表中不存在当前蓝牙-请执行搜索蓝牙");
            //    return;//
            //}
            //CurrentDevice = await BluetoothLEDevice.FromIdAsync(itemList[0].BluetoothDeviceId);

            // 修改:不用搜索也可以连接
            byte[] _Bytes1 = BitConverter.GetBytes(bluetoothAdapter.BluetoothAddress);//ulong转换为byte数组
            Array.Reverse(_Bytes1);
            string macAddress = BitConverter.ToString(_Bytes1, 2, 6).Replace('-', ':').ToLower();
            string Id = "BluetoothLE#BluetoothLE" + macAddress + "-" + mac;
            CurrentDevice = await BluetoothLEDevice.FromIdAsync(Id);

            if (CurrentDevice != null)
            {
                CurrentDeviceMAC = mac;
                CurrentDevice.ConnectionStatusChanged += CurrentDevice_ConnectionStatusChanged;//蓝牙状态
            }
            else
            {
                this.ReceivedMessage(MessageType.Warning, "通过MAC未查询到蓝牙");
                return;//查询不到蓝牙
            }

            CurrentDevice.GetGattServicesAsync().Completed = async (asyncInfo, asyncStatus) =>
            {
                if (asyncStatus == AsyncStatus.Completed)
                {
                    var services = asyncInfo.GetResults().Services;
                    foreach (GattDeviceService ser in services)
                    {
                        string uid = ser.Uuid.ToString();
                        if (ser.Uuid.ToString().StartsWith("6e400001"))
                        {
                            CurrentService = ser;
                            FindCharacteristic();
                        }
                        else
                        {
                            // ser.Dispose();
                        }
                    }
                    if (CurrentService == null)
                    {
                        this.ReceivedMessage(MessageType.Error, "未获取蓝牙服务-链接失败");
                        return;
                    }
                }
            };
        }

        /// <summary>
        /// 查找读写特征
        /// </summary>
        public void FindCharacteristic()
        {
            CurrentService.GetCharacteristicsAsync().Completed = async (asyncInfo, asyncStatus) =>
            {
                if (asyncStatus == AsyncStatus.Completed)
                {
                    var characteristics = asyncInfo.GetResults().Characteristics;
                    foreach (GattCharacteristic characteristic in characteristics)
                       {
                        string uid = characteristic.Uuid.ToString();
                        System.Console.WriteLine(uid);
                        if (characteristic.Uuid.ToString().StartsWith("6e400003"))
                        {
                            CurrentNotifyCharacteristic = characteristic;//读取
                            CurrentNotifyCharacteristic.ProtectionLevel = GattProtectionLevel.Plain;
                            CurrentNotifyCharacteristic.ValueChanged += CurrentNotifyCharacteristic_ValueChanged;
                            try
                            {
                                 await CurrentNotifyCharacteristic.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue.Notify);
                            }
                            catch (Exception ex)
                            {
                                this.ReceivedMessage(MessageType.Error, "设置蓝牙读取特征Notify异常:" + ex.Message);
                                return;
                            }

                        }
                        else if (characteristic.Uuid.ToString().StartsWith("6e400002"))
                        {
                            CurrentWriteCharacteristic = characteristic;//写入
                        }
                    }
                    if (CurrentNotifyCharacteristic == null || CurrentWriteCharacteristic == null)
                    {
                        this.ReceivedMessage(MessageType.Warning, "未查询到读或写特征码-断开蓝牙");
                        this.CloseConnect();
                    }
                }
            };

        }
        /// <summary>
        /// 蓝牙状态改变触发事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
     
        private void CurrentDevice_ConnectionStatusChanged(BluetoothLEDevice sender, object args)
        {
            if (sender.ConnectionStatus == BluetoothConnectionStatus.Disconnected)
            {
                this.IsConnect = false;
                if (CurrentDevice != null)
                {
                    CurrentDevice.ConnectionStatusChanged -= CurrentDevice_ConnectionStatusChanged;
                    this.CloseConnect();
                    CurrentDevice = null;
                }

                this.DeviceConnect(2, $"蓝牙:{CurrentDeviceMAC}已断开");
                CurrentDeviceMAC = null;
            }
            else
            {
                this.IsConnect = true;
                this.DeviceConnect(1, $"蓝牙:{CurrentDeviceMAC}已连接");

                //保存蓝牙配置
                foreach (BluetoothInfo item in BluetoothList)
                {
                    if (item.BluetoothMac == CurrentDeviceMAC)
                    {
                        Globals.systemConfig.bluetooth = new BluetoothInfo()
                        {
                            BluetoothMac =item.BluetoothMac,
                            BluetoothDeviceId=item.BluetoothDeviceId,
                            BluetoothName=item.BluetoothName
                        };
                        Globals.SaveConfig();
                        break;
                    }
                }

               

            }
        }
        
        /// <summary>
        /// 读特征接收蓝牙数据事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void CurrentNotifyCharacteristic_ValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args)
        {
            byte[] data;
            CryptographicBuffer.CopyToByteArray(args.CharacteristicValue, out data);
            string str = BitConverter.ToString(data);
            OnRev?.Invoke(this, new BleEventArgs(data));
        }

5、关闭蓝牙连接

 /// <summary>
        /// 关闭蓝牙连接
        /// </summary>
        public void CloseConnect()
        {
            //ReceivedMessage(MsgType.WarningMsg, $"正在断开蓝牙:{CurrentDeviceMAC}...");
            CurrentService?.Dispose();
            CurrentDevice?.Dispose();
            
            if (CurrentNotifyCharacteristic != null)
            {
                CurrentNotifyCharacteristic.ValueChanged -= CurrentNotifyCharacteristic_ValueChanged;
            }
            
            CurrentService = null;
            CurrentWriteCharacteristic = null;
            CurrentNotifyCharacteristic = null;
            //if (CurrentDevice != null)
            //{
            //    CurrentDevice.ConnectionStatusChanged -= CurrentDevice_ConnectionStatusChanged;
            //}
           // CurrentDevice = null;
        }

6、通过写特征向蓝牙发送数据

/// <summary>
        /// 发送数据接口
        /// </summary>
        /// <param name="characteristic"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public async Task<bool> Write(byte[] data)
        {
            if (CurrentWriteCharacteristic == null) { return false; }


            int count = 50;
            int len = count;
            try
            {
                for (int i = 0; i < data.Length; i += count)
                {
                    if (i + count > data.Length)
                    {
                        len = data.Length - i;
                    }
                    byte[] b1 = new byte[len];

                    Array.Copy(data, i, b1, 0, len);

                    GattCommunicationStatus status = await CurrentWriteCharacteristic.WriteValueAsync(CryptographicBuffer.CreateFromByteArray(b1), GattWriteOption.WriteWithoutResponse);
                    if (status != GattCommunicationStatus.Success) { return false; }
                    else
                    {
                        Thread.Sleep(1);
                    }
                }
                return true;
            }
            catch (Exception ex)
            {
                this.ReceivedMessage(MessageType.Error,$"发送异常:{ex.Message}");
                return false;
            }

        }
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值