首页 文章

在iOS上的BLE上写入数据时出现未知错误

提问于
浏览
10

我正在尝试开发iOS应用程序,它正在检测BLE设备并需要调用写入命令 . 我可以成功连接到BLE设备并发现其服务和特性 . 但是在连接的外围设备上写入数据时出现未知错误 . 以下是我写的代码:

发现特征:

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error {
  NSArray     *characteristics    = [service characteristics];

  if (peripheral != self.peripheral) {
    NSLog(@"Wrong Peripheral.\n");
    return ;
  }

 if (error != nil) {
    NSLog(@"Error %@\n", error);
    return ;
  }

  for (CBCharacteristic *characteristic in characteristics) {

if ([[characteristic UUID] isEqual:RWT_POSITION_CHAR_UUID]) {
  self.positionCharacteristic = characteristic;
   }
 }
}

这是在BLE设备上写入数据的功能

- (void)writeCommand{

// See if characteristic has been discovered before writing to it
if (!self.positionCharacteristic) {
    return;
}
NSString *cmd1=@"CQ+WHORU\r";

 NSData *dataToWrite = [cmd1 dataUsingEncoding:NSUTF8StringEncoding];

CBCharacteristic *chr = self.positionCharacteristic;
NSLog(@"%@,%lu...%@",chr.UUID,chr.properties,chr);



NSInteger dataSize = [[NSByteCountFormatter stringFromByteCount:dataToWrite.length countStyle:NSByteCountFormatterCountStyleFile] integerValue];
if (dataSize > 130) {
    NSLog(@"Cannot send more than 130 bytes");
}
else
{
    [self.peripheral writeValue:dataToWrite forCharacteristic:self.positionCharacteristic type:CBCharacteristicWriteWithResponse];

    }

}

- (void)peripheral:(CBPeripheral *)peripheral
didWriteValueForCharacteristic:(CBCharacteristic *)characteristic
         error:(NSError *)error
{
    if (error)
    {
        NSLog(@"Error writing characteristic value: %@",[error      localizedDescription]);
    }
    else
    {
        NSLog(@"Successfuly writing characteristic value");
    }
}

在“didWriteValueForCharacteristic”委托方法中我得到以下错误:

Error writing characteristic value: Unknown error.

谁能帮我这个?可能是这个错误的原因是什么?

另外如果我试图定义在BLE设备上发送数据的特性,例如:

CBMutableCharacteristic *writeChar=[[CBMutableCharacteristic alloc]initWithType:[CBUUID UUIDWithString:@"ffe1"] properties:CBCharacteristicPropertyWriteWithoutResponse|CBCharacteristicPropertyNotify value:nil permissions:CBAttributePermissionsWriteable|CBAttributePermissionsReadable];
int8_t cmd=*[cmd1 UTF8String];

NSData *data = [NSData dataWithBytes:&cmd length:sizeof(cmd)];

NSInteger dataSize = [[NSByteCountFormatter stringFromByteCount:dataToWrite.length countStyle:NSByteCountFormatterCountStyleFile] integerValue];
if (dataSize > 130) {
    NSLog(@"Cannot send more than 130 bytes");
}
else
{
    [self.peripheral writeValue:dataToWrite forCharacteristic:writeChar type:CBCharacteristicWriteWithResponse];
    //        [self.peripheral writeValue:dataToWrite forCharacteristic:writeChar type:CBCharacteristicWriteWithResponse];
}

然后我收到这个错误:

**CoreBluetooth[WARNING] CBMutableCharacteristic: 0x1552a270 UUID = Unknown (<ffe1>),Value = (null), Properties = 0x14, Permissions = 0x3, Descriptors = (null), SubscribedCentrals = (
)> is not a valid characteristic for peripheral <CBPeripheral: 0x15549930 identifier = FC71890D-9F71-5E16-086D-D491E1EF7599, Name = " DEMOBLE1", state = connected**

