I am sending the date from to the peripheral by using the below code.
NSString* alternative = [NSString stringWithFormat:#"hello"];
NSData *dataToSend = [alternative dataUsingEncoding:NSUTF8StringEncoding];
[self.discoveredPeripheral writeValue:dataToSend forCharacteristic:self.discoveredCharacteristics type:CBCharacteristicWriteWithResponse];
While sending called the delegate method.
- (void)peripheral:(CBPeripheral *)iPeripheral didWriteValueForCharacteristic:(CBCharacteristic *)iCharacteristic error:(NSError *)iError {
NSLog(#"didWriteValue characteristic.value: %# ", iCharacteristic.value);
NSLog(#"Error = %#", iError);
}
But, here I am getting null value.
I can receive in peripheral app also in,
- (void)peripheralManager:(CBPeripheralManager *)iPeripheral didReceiveWriteRequests:(NSArray *)iRequests {
[iPeripheral respondToRequest:[iRequests objectAtIndex:0] withResult:CBATTErrorSuccess];
CBATTRequest *aRequest = iRequests[0];
NSData *aData = aRequest.value;
NSDictionary *aResponse = (NSDictionary *)[NSJSONSerialization JSONObjectWithData:aData options:NSJSONReadingMutableContainers error:nil];
NSLog(#"Received Data = %#", aResponse);
}
receiving result value is same null.
- (void)peripheral:(CBPeripheral *)iPeripheral didWriteValueForCharacteristic:(CBCharacteristic *)iCharacteristic error:(NSError *)iError
The couldn't recognize the issue while sending the data to peripheral.
Any answer will help me a lot
Related
Am new to Objective C Am trying to read data from an arduino peripheral with a specific service and characteristic
there are two characteristics with for two different services
//arduino code
BLEService dataService("938548e6-c655-11ea-87d0-0242ac130003"); //Data reading
BLEService ledService("19B10000-E8F2-537E-4F6C-D104768A1214"); //LED control service
// Initialize dataService characteristics
BLECharacteristic dataArray("77539407-6493-4b89-985f-baaf4c0f8d86", BLERead | BLENotify, 114); // standard 16-bit characteristic UUID
// Initialize ledService characteristics
BLECharacteristic eventChar("19B10001-E8F2-537E-4F6C-D104768A1213", BLERead | BLEWrite, 1);
I was able to notify and got the read value for the first characteristics for when am trying to write for second characteristic am not receiving data from peripheral
for (CBCharacteristic *characteristic in service. characteristics) {
NSLog(#"Charecteristics %#", characteristic.UUID);
if ([characteristic.UUID.UUIDString containsString: #"77539407"]) {
NSLog(#"Specific Characteristics %#", characteristic.UUID);
//Working........ Characteristic
[peripheral setNotifyValue: YES forCharacteristic: characteristic];
}
if ([characteristic.UUID.UUIDString containsString: #"19B10001"]) {
NSLog(#"Specific Charecteristics %#", characteristic.UUID);
NSData *data = [#"01" dataUsingEncoding:NSUTF8StringEncoding];
NSLog(#"WRITING DATA");
NSLog(#"%# : dataaaaaa",data);
[peripheral writeValue: data forCharacteristic: characteristic
type: CBCharacteristicWriteWithResponse];
}
}
after writing the data it goes to the didWriteValueForCharacteristic where I get null for the writeCallBack can someone explain me what mistake am doing
- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
NSLog(#"didWrite");
NSString *key = [self keyForPeripheral: peripheral andCharacteristic:characteristic];
NSLog(#" writeCallback : %# ",key);
RCTResponseSenderBlock writeCallback = [writeCallbacks objectForKey:key];
NSLog(#" writeCallback : %# ",writeCallback);
if (writeCallback) {
if (error) {
NSLog(#"%#", error);
[writeCallbacks removeObjectForKey:key];
writeCallback(#[error.localizedDescription]);
} else {
if ([writeQueue count] == 0) {
NSLog(#"NO 1");
[writeCallbacks removeObjectForKey:key];
writeCallback(#[]);
}else{
// Remove and write the queud message
NSLog(#"NO 2");
NSData *message = [writeQueue objectAtIndex:0];
[writeQueue removeObjectAtIndex:0];
[peripheral writeValue:message forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
}
}
}
}
Below image is the log
OUTPUT LOG
- (void)bleManagerPeripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
NSString * str = #"0A0B";
NSString * hexStr = [NSString stringWithFormat:#"%#",[NSData dataWithBytes:[str cStringUsingEncoding:NSUTF8StringEncoding]
length:strlen([str cStringUsingEncoding:NSUTF8StringEncoding])]];
for(NSString * toRemove in [NSArray arrayWithObjects:#"<", #">", #" ", nil])
hexStr = [hexStr stringByReplacingOccurrencesOfString:toRemove withString:#""];
NSData *data = [hexStr dataUsingEncoding:NSUTF8StringEncoding];
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
[peripheral writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
}
I want to send a message or command to BLE machine like Tea-Maker Machine but device is not responding to my message and I am getting following error:
Error Domain=CBATTErrorDomain Code=3 "Writing is not permitted." UserInfo={NSLocalizedDescription=Writing is not permitted.}
My question is how to send data from our iOS app (iPhone) to the BLE machine by using blemanager?
Sending data through the iOS (writeValue: forCharacteristic: type :) method works fine without error, but the value does not change. Do you know why?
> 2017-06-27 14:53:54.846963+0900 BluetoothSample[12662:5477661] Did
> write characteristic <CBCharacteristic: 0x1700ad500, UUID =
> 2A588021-4FB2-40F5- 8204-85315DEF11C5, properties = 0xA, value =
> <1357>, notifying = NO>
uint8_t val = 123;
NSData * valData = [NSData dataWithBytes:(void*)&val length:sizeof(val)];
[self.discoveredPeripheral writeValue:valData forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
- (void) peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
if (error) {
NSLog(#"didWriteValueForCharacteristic With error: %#", [error localizedDescription]);
self.receivePaketDataTextView.text = [[NSString alloc] initWithFormat:#"%#",[error localizedDescription]];
return ;
}
self.receivePaketDataTextView.text = [[NSString alloc] initWithFormat:#"%#",characteristic.value];
}
When I try to write, only the same logs are printed.
Try:
[self.discoveredPeripheral writeValue: valData
forCharacteristic:self.usedCharacteristic
type:CBCharacteristicWriteWithoutResponse];
Use type: CBCharacteristicWriteWithoutResponse
Also check if you have set the notifier
[self.discoveredPeripheral setNotifyValue:YES forCharacteristic:self.usedCharacteristic];
Before hand in your delegates.
On your iOS central the value of the characteristic in didWriteValueForCharacteristic does not reflect the change you just wrote.
You need to issue an explicit read to get the new value.
This is by design, since there is no guarantee that the value you have just written is the current value of the characteristic; only the peripheral can give you the current value.
I am using the code below written by Apple.
https://developer.apple.com/library/mac/samplecode/HeartRateMonitor/Listings/HeartRateMonitor_HeartRateMonitorAppDelegate_m.html#//apple_ref/doc/uid/DTS40011322-HeartRateMonitor_HeartRateMonitorAppDelegate_m-DontLinkElementID_4
Here is the writeValue section written by Apple
if ([aChar.UUID isEqual:[CBUUID UUIDWithString:#"2A39"]])
{
uint8_t val = 1;
NSData* valData = [NSData dataWithBytes:(void*)&val length:sizeof(val)];
[aPeripheral writeValue:valData forCharacteristic:aChar type:CBCharacteristicWriteWithResponse];
}
I added didWriteValueForCharacteristic
- (void) peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
NSLog(#"Did write characteristic value : %# with ID %#", characteristic.value, characteristic.UUID);
NSLog(#"With error: %#", [error localizedDescription]);
}
The print out from didWriteValueForCharacteristic is the following:
Did write characteristic value : (null) with ID Unknown (<2a39>)
With error: (null)
I have used two different heart monitors and Blue Light app (simulates ble device) but I get the same outcome.
Why do I get null back for the value and error for didWriteValueForCharacteristic?
What you see is the last read value of the characteristic. Since you never read it before, it is nil. You need to explicitly read the value to get it updated on the central side with the readValueForCharacteristic: method.
I implement iOS CoreBluetooth client & server for sending data
client site
[self.connectedPeripheral writeValue:mainData forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
and
- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic
{
NSString *s= [[NSString alloc] initWithData:characteristic.value encoding:NSUTF8StringEncoding];
NSLog(#"didWriteValue characteristic.value: %# ", s);
}
and server site
- (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveWriteRequests:(NSArray *)requests
{
NSData *res= [[NSString stringWithFormat:#"Hello"] dataUsingEncoding:NSUTF8StringEncoding];
[self.peripheral updateValue:res
forCharacteristic:self.writeCharacteristic
onSubscribedCentrals:nil];
[peripheral respondToRequest:aReq withResult:CBATTErrorSuccess];
}
however, client can't receive any data.
Any idea?
Thanks for your help.
According to Apple's doc on CoreBluetooth, you should use:
- (void)respondToRequest:(CBATTRequest *)request withResult:(CBATTError)result;
to reply to the central.This is also a choice when you receive a reading request
To use:
- (BOOL)updateValue:(NSData *)value forCharacteristic:(CBMutableCharacteristic *)characteristic onSubscribedCentrals:(NSArray *)centrals;
you first need to subscribe to it using
- (void)setNotifyValue:(BOOL)enabled forCharacteristic:(CBCharacteristic *)characteristic;
from client side.