***** 编辑:我现在正在工作,请参阅下面接受的答案和此问题中的更新代码... *****
好的,我对微控制器代码非常陌生,但对 Objective-c 蓝牙代码也很陌生。
我想要的是
我想用一个 iOS 应用程序连接到我的蓝牙 Bluefruit Friend UART LE(NRF51822 芯片)并向它发送一个 128 位令牌并让它响应一个 HID 消费者代码。
我试过的
目前,我可以使用串行监视器连接到芯片并通过我想要的消费者代码发送,它会通过执行该操作来响应。因此,如果我发送代码以使设备静音或增大/减小音量,它将在我的 iOS 设备中静音/增大/减小音量。这很棒!
现在我需要在笔记本电脑上没有串行监视器的情况下执行此操作,并引入发送令牌而不是 HID 代码的概念,并让它以 HID 代码响应。这非常棘手,似乎向我介绍了服务和渠道等新概念。似乎大多数蓝牙设备都带有许多可用的自定义服务,开发人员可以添加这些服务,并允许将读取与写入操作分开。每个服务都允许许多特征,例如读/写/通知/更新等等。
所以...我假设可以通过这些服务使用我想要的解决方案。如果我有一个用于读取令牌的服务和另一个用于编写 a 的服务,GATT HID Consumer Code
那么我应该能够通过 Objective-c 中的蓝牙分别连接到每个服务。这将使我能够区分发送令牌和接收回代码。
问题
正如你所看到的,我在下面的代码中有很多 NSLogs,目前这些日志都没有显示我在盒子上放置的任何服务。服务总是打印为零。如果我使用名为 的应用商店中的 iOS 应用RF Connect
,我可以连接到盒子,我可以看到这些服务肯定在那里......
我试过的代码
这是我一直用来尝试检测设备服务的当前代码......我认为这是一个从这里开始的好地方。
蓝牙管理器.h
#import <Foundation/Foundation.h>
@protocol BluetoothMgrDelegate <NSObject>
@optional
- (void)didConnectToDevice;
- (void)didDisconnectFromDevice;
@end
@interface BluetoothMgr : NSObject {
}
@property (nonatomic, weak) id <BluetoothMgrDelegate> delegate;
+ (BluetoothMgr *)sharedInstance;
- (void)scanForPeripherals;
- (void)disconnectDevice;
- (void)connectToDevice;
@end
蓝牙管理器
#define SERVICE_UUID @"0000BBB5-2222-3333-4444-AABBCCDDEEFF"
#define CARACHTERISTIC_UUID @"0000BBB6-1111-2222-3333-AABBCCDDEEFF"
#import "BluetoothMgr.h"
#import <UIkit/UIKit.h>
#import <CoreBluetooth/CoreBluetooth.h>
#import <QuartzCore/QuartzCore.h>
@interface BluetoothMgr () <CBCentralManagerDelegate, CBPeripheralDelegate> {
int count;
}
@property (nonatomic, strong) CBCentralManager *centralManager;
@property (nonatomic, strong) CBPeripheralManager *peripheralManager;
@property (nonatomic, strong) CBPeripheral *myPeripheral;
@property (nonatomic, strong) CBUUID *deviceUUID;
@property (nonatomic, strong) CBService *functionalityServiceLayer;
@property (nonatomic, strong) CBCharacteristic *characteristic;
@end
@implementation BluetoothMgr
+ (BluetoothMgr *)sharedInstance {
static BluetoothMgr *_sharedInstance = nil;
static dispatch_once_t oncePredicate;
dispatch_once(&oncePredicate, ^{
_sharedInstance = [[BluetoothMgr alloc] init];
});
return _sharedInstance;
}
- (id)init {
self = [super init];
if(self) {
self.centralManager = [[CBCentralManager alloc] initWithDelegate:self
queue:nil
options:@{ CBCentralManagerOptionRestoreIdentifierKey : @"DriveSafeDevice"}];
}
return self;
}
- (void)connectToDevice {
if(_myPeripheral != nil) {
[self.centralManager connectPeripheral:self.myPeripheral
options:@{ CBConnectPeripheralOptionNotifyOnConnectionKey: [NSNumber numberWithInt:1] }
];
}
}
- (void)scanForPeripherals {
NSLog(@"*** scan for Bluetooth peripherals");
if (_centralManager.state == CBCentralManagerStatePoweredOn) {
NSLog(@"--- central manager powered on. Start scanning.");
[self.centralManager scanForPeripheralsWithServices:@[self.deviceUUID] options:nil];
}
}
- (void)disconnectDevice {
if (!(self.centralManager == nil || _myPeripheral == nil)) {
[self.centralManager cancelPeripheralConnection:_myPeripheral];
}
}
#pragma mark - CBCentralManager delegate methods
- (void)centralManager:(CBCentralManager *)central
willRestoreState:(NSDictionary<NSString *,id> *)state {
NSLog(@"--- will restore state.");
}
- (void)centralManagerDidUpdateState:(CBCentralManager *)central {
NSLog(@"centralManagerDidUpdateState invoked...");
// Determine the state of the peripheral
if ([central state] == CBCentralManagerStatePoweredOff) {
NSLog(@"CoreBluetooth BLE hardware is powered off");
} else if (central.state == CBCentralManagerStatePoweredOn) {
NSLog(@"CoreBluetooth BLE hardware is powered on.");
[self.centralManager scanForPeripheralsWithServices:nil options:nil];
}
}
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverDescriptorsForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
NSLog(@"did discover characteristic! peripheral: %@", peripheral);
NSLog(@"did discover characteristic! characteristic: %@", characteristic);
NSLog(@"did discover characteristic! error: %@", error);
}
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error {
NSLog(@"did discover service! peripheral: %@", peripheral);
NSLog(@"services??: %@", peripheral.services);
NSLog(@"did discover service! error: %@", error);
}
- (void)centralManager:(CBCentralManager *)central
didDiscoverPeripheral:(CBPeripheral *)peripheral
advertisementData:(NSDictionary *)advertisementData
RSSI:(NSNumber *)RSSI {
NSLog(@"peripheral: %@", peripheral);
NSLog(@"advertisement data: %@", advertisementData);
if([peripheral.name containsString:@"Adafruit Bluefruit LE"]) {
NSLog(@"central: %@", central);
NSLog(@"peripheral: %@", peripheral);
NSLog(@"advertisement data: %@", advertisementData);
NSLog(@"RSSI: %@", RSSI);
NSLog(@"found peripheral services!: %@", peripheral.services);
self.myPeripheral = peripheral;
self.myPeripheral.delegate = self;
//self.serviceUUID = ;
self.deviceUUID = [CBUUID UUIDWithString:[peripheral.identifier UUIDString]];
[self connectToDevice];
}
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
NSLog(@"--- didConnectPeripheral");
NSLog(@"peripheral in didConnect function: %@", peripheral);
NSLog(@"any services??: %@", peripheral.services);
[peripheral discoverServices:@[self.deviceUUID]];
if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateActive) {
NSLog(@"--- connected to peripheral in foreground");
[[NSNotificationCenter defaultCenter] postNotificationName:@"connectedToDevice" object:self];
[self triggerLocalNotification];
} else {
NSLog(@"--- connected to peripheral in background");
[[NSNotificationCenter defaultCenter] postNotificationName:@"connectedToDevice" object:self];
[self triggerLocalNotification];
//[self.delegate didConnectToDevice];
}
}
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(nonnull CBPeripheral *)peripheral error:(nullable NSError *)error {
NSLog(@"--- did disconnect ConnectPeripheral");
}
- (void)peripheral:(CBPeripheral *)peripheral didModifyServices:(NSArray<CBService *> *)invalidatedServices {
NSLog(@"peripheral services: %@", peripheral.services);
NSLog(@"services invalidated: %@", invalidatedServices);
}
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {
NSLog(@"Failed to connect");
}
- (void)sendCodeToBTDevice:(NSString *)code
characteristic:(CBCharacteristic *)characteristic {
if(code != nil) {
NSData *data = [code dataUsingEncoding:NSUTF8StringEncoding];
[self.ourPeripheral writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
}
}
@end
最后的想法...
我在如何在 Arduino 板/任何 BT 设备中编写自定义服务/特性方面的知识差距显然是这里的问题。我不确定我是否应该在设备或我的 OBJ-C 应用程序中创建服务/特征。
考虑到现在这些是在设备而不是应用程序中创建的,这个概念现在很可笑。