Чтение данных с устройства BLE
Я пытаюсь прочитать данные с устройства bluetooth (BR-LE4.0-S2). Я смог подключить устройство BLE, но не смог прочитать данные из него. У меня нет спецификации о службах BLE и ее характеристиках. Здесь моя проблема - (void)peripheral:didUpdateValueForCharacteristic:error:
не вызвана. Я следил за учебником " https://developer.apple.com/library/ios/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/PerformingCommonCentralRoleTasks/PerformingCommonCentralRoleTasks.html#//apple_ref/doc/uid/TP40013257-CH3-SW2". Следующим является мой код.
Какое мое требование - непрерывно считывать данные с устройства BLE. Любая помощь приветствуется.
- (void)viewDidLoad
{
self.myCentralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
self.peripheral = [[CBPeripheral alloc] init];
self.peripheral.delegate = self;
[super viewDidLoad];
}
- (void) centralManagerDidUpdateState:(CBCentralManager *)central {
switch (central.state) {
case CBCentralManagerStatePoweredOn:
[self.myCentralManager scanForPeripheralsWithServices:nil options:nil];
break;
default:
NSLog(@"Central Manager did change state");
break;
}
}
- (void)centralManager:(CBCentralManager *)central
didDiscoverPeripheral:(CBPeripheral *)peripheral
advertisementData:(NSDictionary *)advertisementData
RSSI:(NSNumber *)RSSI {
NSLog(@"Discovered %@", peripheral.name);
[self.myCentralManager stopScan];
NSLog(@"Scanning stopped");
if (self.peripheral != peripheral) {
self.peripheral = peripheral;
NSLog(@"Connecting to peripheral %@", peripheral);
// Connects to the discovered peripheral
[self.myCentralManager connectPeripheral:peripheral options:nil];
}
}
- (void)centralManager:(CBCentralManager *)central
didConnectPeripheral:(CBPeripheral *)peripheral {
NSLog(@"Peripheral connected");
NSLog(@"Peripheral services : %@",peripheral.services );
[self.peripheral setDelegate:self];
[peripheral discoverServices:nil];
}
- (void)peripheral:(CBPeripheral *)peripheral
didDiscoverServices:(NSError *)error {
if (error) {
NSLog(@"Error discovering service: %@", [error localizedDescription]);
return;
}
for (CBService *service in peripheral.services) {
[peripheral discoverCharacteristics:nil forService:nil];
}
}
- (void)peripheral:(CBPeripheral *)peripheral
didDiscoverCharacteristicsForService:(CBService *)service
error:(NSError *)error {
int i = 0;
for (CBCharacteristic *characteristic in service.characteristics) {
[peripheral setNotifyValue:YES forCharacteristic: characteristic];
}
}
- (void)peripheral:(CBPeripheral *)peripheral
didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic
error:(NSError *)error {
NSData *data = characteristic.value;
NSString *value = [[NSString alloc] initWithData:characteristic.value encoding:NSUTF8StringEncoding];
NSLog(@"Value %@",value);
NSString *stringFromData = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"Data ====== %@", stringFromData);
}
- (void)peripheral:(CBPeripheral *)peripheral
didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic
error:(NSError *)error {
if (error) {
NSLog(@"Error changing notification state: %@",
[error localizedDescription]);
}
NSString *value = [[NSString alloc] initWithData:self.interestingCharacteristic.value encoding:NSUTF8StringEncoding];
NSLog(@"Value %@",value);
NSLog(@"description: %@, descriptors: %@, properties: %d, service :%@, value:%@", characteristic.description, characteristic.descriptors, characteristic.properties, characteristic.service, characteristic.value);
NSData *data = characteristic.value;
if (characteristic.isNotifying) {
NSString *stringFromData = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
[peripheral readValueForCharacteristic:characteristic];
NSLog(@"Data ====== %@", @"ccdc");
} else {
[self.myCentralManager cancelPeripheralConnection:peripheral];
}
}
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
NSLog(@"Peripheral Disconnected");
self.peripheral = nil;
// We're disconnected, so start scanning again
NSDictionary *scanOptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:CBCentralManagerScanOptionAllowDuplicatesKey];
[self.myCentralManager scanForPeripheralsWithServices:nil options:scanOptions];
}
Ответы
Ответ 1
Чтобы прочитать значение с периферийного устройства BLE, выполните следующие действия.
-
Сканирование для avilable устройств
NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:CBCentralManagerScanOptionAllowDuplicatesKey];
[self.myCentralManager scanForPeripheralsWithServices:nil options:options];`
-
При обнаружении устройства возвращается вызов метода делегирования "didDiscoverPeripheral". Затем установите соединение с обнаруженным устройством BLE
-(void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {
//Connect detected device....
if (!peripheral.isConnected) {
peripheral.delegate = self;
[bluetoothManager_ connectPeripheral:peripheral options:nil];
}
}
-
При успешном соединении запросите все сервисы, доступные в устройстве BLE
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{
NSLog(@"Peripheral Connected");
// Make sure we get the discovery callbacks
peripheral.delegate = self;
// Search only for services that match our UUID
[peripheral discoverServices:nil];
}
-
Запросить все характеристики, доступные в каждой службе
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error {
if (error) {
NSLog(@"Error discovering services: %@", [error localizedDescription]);
return;
}
// Loop through the newly filled peripheral.services array, just in case there more than one.
for (CBService *service in peripheral.services) {
[peripheral discoverCharacteristics:nil forService:service];
}
}
-
Как только мы получим требуемые характеристики, нам нужно подписаться на него, что позволяет периферийным устройствам знать, что мы хотим, чтобы содержащиеся в нем данные
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error{
// Deal with errors (if any)
if (error) {
NSLog(@"Error discovering characteristics: %@", [error localizedDescription]);
return;
}
// Again, we loop through the array, just in case.
for (CBCharacteristic *characteristic in service.characteristics) {
if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:REQUIRED_CHARA_ID]]) {
// If it is, subscribe to it
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
}
}
}
-
Выполняя все эти шаги, устройство BLE сообщит вам об изменении статуса уведомления с помощью метода делегирования
- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
if (error) {
NSLog(@"Error changing notification state: %@", error.localizedDescription);
}
// Notification has started
if (characteristic.isNotifying) {
NSLog(@"Notification began on %@", characteristic);
}
}
Вы получите уведомление с устройства BLE следующим способом.
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
if (error) {
NSLog(@"Error reading characteristics: %@", [error localizedDescription]);
return;
}
if (characteristic.value != nil) {
//value here.
}
}
Ответ 2
Swift версия itZme answer с небольшим изменением из-за отсутствия didConnectToPeripheral
(вы также необходимо поддерживать сильную ссылку на периферийные устройства, чтобы подключиться следующим образом:
Сканирование доступных устройств:
centralManager.scanForPeripheralsWithServices(nil, options: nil)
При обнаружении устройства возвращается вызов метода делегирования "didDiscoverPeripheral". Затем установите соединение с обнаруженным устройством BLE. Но сначала сохраните сильную ссылку на периферийные устройства:
private var peripheral: [CBPeripheral] = []
func centralManager(central: CBCentralManager, didDiscoverPeripheral peripheral: CBPeripheral, advertisementData: [String : AnyObject], RSSI: NSNumber) {
if peripheral.state == .Connected {
self.peripherals.append(peripheral)
peripheral.delegate = self
centralManager.connectPeripheral(peripheral , options: nil)
}
}
И остальное должно быть всем:
extension ViewController: CBPeripheralDelegate {
func centralManager(central: CBCentralManager, didFailToConnectPeripheral peripheral: CBPeripheral, error: NSError?) {
if error != nil {
print("Error connecting to peripheral: \(error?.localizedDescription)")
return
}
}
func centralManager(central: CBCentralManager, didConnectPeripheral peripheral: CBPeripheral) {
print("Peripheral connected.")
peripheral.delegate = self
peripheral.discoverServices(nil)
}
func peripheral(peripheral: CBPeripheral, didDiscoverServices error: NSError?) {
if error != nil {
print("Error discovering services \(error?.localizedDescription)")
return
}
for service: CBService in peripheral.services! {
peripheral.discoverCharacteristics(nil, forService: service)
}
}
func peripheral(peripheral: CBPeripheral, didDiscoverCharacteristicsForService service: CBService, error: NSError?) {
if error != nil {
print("Error discovering characteristics \(error?.localizedDescription)")
return
}
for characteristic: CBCharacteristic in service.characteristics! {
if characteristic.UUID == CBUUID(string: YOUR_CHARACTERISTIC_UUID) {
peripheral.readValueForCharacteristic(characteristic)
// for some devices, you can skip readValue() and print the value here
}
}
}
func peripheral(peripheral: CBPeripheral, didUpdateValueForCharacteristic characteristic: CBCharacteristic, error: NSError?) {
if characteristic.UUID == CBUUID(string: YOUR_CHARACTERISTIC_UUID) {
print(characteristic.value)
}
}
}
Ответ 3
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
for newChar: CBCharacteristic in service.characteristics!{
peripheral.readValue(for: newChar)
if newChar.properties.rawValue == 0x10 || newChar.properties.rawValue == 0x8C{
peripheral.setNotifyValue(true, for: newChar)
}
else if newChar.properties.rawValue == 0x12{
peripheral.setNotifyValue(true, for: newChar)
}
}
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
print(characteristic)
}