[转]windows BLE编程 net winform 连接蓝牙4.0
本文转自:https://www.cnblogs.com/webtojs/p/9675956.html
winform 程序调用Windows.Devices.Bluetoot API 实现windows下BLE蓝牙设备自动连接,收发数据功能。不需要使用win10的UWP开发。
先贴图,回头来完善代码
源码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Devices.Bluetooth;
using Windows.Devices.Bluetooth.GenericAttributeProfile;
using Windows.Devices.Enumeration;
using Windows.Foundation;
using Windows.Security.Cryptography; namespace BLECode
{
public class BluetoothLECode
{
//存储检测的设备MAC。
public string CurrentDeviceMAC { get; set; }
//存储检测到的设备。
public BluetoothLEDevice CurrentDevice { get; set; }
//存储检测到的主服务。
public GattDeviceService CurrentService { get; set; }
//存储检测到的写特征对象。
public GattCharacteristic CurrentWriteCharacteristic { get; set; }
//存储检测到的通知特征对象。
public GattCharacteristic CurrentNotifyCharacteristic { get; set; } public string ServiceGuid { get; set; } public string WriteCharacteristicGuid { get; set; }
public string NotifyCharacteristicGuid { get; set; } private const int CHARACTERISTIC_INDEX = 0;
//特性通知类型通知启用
private const GattClientCharacteristicConfigurationDescriptorValue CHARACTERISTIC_NOTIFICATION_TYPE = GattClientCharacteristicConfigurationDescriptorValue.Notify; private Boolean asyncLock = false; private DeviceWatcher deviceWatcher; //定义一个委托
public delegate void eventRun(MsgType type, string str,byte[] data=null);
//定义一个事件
public event eventRun ValueChanged; public BluetoothLECode(string serviceGuid, string writeCharacteristicGuid, string notifyCharacteristicGuid)
{
ServiceGuid = serviceGuid;
WriteCharacteristicGuid = writeCharacteristicGuid;
NotifyCharacteristicGuid = notifyCharacteristicGuid;
} public void StartBleDeviceWatcher()
{ string[] requestedProperties = { "System.Devices.Aep.DeviceAddress", "System.Devices.Aep.IsConnected", "System.Devices.Aep.Bluetooth.Le.IsConnectable" };
string aqsAllBluetoothLEDevices = "(System.Devices.Aep.ProtocolId:=\"{bb7bb05e-5972-42b5-94fc-76eaa7084d49}\")"; deviceWatcher =
DeviceInformation.CreateWatcher(
aqsAllBluetoothLEDevices,
requestedProperties,
DeviceInformationKind.AssociationEndpoint); // Register event handlers before starting the watcher.
deviceWatcher.Added += DeviceWatcher_Added;
deviceWatcher.Stopped += DeviceWatcher_Stopped;
deviceWatcher.Start();
string msg = "自动发现设备中.."; ValueChanged(MsgType.NotifyTxt, msg);
} private void DeviceWatcher_Stopped(DeviceWatcher sender, object args)
{
string msg = "自动发现设备停止";
ValueChanged(MsgType.NotifyTxt, msg);
} private void DeviceWatcher_Added(DeviceWatcher sender, DeviceInformation args)
{
ValueChanged(MsgType.NotifyTxt, "发现设备:" + args.Id);
if (args.Id.EndsWith(CurrentDeviceMAC))
{
Matching(args.Id);
} } /// <summary>
/// 按MAC地址查找系统中配对设备
/// </summary>
/// <param name="MAC"></param>
public async Task SelectDevice(string MAC)
{
CurrentDeviceMAC = MAC;
CurrentDevice = null;
DeviceInformation.FindAllAsync(BluetoothLEDevice.GetDeviceSelector()).Completed = async (asyncInfo, asyncStatus) =>
{
if (asyncStatus == AsyncStatus.Completed)
{
DeviceInformationCollection deviceInformation = asyncInfo.GetResults();
foreach (DeviceInformation di in deviceInformation)
{
await Matching(di.Id);
}
if (CurrentDevice == null)
{
string msg = "没有发现设备";
ValueChanged(MsgType.NotifyTxt, msg);
StartBleDeviceWatcher();
}
}
};
}
/// <summary>
/// 按MAC地址直接组装设备ID查找设备
/// </summary>
/// <param name="MAC"></param>
/// <returns></returns>
public async Task SelectDeviceFromIdAsync(string MAC)
{
CurrentDeviceMAC = MAC;
CurrentDevice = null;
BluetoothAdapter.GetDefaultAsync().Completed = async (asyncInfo, asyncStatus) =>
{
if (asyncStatus == AsyncStatus.Completed)
{
BluetoothAdapter mBluetoothAdapter = asyncInfo.GetResults();
byte[] _Bytes1 = BitConverter.GetBytes(mBluetoothAdapter.BluetoothAddress);//ulong转换为byte数组
Array.Reverse(_Bytes1);
string macAddress = BitConverter.ToString(_Bytes1, 2, 6).Replace('-', ':').ToLower();
string Id = "BluetoothLE#BluetoothLE" + macAddress + "-" + MAC;
await Matching(Id);
} }; } private async Task Matching(string Id)
{ try
{
BluetoothLEDevice.FromIdAsync(Id).Completed = async (asyncInfo, asyncStatus) =>
{
if (asyncStatus == AsyncStatus.Completed)
{
BluetoothLEDevice bleDevice = asyncInfo.GetResults();
//在当前设备变量中保存检测到的设备。
CurrentDevice = bleDevice;
await Connect(); }
};
}
catch (Exception e)
{
string msg = "没有发现设备" + e.ToString();
ValueChanged(MsgType.NotifyTxt, msg);
StartBleDeviceWatcher();
} } private async Task Connect()
{
string msg = "正在连接设备<" + CurrentDeviceMAC + ">..";
ValueChanged(MsgType.NotifyTxt, msg);
CurrentDevice.ConnectionStatusChanged += CurrentDevice_ConnectionStatusChanged;
await SelectDeviceService(); } /// <summary>
/// 主动断开连接
/// </summary>
/// <returns></returns>
public void Dispose()
{ CurrentDeviceMAC = null;
CurrentService?.Dispose();
CurrentDevice?.Dispose();
CurrentDevice = null;
CurrentService = null;
CurrentWriteCharacteristic = null;
CurrentNotifyCharacteristic = null;
ValueChanged(MsgType.NotifyTxt, "主动断开连接"); } private void CurrentDevice_ConnectionStatusChanged(BluetoothLEDevice sender, object args)
{
if (sender.ConnectionStatus == BluetoothConnectionStatus.Disconnected && CurrentDeviceMAC != null)
{
string msg = "设备已断开,自动重连";
ValueChanged(MsgType.NotifyTxt, msg);
if (!asyncLock)
{
asyncLock = true;
CurrentDevice.Dispose();
CurrentDevice = null;
CurrentService = null;
CurrentWriteCharacteristic = null;
CurrentNotifyCharacteristic = null;
SelectDeviceFromIdAsync(CurrentDeviceMAC);
} }
else
{
string msg = "设备已连接";
ValueChanged(MsgType.NotifyTxt, msg);
}
}
/// <summary>
/// 按GUID 查找主服务
/// </summary>
/// <param name="characteristic">GUID 字符串</param>
/// <returns></returns>
public async Task SelectDeviceService()
{
Guid guid = new Guid(ServiceGuid);
CurrentDevice.GetGattServicesForUuidAsync(guid).Completed = (asyncInfo, asyncStatus) =>
{
if (asyncStatus == AsyncStatus.Completed)
{
try
{
GattDeviceServicesResult result = asyncInfo.GetResults();
string msg = "主服务=" + CurrentDevice.ConnectionStatus;
ValueChanged(MsgType.NotifyTxt, msg);
if (result.Services.Count > 0)
{
CurrentService = result.Services[CHARACTERISTIC_INDEX];
if (CurrentService != null)
{
asyncLock = true;
GetCurrentWriteCharacteristic();
GetCurrentNotifyCharacteristic(); }
}
else
{
msg = "没有发现服务,自动重试中";
ValueChanged(MsgType.NotifyTxt, msg);
SelectDeviceService();
}
}
catch (Exception e)
{
ValueChanged(MsgType.NotifyTxt, "没有发现服务,自动重试中");
SelectDeviceService(); }
}
};
} /// <summary>
/// 设置写特征对象。
/// </summary>
/// <returns></returns>
public async Task GetCurrentWriteCharacteristic()
{ string msg = "";
Guid guid = new Guid(WriteCharacteristicGuid);
CurrentService.GetCharacteristicsForUuidAsync(guid).Completed = async (asyncInfo, asyncStatus) =>
{
if (asyncStatus == AsyncStatus.Completed)
{
GattCharacteristicsResult result = asyncInfo.GetResults();
msg = "特征对象=" + CurrentDevice.ConnectionStatus;
ValueChanged(MsgType.NotifyTxt, msg);
if (result.Characteristics.Count > 0)
{
CurrentWriteCharacteristic = result.Characteristics[CHARACTERISTIC_INDEX];
}
else
{
msg = "没有发现特征对象,自动重试中";
ValueChanged(MsgType.NotifyTxt, msg);
await GetCurrentWriteCharacteristic();
}
}
};
} /// <summary>
/// 发送数据接口
/// </summary>
/// <param name="characteristic"></param>
/// <param name="data"></param>
/// <returns></returns>
public async Task Write(byte[] data)
{
if (CurrentWriteCharacteristic != null)
{
CurrentWriteCharacteristic.WriteValueAsync(CryptographicBuffer.CreateFromByteArray(data), GattWriteOption.WriteWithResponse);
} } /// <summary>
/// 设置通知特征对象。
/// </summary>
/// <returns></returns>
public async Task GetCurrentNotifyCharacteristic()
{
string msg = "";
Guid guid = new Guid(NotifyCharacteristicGuid);
CurrentService.GetCharacteristicsForUuidAsync(guid).Completed = async (asyncInfo, asyncStatus) =>
{
if (asyncStatus == AsyncStatus.Completed)
{
GattCharacteristicsResult result = asyncInfo.GetResults();
msg = "特征对象=" + CurrentDevice.ConnectionStatus;
ValueChanged(MsgType.NotifyTxt, msg);
if (result.Characteristics.Count > 0)
{
CurrentNotifyCharacteristic = result.Characteristics[CHARACTERISTIC_INDEX];
CurrentNotifyCharacteristic.ProtectionLevel = GattProtectionLevel.Plain;
CurrentNotifyCharacteristic.ValueChanged += Characteristic_ValueChanged;
await EnableNotifications(CurrentNotifyCharacteristic); }
else
{
msg = "没有发现特征对象,自动重试中";
ValueChanged(MsgType.NotifyTxt, msg);
await GetCurrentNotifyCharacteristic();
}
}
};
} /// <summary>
/// 设置特征对象为接收通知对象
/// </summary>
/// <param name="characteristic"></param>
/// <returns></returns>
public async Task EnableNotifications(GattCharacteristic characteristic)
{
string msg = "收通知对象=" + CurrentDevice.ConnectionStatus;
ValueChanged(MsgType.NotifyTxt, msg); characteristic.WriteClientCharacteristicConfigurationDescriptorAsync(CHARACTERISTIC_NOTIFICATION_TYPE).Completed = async (asyncInfo, asyncStatus) =>
{
if (asyncStatus == AsyncStatus.Completed)
{
GattCommunicationStatus status = asyncInfo.GetResults();
if (status == GattCommunicationStatus.Unreachable)
{
msg = "设备不可用";
ValueChanged(MsgType.NotifyTxt, msg);
if (CurrentNotifyCharacteristic != null && !asyncLock)
{
await EnableNotifications(CurrentNotifyCharacteristic);
}
}
asyncLock = false;
msg = "设备连接状态" + status;
ValueChanged(MsgType.NotifyTxt, msg);
}
};
} private void Characteristic_ValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args)
{
byte[] data;
CryptographicBuffer.CopyToByteArray(args.CharacteristicValue, out data);
string str = BitConverter.ToString(data);
ValueChanged(MsgType.BLEData,str, data); }
} public enum MsgType
{
NotifyTxt,
BLEData
}
}

