c/c++ windows ble 蓝牙
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
前言
在使用c/c++ 通过winrt 操作ble蓝牙之前本身采用了qt的ble蓝牙库去操作但是最后发现qt的ble只能使用在msvc+qt中使用其他的使用的时候就会在扫描的时候没有反应最终又只能在比较了解ble的同事帮助之下去研究 微软的使用c/c++ 通过winrt 操作ble蓝牙另外如果不用通过广播过滤设备可以使用第三方库 WCHBleLib_MultiOS 或者是BleWinrtDll 如果想多深入了解的话也可以参考微软写的demo BluetoothLE关于微软操作ble接口说明文档地址是bluetoothleadvertisement
注意事项
1.使用该方式的时候c++的版本要设置为 c++17
2.引用的头文件为
#include <windows.h>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <mutex>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.Devices.Bluetooth.h>
#include <winrt/Windows.Devices.Enumeration.h>
#include <winrt/Windows.Devices.Bluetooth.Advertisement.h>
#include <winrt/Windows.Devices.Bluetooth.GenericAttributeProfile.h>
#include <winrt/Windows.Storage.Streams.h>
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.Devices.Radios.h>
#include <winrt/Windows.Web.Syndication.h>
#include <windows.devices.bluetooth.h>
#include <windows.foundation.h>
#include<coroutine>
using namespace winrt;
using namespace Windows::Devices::Bluetooth;
using namespace Windows::Devices::Bluetooth::Advertisement;
using namespace Windows::Devices::Bluetooth::GenericAttributeProfile;
using namespace winrt::Windows::Devices::Radios;
using namespace Windows::Foundation;
#pragma comment(lib, "windowsapp")
#pragma comment(lib, "WindowsApp.lib")
using namespace std;
1.获取电脑是否支持ble蓝牙和蓝牙是否打开
bool BLEIsLowEnergySupported() {
auto getadapter_op = Windows::Devices::Bluetooth::BluetoothAdapter::GetDefaultAsync();
auto adapter = getadapter_op.get();
auto supported = adapter.IsLowEnergySupported(); // 获取windows电脑是否支持ble
if (supported == false) return false;
auto async = adapter.GetRadioAsync(); //获取本地蓝牙信息
auto radio = async.get();
auto t = radio.State(); // 获取电脑蓝牙状态 0未知1打开2关闭3硬件关闭或禁用
if (t != winrt::Windows::Devices::Radios::RadioState::On) {
return false;
}
return true;
}
LPWSTRT 与char 互转
LPWSTR ConvertCharToLPWSTR(char* szString, WCHAR* addrchar)
{
int dwLen = strlen(szString) + 1;
int nwLen = MultiByteToWideChar(CP_ACP, 0, szString, dwLen, NULL, 0);//算出合适的长度
MultiByteToWideChar(CP_ACP, 0, szString, dwLen, addrchar, nwLen);
return addrchar;
}
unsigned char* ConvertLPWSTRToChar(LPCTSTR widestr, unsigned char* addrchar)
{
int num = WideCharToMultiByte(CP_OEMCP, NULL, widestr, -1, NULL, 0, NULL, FALSE);
WideCharToMultiByte(CP_OEMCP, NULL, widestr, -1, (char*)addrchar, num, NULL, FALSE);
return addrchar;
}
2.扫描ble蓝牙
void Scanblebackfun(BluetoothLEAdvertisementWatcher w, BluetoothLEAdvertisementReceivedEventArgs e) // 扫描到的ble蓝牙设备通过此回调方式返回{
if (e.AdvertisementType() == BluetoothLEAdvertisementType::ConnectableUndirected)
{
uint64_t address = e.BluetoothAddress(); //获取蓝牙地址建议不用转字符串太麻烦
auto Rssi = e.RawSignalStrengthInDBm(); //获取蓝牙信号强度
//保存有效地址
BluetoothLEDevice dev = BluetoothLEDevice::FromBluetoothAddressAsync(address).get();
int cid = 0;
auto id = dev.BluetoothDeviceId(); //获取蓝牙唯一id
auto name = dev.Name(); //获取蓝牙名称
char ID[50] = {0};
char Name[50] = {0};
ConvertLPWSTRToChar(id.Id().c_str(), (unsigned char*)ID);
ConvertLPWSTRToChar(name.c_str(), (unsigned char*)Name);
auto advertisement = e.Advertisement(); //获取蓝牙广播
auto serviceUuids = advertisement.ServiceUuids(); //获取广播的服务器的uuid
auto view = serviceUuids.GetView();
bool Isfindguid = false;
for (size_t i = 0; i < view.Size(); i++)
{
auto guid = view.GetAt(i);
if (guid.Data1 == 0xf801 ) { //获取自己需要的广播
Isfindguid = true;
}
}
dev.Close();
if (Isfindguid == false) return;
}
void ScanBLEDevice(int timeout) {
BluetoothLEAdvertisementWatcher m_btWatcher;
m_btWatcher.ScanningMode(BluetoothLEScanningMode::Passive); //扫描所有此时没有连接的蓝牙
m_btWatcher.Received(Scanblebackfun); // 注册扫描到的蓝牙回调
Pens.clear();
m_btWatcher.Start(); //开始扫描
Sleep(timeout);
m_btWatcher.Stop();//结束扫描
}
3.连接蓝牙获取服务和特征
void Characteristic_ValueChanged(GattCharacteristic const& characteristic, GattValueChangedEventArgs args){//订阅回传的数据
}
BLEHandle ConnectBLEDevice(char * id) {
WCHAR ID[255] = { 0 };
ConvertCharToLPWSTR(id, ID);
hstring hst(ID);
auto device = BluetoothLEDevice::FromIdAsync(hst).get();
auto result = device.GetGattServicesAsync(BluetoothCacheMode::Uncached).get();//连接蓝牙服务
auto services = result.Services();
for (size_t i = 0; i < services.Size(); i++)
{
auto service = services.GetAt(i);
auto uuid = service.Uuid(); //获取服务uuid
auto charact = service.GetCharacteristicsAsync().get();
auto characts = charact.Characteristics();
for (size_t j = 0; j < characts.Size(); j++)
{
auto charact = characts.GetAt(j);
auto uuid = charact.Uuid(); //获取子服务的uuid
auto GAttpro = charact.CharacteristicProperties(); //获取每个子服务特征值
if (GAttpro == GattCharacteristicProperties::Notify) { charact.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue::Notify);//注册订阅
charact.ValueChanged(auto_revoke, &Characteristic_ValueChanged); //设置订阅数据回传的回调
}
if (GAttpro == GattCharacteristicProperties::Write) {
//写入数据
unsigned char* buff = "123456";
unsigned int lenght = 6;
winrt::Windows::Storage::Streams::DataWriter writer;
writer.WriteBytes(array_view<uint8_t const>(buff, buff + lenght));
winrt::Windows::Storage::Streams::IBuffer buffer = writer.DetachBuffer();
charact.WriteValueAsync(buffer);
}
if (GAttpro == GattCharacteristicProperties::Read) {
}
if (GAttpro == (GattCharacteristicProperties::Write | GattCharacteristicProperties::WriteWithoutResponse)) {
}
if (GAttpro == (GattCharacteristicProperties::Notify | GattCharacteristicProperties::Write)) {
}
if (GAttpro == (GattCharacteristicProperties::Notify | GattCharacteristicProperties::Read)) {
}
if (GAttpro == (GattCharacteristicProperties::Write | GattCharacteristicProperties::Read)) {
}
return;
}
}
}