工作需要,要求在原有的c#界面中添加ble蓝牙通信模块,想要嵌入到原有代码中;这里网上也是有很多实例,也是参考了许多博主的文章其实都大同小异,主要还是在环境搭建这里;
我首先新建了一个c#控制台应用,初步实现对蓝牙的搜索和链接后续在将其移植到代码中实现需要的逻辑;下面主要以在控制台实现的通信作为一个记录。
这里和蓝牙模块初步实现了一个通信协议,所以在下文中会出现数据的发送和接收;
一:环境准备
1:修改 “工程.csproj” ,在其中增加:
10.0
2:重新加载项目
3:右键点击工程选择“添加”--->"引用"
二:核心代码
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;
using Windows.Storage.Streams;
using System.IO;
using System.Windows.Forms;
using System.Timers;
//using bluetoothLE;
namespace bluetoothLE
{
class BleCore
{
//设置定时器来限制搜索时间
System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
//static string _name;
// static string _rid, _wid, _nid;
// public static string Redastr;
public static Guid Wid { get; set; }
public static Guid Rid { get; set; }
public static Guid Nid { get; set; }
private static List characteristics = new List();
private static void CharacteristicFinish(int size)
{
if (size <= 0)
{
Console.WriteLine("设备未连上");
return;
}
}
private static void Recdata(GattCharacteristic sender, byte[] data)
{
string str = BitConverter.ToString(data);
Console.WriteLine(sender.Uuid + " " + str);
}
private void CharacteristicAdded(GattCharacteristic gatt)
{
Console.WriteLine(
"handle:[0x{0}] char properties:[{1}] UUID:[{2}]",
gatt.AttributeHandle.ToString("X4"),
gatt.CharacteristicProperties.ToString(),
gatt.Uuid);
if (gatt.CharacteristicProperties.ToString() == "Notify")
{
Console.WriteLine(gatt.Uuid);
Nid = gatt.Uuid;
}
if (gatt.CharacteristicProperties.ToString() == "Read")
{
Console.WriteLine(gatt.Uuid);
// Rid = gatt.Uuid;
}
if (gatt.CharacteristicProperties.ToString() == "WriteWithoutResponse, Write")
{
Console.WriteLine(gatt.Uuid);
Wid = gatt.Uuid;
}
characteristics.Add(gatt);
}
private void DeviceWatcherChanged(BluetoothLEDevice currentDevice,string signal )
{
byte[] _Bytes1 = BitConverter.GetBytes(currentDevice.BluetoothAddress);
Array.Reverse(_Bytes1);
string address = BitConverter.ToString(_Bytes1, 2, 6).Replace('-', ':').ToLower();
Console.WriteLine("发现设备:<" + currentDevice.Name + "> address:<" + address + ">"+ " 信号值:<"+ signal + ">");
//Console.WriteLine("发现设备:{0,- 30} address:<{1,15}> 信号值:{2,4}", currentDevice.Name, address,signal);
//string str = getName();
//string str = Name;
string str = currentDevice.Name.Substring(0, 2);
Console.WriteLine("截取的字符串长度:"+str);
// if (currentDevice.Name.Equals(str) || currentDevice.DeviceId.Contains("C1-29-63-15-A1-21"))
// if (currentDevice.Name.Equals(str))
if (str.Equals("G1"))
{
ConnectDevice(currentDevice);
//GattCharacteristic gattCharacteristic = characteristics.Find((x) => { return x.Uuid.Equals(new Guid("6e400003-b5a3-f393-e0a9-e50e24dcca9e")); });
// GattCharacteristic gattCharacteristic = characteristics.Find((x) => { return x.Uuid.Equals(Rid); });
// this.SetOpteron(gattCharacteristic);
//gattCharacteristic = characteristics.Find((x) => { return x.Uuid.Equals(new Guid("00002a00-0000-1000-8000-00805f9b34fb")); });
GattCharacteristic gattCharacteristic = characteristics.Find((x) => { return x.Uuid.Equals(Wid); });
this.SetOpteron(gattCharacteristic);
//gattCharacteristic = characteristics.Find((x) => { return x.Uuid.Equals(new Guid("6e400002-b5a3-f393-e0a9-e50e24dcca9e")); });
gattCharacteristic = characteristics.Find((x) => { return x.Uuid.Equals(Nid); });
this.SetOpteron(gattCharacteristic);
byte[] b = { 0x52, 0x4d, 0x10, 0x05, 0x05, 0x00, 0x01, 0x02, 0x03 };
this.Write(b);
}
}
private void ConnectDevice(BluetoothLEDevice Device)
{
characteristics.Clear();
this.StopBleDeviceWatcher();
this.StartMatching(Device);
this.FindService();
}
/* public static string getName()
{
return _name;
}
public void setName(string name)
{
_name = name;
}
*/
public string Name { get; set; }
/*public void setRWNuuid(string Rid, string Wid, string Nid)
{
_rid = Rid;
_wid = Wid;
_nid = Nid;
}
public static string GetRid()
{
return _rid;
}
public static string GetWid()
{
return _wid;
}
public static string GetNid()
{
return _nid;
}
*/
/*
public string getReadValue()
{
return Redastr;
}
public void setReadValue(string str)
{
Redastr = null;
Redastr = str;
}*/
public string ReadValue { get; set; }
private bool asyncLock = false;
///
/// 当前连接的服务
///
private GattDeviceService CurrentService { get; set; }
///
/// 当前连接的蓝牙设备
///
private BluetoothLEDevice CurrentDevice { get; set; }
///
/// 写特征对象
///
private GattCharacteristic CurrentWriteCharacteristic { get; set; }
///
/// 通知特征对象
///
private GattCharacteristic CurrentNotifyCharacteristic { get; set; }
///
/// 存储检测到的设备
///
private List DeviceList { get; set; }
///
/// 特性通知类型通知启用
///
private const GattClientCharacteristicConfigurationDescriptorValue CHARACTERISTIC_NOTIFICATION_TYPE = GattClientCharacteristicConfigurationDescriptorValue.Notify;
///
/// 当前连接的蓝牙Mac
///
private string CurrentDeviceMAC { get; set; }
private BluetoothLEAdvertisementWatcher Watcher = null;
public BleCore()
{
DeviceList = new List();
timer.Enabled = true;
timer.Interval = 1500;//规定搜索15秒
timer.Tick += new EventHandler(this.Timer1_Tick);
timer.Stop();
}
///
/// 搜索蓝牙设备
///
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;
// 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
//设置定时器来限制蓝牙搜索时间
timer.Start();
Watcher.Start();
Console.WriteLine("自动发现设备中..");
}
private void Timer1_Tick(object sender, EventArgs e)
{
StopBleDeviceWatcher();//停止搜索蓝牙
Console.WriteLine("停止搜索");
timer.Stop();
//throw new NotImplementedException();
}
///
/// 停止搜索蓝牙
///
public void StopBleDeviceWatcher()
{
if (Watcher != null)
this.Watcher.Stop();
}
///
/// 主动断开连接
///
///
public void Dispose()
{
CurrentDeviceMAC = null;
CurrentService?.Dispose();
CurrentDevice?.Dispose();
CurrentDevice = null;
CurrentService = null;
CurrentWriteCharacteristic = null;
CurrentNotifyCharacteristic = null;
Console.WriteLine("主动断开连接");
}
///
/// 匹配
///
///
private void StartMatching(BluetoothLEDevice Device)
{
this.CurrentDevice = Device;
}
///
/// 发送数据接口
///
///
public void Write(byte[] data)
{
if (CurrentWriteCharacteristic != null)
{
CurrentWriteCharacteristic.WriteValueAsync(CryptographicBuffer.CreateFromByteArray(data), GattWriteOption.WriteWithResponse).Completed = (asyncInfo, asyncStatus) =>
{
if (asyncStatus == AsyncStatus.Completed)
{
GattCommunicationStatus a = asyncInfo.GetResults();
Console.WriteLine("发送数据:" + BitConverter.ToString(data) + " State : " + a);
}
};
}
}
/// 获取蓝牙服务
///
private void FindService()
{
this.CurrentDevice.GetGattServicesAsync().Completed = (asyncInfo, asyncStatus) =>
{
if (asyncStatus == AsyncStatus.Completed)
{
var services = asyncInfo.GetResults().Services;
Console.WriteLine("GattServices size=" + services.Count);
foreach (GattDeviceService ser in services)
{
FindCharacteristic(ser);
}
//CharacteristicFinish?.Invoke(services.Count);
CharacteristicFinish(services.Count);
}
};
}
///
/// 按MAC地址直接组装设备ID查找设备
///
public void SelectDeviceFromIdAsync(string MAC)
{
CurrentDeviceMAC = MAC;
CurrentDevice = null;
BluetoothAdapter.GetDefaultAsync().Completed = (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;
Matching(Id);
}
};
}
///
/// 获取操作
///
///
private void SetOpteron(GattCharacteristic gattCharacteristic)
{
byte[] _Bytes1 = BitConverter.GetBytes(this.CurrentDevice.BluetoothAddress);
Array.Reverse(_Bytes1);
this.CurrentDeviceMAC = BitConverter.ToString(_Bytes1, 2, 6).Replace('-', ':').ToLower();
string msg = "正在连接设备<" + this.CurrentDeviceMAC + ">..";
Console.WriteLine(msg);
if (gattCharacteristic.CharacteristicProperties == GattCharacteristicProperties.Write)
{
this.CurrentWriteCharacteristic = gattCharacteristic;
}
if (gattCharacteristic.CharacteristicProperties == GattCharacteristicProperties.Notify)
{
this.CurrentNotifyCharacteristic = gattCharacteristic;
this.CurrentNotifyCharacteristic.ProtectionLevel = GattProtectionLevel.Plain;
this.CurrentNotifyCharacteristic.ValueChanged += Characteristic_ValueChanged;
this.CurrentDevice.ConnectionStatusChanged += this.CurrentDevice_ConnectionStatusChanged;
this.EnableNotifications(CurrentNotifyCharacteristic);
}
if (gattCharacteristic.CharacteristicProperties == (GattCharacteristicProperties.WriteWithoutResponse |GattCharacteristicProperties.Write) )
{
//Console.WriteLine("WriteWithoutResponse----------");
this.CurrentWriteCharacteristic = gattCharacteristic;
}
if ((uint)gattCharacteristic.CharacteristicProperties == 26)
{
// Console.WriteLine("Write26----------");
}
if (gattCharacteristic.CharacteristicProperties == (GattCharacteristicProperties.Write | GattCharacteristicProperties.Notify))
{
this.CurrentWriteCharacteristic = gattCharacteristic;
this.CurrentNotifyCharacteristic = gattCharacteristic;
this.CurrentNotifyCharacteristic.ProtectionLevel = GattProtectionLevel.Plain;
this.CurrentNotifyCharacteristic.ValueChanged += Characteristic_ValueChanged;
this.CurrentDevice.ConnectionStatusChanged += this.CurrentDevice_ConnectionStatusChanged;
this.EnableNotifications(CurrentNotifyCharacteristic);
}
}
private void OnAdvertisementReceived(BluetoothLEAdvertisementWatcher watcher, BluetoothLEAdvertisementReceivedEventArgs eventArgs)
{
Int16 rssi = eventArgs.RawSignalStrengthInDBm;
BluetoothLEDevice.FromBluetoothAddressAsync(eventArgs.BluetoothAddress).Completed = (asyncInfo, asyncStatus) =>
{
if (asyncStatus == AsyncStatus.Completed)
{
if (asyncInfo.GetResults() == null)
{
//Console.WriteLine("没有得到结果集");
}
else
{
BluetoothLEDevice currentDevice = asyncInfo.GetResults();
if (DeviceList.FindIndex((x) => { return x.Name.Equals(currentDevice.Name); }) < 0)
{
this.DeviceList.Add(currentDevice);
// DeviceWatcherChanged?.Invoke(currentDevice);
DeviceWatcherChanged(currentDevice, rssi.ToString());
}
}
}
};
}
///
/// 获取特性
///
private void FindCharacteristic(GattDeviceService gattDeviceService)
{
this.CurrentService = gattDeviceService;
this.CurrentService.GetCharacteristicsAsync().Completed = (asyncInfo, asyncStatus) =>
{
if (asyncStatus == AsyncStatus.Completed)
{
var services = asyncInfo.GetResults().Characteristics;
foreach (var c in services)
{
//this.CharacteristicAdded?.Invoke(c);
CharacteristicAdded(c);
}
}
};
}
///
/// 搜索到的蓝牙设备
///
///
private void Matching(string Id)
{
try
{
BluetoothLEDevice.FromIdAsync(Id).Completed = (asyncInfo, asyncStatus) =>
{
if (asyncStatus == AsyncStatus.Completed)
{
BluetoothLEDevice bleDevice = asyncInfo.GetResults();
this.DeviceList.Add(bleDevice);
Console.WriteLine(bleDevice);
}
if (asyncStatus == AsyncStatus.Started)
{
Console.WriteLine(asyncStatus.ToString());
}
if (asyncStatus == AsyncStatus.Canceled)
{
Console.WriteLine(asyncStatus.ToString());
}
if (asyncStatus == AsyncStatus.Error)
{
Console.WriteLine(asyncStatus.ToString());
}
};
}
catch (Exception e)
{
string msg = "没有发现设备" + e.ToString();
Console.WriteLine(msg);
this.StartBleDeviceWatcher();
}
}
private void CurrentDevice_ConnectionStatusChanged(BluetoothLEDevice sender, object args)
{
if (sender.ConnectionStatus == BluetoothConnectionStatus.Disconnected && CurrentDeviceMAC != null)
{
if (!asyncLock)
{
asyncLock = true;
Console.WriteLine("设备已断开");
this.CurrentDevice?.Dispose();
this.CurrentDevice = null;
CurrentService = null;
CurrentWriteCharacteristic = null;
CurrentNotifyCharacteristic = null;
SelectDeviceFromIdAsync(CurrentDeviceMAC);
}
}
else
{
if (!asyncLock)
{
asyncLock = true;
Console.WriteLine("设备已连接");
}
}
}
///
/// 设置特征对象为接收通知对象
///
///
///
private void EnableNotifications(GattCharacteristic characteristic)
{
Console.WriteLine("收通知对象=" + CurrentDevice.Name + ":" + CurrentDevice.ConnectionStatus);
characteristic.WriteClientCharacteristicConfigurationDescriptorAsync(CHARACTERISTIC_NOTIFICATION_TYPE).Completed = (asyncInfo, asyncStatus) =>
{
if (asyncStatus == AsyncStatus.Completed)
{
GattCommunicationStatus status = asyncInfo.GetResults();
if (status == GattCommunicationStatus.Unreachable)
{
Console.WriteLine("设备不可用");
if (CurrentNotifyCharacteristic != null && !asyncLock)
{
this.EnableNotifications(CurrentNotifyCharacteristic);
}
return;
}
asyncLock = false;
Console.WriteLine("设备连接状态" + status);
}
};
}
///
/// 接受到蓝牙数据
///
private void Characteristic_ValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args)
{
byte[] data;
CryptographicBuffer.CopyToByteArray(args.CharacteristicValue, out data);
// Recdate?.Invoke(sender, data);
string byteResult = BitConverter.ToString(data).Replace("-"," ");
ReadValue = byteResult;
Console.WriteLine(byteResult);
}
}
}
三:如何引用
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using bluetoothLE;
namespace bluetoothLE
{
class MainFun
{
// private static BleCore bleCore = null;
public static void Main(string[] args)
{
BleCore b = new BleCore();
//bleCore = b.getBleCore();
b.StartBleDeviceWatcher();
byte[] by = { 0x52, 0x4d, 0x10, 0x05, 0x05, 0x00, 0x01, 0x02, 0x03 };
string s = "52 4d 10 05 05 00 01 02 03";
byte[] byteArray = System.Text.Encoding.Default.GetBytes(s);
//byte[] byteArray = BitConverter.GetBytes()
Console.WriteLine(BitConverter.ToString(byteArray));
while (true)
{
if (Console.ReadLine() == "q")
{
b.Dispose();
}
b.Write(by);
// if (b.getReadValue() != null)
//{
Console.WriteLine("接收到的数据:"+ b.ReadValue);
// }
}
}
}
}