调用方式:
bluetooth = new BluetoothLECode(_serviceGuid, _writeCharacteristicGuid, _notifyCharacteristicGuid);
bluetooth.ValueChanged += Bluetooth_ValueChanged;
如果你无法编译上面的类库,请直接使用我生成的DLL文件
https://files.cnblogs.com/files/webtojs/BLECode.rar
[转]windows BLE编程 net winform 连接蓝牙4.0的更多相关文章
- windows BLE编程 net winform 连接蓝牙4.0
winform 程序调用Windows.Devices.Bluetoot API 实现windows下BLE蓝牙设备自动连接,收发数据功能.不需要使用win10的UWP开发. 先贴图,回头来完善代码 ...
- Windows 10下怎么远程连接 Ubuntu 16.0.4(方案二)
使用TeamViewer实现远程桌面连接 背景: 有些朋友反映,借助Ubuntu自带的桌面共享工具desktop sharing会有不再同一网端下出现连接不稳定或者掉线的问题,那么现在我们就可以借助第 ...
- Windows 10下怎么远程连接 Ubuntu 16.0.4(小白级教程)
前言: 公司因为用Ruby做开发,所有适用了Ubuntu系统,但是自己笔记本是W10,又不想装双系统,搭建开发环境,便想到倒不如自己远程操控公司电脑,这样在家的时候也可以处理一些问题.故此便有了下面的 ...
- 蓝牙4.0(包含BLE)简介
1. BLE (低功耗蓝牙)简介 国际蓝牙联盟( BT-SIG,TI 是 企业成员之一)通过的一个标准蓝牙无线协议. 主要的新特性是在蓝牙标准版本上添加了4.0 蓝牙规范 (2010 年6 月 ...
- iOS蓝牙BLE4.0通信功能
概述 iOS蓝牙BLE4.0通信功能,最近刚学的苹果,为了实现蓝牙门锁的项目,找了一天学习了下蓝牙的原理,亲手测试了一次蓝牙的通信功能,结果成功了,那么就把我学习的东西分享一下. 详细 代码下载:ht ...
- 基于蓝牙4.0(Bluetooth Low Energy)胎压监测方案设计
基于一种新的蓝牙技术——蓝牙4.0(Bluetooth Low Energy)新型的胎压监测系统(TPMS)的设计方案.鉴于蓝牙4.0(Bluetooth Low Energy)的低成本.低功耗.高稳 ...
- Android项目实战(三十四):蓝牙4.0 BLE 多设备连接
最近项目有个需求,手机设备连接多个蓝牙4.0 设备 并获取这些设备的数据. 查询了很多资料终于实现,现进行总结. ------------------------------------------- ...
- android4.3 蓝牙BLE编程
一.蓝牙4.0简介 蓝牙4.0标准包含两个蓝牙标准,准确的说,是一个双模的标准,它包含传统蓝牙部分(也有称之为经典蓝牙Classic Bluetooth)和低功耗蓝牙部分(Bluetooth Low ...
- Android5.0(Lollipop) BLE蓝牙4.0+浅析demo连接(三)
作者:Bgwan链接:https://zhuanlan.zhihu.com/p/23363591来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. Android5.0(L ...
随机推荐
- charming_memory
Memory Master 一 .Forget遗忘 遗忘似乎是记忆的天敌,但是善用遗忘规律却能帮助我们更好的记忆. 复习的最佳时间是实际材料的1~24小时,最晚不超过2天,复习时间太长,就有一种生疏的 ...
- kubernetes CRD学习笔记
前言 最近在极客时间订阅了kubernetes的专栏,这篇文章是想记录一下自己学习CRD(custom resource definition)的过程,加深一下记忆. 准备工作 首先安装一下我们用的g ...
- 2018年2月19日我的java学习(——)
在学完了类和对象的时候,开始对面向对象的思想有了一点认识,不过也不是完全的理解了. 就现在的学习状态来说,是非常的不错的,但是在学习的内容来说,我学的好像只是跟随这 站长的思路而已,也许是经验不足吧. ...
- 基于fpga的vga学习(2)
本次学习主要向配合basys2实行. 上次学习vga的rgb三个output都是1位的,但是我看了basys2的rgb分别是332位,这里让我卡顿了很久, 之后通过查资料才知道,rgb的不同大小表示的 ...
- poj 1026
这题一开始没看清楚 等级差距不超过1 1->2->3 就是错误的,因为3-1==2 ,意思是间接的也不行 其次等级最小是1,最大是n 你要到达1号首领的位置 假设1号等级x,限制m,最大上 ...
- win32控制台程序 宽字符与短字符转化
由于vs各版本之间存在字符设置不兼容问题,特总结char与tchar的互相转换函数,如下,在之后的工程中可以使用. void TcharToChar(const TCHAR * tchar, char ...
- css格式比较及选择器类型总结
在前端入门的前三天把网页制作过程中常用的一些标签和属性都认识和练习了一遍,能够做出简单模块的框架.就像老师说的网页制作就像建一栋大楼,html是砖和水泥,css是精装,js是完善各个功能.现在就开始进 ...
- Windows 10 IoT Serials 10 – 如何使用OCR引擎进行文字识别
1. 引言 OCR (Optical Character Recognition,光学字符识别)是指电子设备(例如扫描仪或数码相机)检查纸上打印的字符,通过检测暗.亮的模式确定其形状,然后用字符识别方 ...
- Java初学者最佳的学习方法以及会遇到的坑(内含学习资料)!
最近系统整理了一套java初学者最佳的学习方法以及会遇到的坑等,希望对你有所帮助. 目录: 一.学习java的前提 二.学习java的方法 三.学习java时的坑 四.学习java的路线(画重点) 一 ...
- Logistic回归Cost函数和J(θ)的推导----Andrew Ng【machine learning】公开课
最近翻Peter Harrington的<机器学习实战>,看到Logistic回归那一章有点小的疑问. 作者在简单介绍Logistic回归的原理后,立即给出了梯度上升算法的code:从算法 ...