3 回答

  • 0

    当您编写数据时,您正在请求响应( CBCharacteristicWriteWithResponse ) .

    如果您要写入的特性没有设置属性 CBCharacteristicPropertyWrite ,则写入将失败,但仅支持无响应的写入( CBCharacteristicPropertyWriteWithoutResponse ) .

    if ((self.positionCharacteristic.properties & CBCharacteristicPropertyWrite) == CBCharacteristicPropertyWrite) {
        // Responses are available, so write with response.
        [self.peripheral writeValue:dataToWrite forCharacteristic:self.positionCharacteristic type:CBCharacteristicWriteWithResponse];
    }
    else if ((self.positionCharacteristic.properties & CBCharacteristicPropertyWriteWithoutResponse) == CBCharacteristicPropertyWriteWithoutResponse) {
        // Responses are not available.
        // Write with response is going to fail, so write without response.
        [self.peripheral writeValue:dataToWrite forCharacteristic:self.positionCharacteristic type:CBCharacteristicWriteWithoutResponse];
    }
    
  • 1

    我在开发iOS App(作为Central)和BLE Device固件(作为Peripheral)时看到了这个错误 . 当我更改/修改BLE外设上的特性时会发生这种情况 .

    iOS似乎在连接后缓存有关服务和特征的信息 . 每当我构建/下载新固件到设备时,我就能通过更新外围设备的蓝牙地址来解决这个问题 .

  • 9

    首先,你正在使用 CBCentralManager ,对吧?

    确保以正确的方式进行:

    • 使用 CBCentralManager
    self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
    
    • 检测外围设备何时连接
    - (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
    {
    
        if (connectedDevice) // make sure you disconnect previous device
            [self.centralManager cancelPeripheralConnection:connectedDevice];
    
        connectedDevice = [peripheral retain];
        connectedDevice.delegate = self;
        [connectedDevice discoverServices:nil]; // this will discover all kind of services
    }
    
    • 如果在连接过程中出现问题,您可以在这里找到(例如,电量不足)
    - (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{
        NSLog(@"Did fail to connect: %@",error.description);
        connectedDevice = nil;
    }
    
    • 成功连接的BLE出现问题(例如,电池电量不足,用户关闭了设备)
    - (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{
        NSLog(@"Disconnected: %@",error.description);
        connectedDevice = nil;
    }
    
    • 在这里,您可以找到可用的服务
    - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {
        NSLog([NSString stringWithFormat:@"%@",[advertisementData description]]);
    }
    

    6 .

    - (void)centralManagerDidUpdateState:(CBCentralManager *)central{
            NSString *messtoshow;
    
            switch (central.state) {
                case CBCentralManagerStatePoweredOn:
                {
                    [NSString stringWithFormat:@"Bluetooth is currently powered on and available to use."];
    
                    CBUUID *heartRate = [CBUUID UUIDWithString:HRM_SERVICE_UUID];
                    CBUUID *batteryLevel = [CBUUID UUIDWithString:BATTERY_LIFE_SERVICE_UUID];
    
                    NSDictionary *scanOptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:CBCentralManagerScanOptionAllowDuplicatesKey];
    
                    [self.centralManager scanForPeripheralsWithServices:[NSArray arrayWithObjects:heartRate,batteryLevel,nil] options:scanOptions];
                    break;
                }
    
            }
        }
    
    • 从现在开始,您可以实现 CBPeripheralDelegate 方法
    - (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
    {
        for (CBService *service in peripheral.services) {
            NSLog(@"Discovered service: %@", service.UUID);
            [peripheral discoverCharacteristics:nil forService:service];
        }
    }
    
    - (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
    {
        if ([service.UUID isEqual:[CBUUID UUIDWithString:HRM_SERVICE_UUID]])  {
            for (CBCharacteristic *aChar in service.characteristics)
            {
                if ([aChar.UUID isEqual:[CBUUID UUIDWithString:HRM_MEASUREMENT_CHARACTERISTIC_UUID]]) {
                    [connectedDevice setNotifyValue:YES forCharacteristic:aChar];
                }
            }
        }
    
        if ([service.UUID isEqual:[CBUUID UUIDWithString:BATTERY_LIFE_SERVICE_UUID]])  {
            for (CBCharacteristic *aChar in service.characteristics)
            {
                if ([aChar.UUID isEqual:[CBUUID UUIDWithString:BATTERY_LEVEL_CHARACTERISTIC_UUID]]) {
                    [connectedDevice readValueForCharacteristic:aChar];
                }
            }
        }
    }
    
    - (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
    {
        NSError* err = nil;
        if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:HRM_MEASUREMENT_CHARACTERISTIC_UUID]]) {
                NSData *data = [characteristic value];
        }
    
        if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:BATTERY_LEVEL_CHARACTERISTIC_UUID]]) { 
    
        }
    }
    

    这应该工作正常 . 我以同样的方式实现了它,并没有任何问题 . 我希望这有帮助 .

相关问题