- (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?
Related
I am working on BLE app(Heath related), In that i have one option to get ECG values from BLE device.In that i need to enable 8 waveforms to get ECG data in my app.
My question how i can enable all waveforms using CBDescriptor.I need to pass data like below to CBDescriptor.
Format of Waveform ID
0: 8bit, 1: 16bit, 2: 32bit, 3: 64bit, 4:128bit, 5: 8bit*3, 6: 16bit*3, 7: 32bit*3
uint8_t waveArray[8] = {0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00};
NSData *waveData = [NSData dataWithBytes:waveArray length:sizeof(waveArray)/sizeof(uint8_t)];
[peripheral writeValue:waveData forDescriptor:descript];
But i didn't get any response from device. Please help me.
Finally i got solution for my question. First we need to call discover methods for CBDescriptor.
[peripheral discoverDescriptorsForCharacteristic:characteristic];
-(void)peripheral:(CBPeripheral *)peripheral didDiscoverDescriptorsForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
NSArray *Descroptors = [characteristic descriptors];
CBDescriptor *descript;
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
for (descript in Descroptors)
{
if ([descript.UUID isEqual:[CBUUID UUIDWithString:KT_WP_WC_CHARACTERISTIC]])
{
uint8_t waveArray[9] = {0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00};//Your data which you need to send to BLE device
NSData *waveData = [NSData dataWithBytes:waveArray length:sizeof(waveArray)/sizeof(uint8_t)];
[peripheral writeValue:waveData forDescriptor:descript];
NSLog(#"waveData ==%#",waveData);
CBUUID * sCBUUID = [CBUUID UUIDWithString:KT_WP_SERVICE];
CBUUID * cCBUUID = [CBUUID UUIDWithString:KT_WP_WF_CHARACTERISTIC];
[self CBUUIDwriteValue:sCBUUID characteristicUUID:cCBUUID p:peripheral data:waveData];
}else
{
const unsigned char bytes[] = { 0x28, 0x00 };//Your data which you need to send BLE device
NSData *descriptorData = [NSData dataWithBytes:bytes length:2];
CBUUID * sCBUUID = [CBUUID UUIDWithString:KT_WP_SERVICE];
CBUUID * cCBUUID = [CBUUID UUIDWithString:KT_WP_WF_CHARACTERISTIC];
[self CBUUIDwriteValue:sCBUUID characteristicUUID:cCBUUID p:peripheral data:descriptorData];
}
}
}
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 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
I am a ios developer.
I can take a value from arduino sensor. But i cannot send a message by using the following the method.
[peripheral writeValue:dataToWrite forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
"dataToWrite" value is alloc by using NSString*
NSString* data = #"1";
NSData* dataToWrite = [data dataUsingEncoding:NSUTF8StringEncoding];
and the following code is full code of "DiscoverCharacteristics in service"
//DISCOVER CHAR
-(void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
if (error) {NSLog(#"DISCOVER_CHAR - Error");return;}
NSString* data = #"1";
NSData* dataToWrite = [data dataUsingEncoding:NSUTF8StringEncoding];
for (CBCharacteristic * characteristic in service.characteristics) {
NSLog(#"DISCOVER_CHAR - Characteristic : %#",characteristic);
[peripheral writeValue:dataToWrite forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
}
}
In this point, I want to summarize my question.
My Question is
"Even i used the [Peripheral writeValue:forCharacteristic:type] Method. why an error message is shown in log monitor? " Like "Writing is not permitted."
Do i need to get some permission to writing the message for an Arduino?
OR I have to change my following code?
OR I have a problem in Arduino(Acutally, Arduino can get a message from other device... so, Arduino source code is fine. maybe...)
NSString* data = #"1";
NSData* dataToWrite = [data dataUsingEncoding:NSUTF8StringEncoding];
I'm a bit of a bluetooth noob. So it's probably something obvious I've overlooked but any help would be much appreciated.
Thank you!:)
Thank you a lot!!!!!!! Paulw11. Finally, i sent a data from iphone to Arduino. what i checked properties of my characteristic is
<CBCharacteristic: 0x13564a680, UUID = FFE1, properties = 0x16, value = (null), notifying = NO>.
My characteristic's properties = 0x16. but i can not find a 0x16 in enum of properties. Still, I don't know the 0x16 meaning. Someone said that "Values representing the possible properties of a characteristic. Since characteristic properties can be combined, a characteristic may have multiple property values set."
URL: Interpret Characteristic Properties (iOS and BLE) .
Anyway I could find a solution by PaulW11 help! How i can do it? Here is my way of solution.
At first, My method is [peripheral writeValue:dataToWrite forCharacteristic:characteristic *type:CBCharacteristicWriteWithResponse]*;.
The problem code is type field. I had to understand the type. The type has a meaning of write, read and so on. So, I changed the type from CBCharacteristicWriteWithResponse to CBCharacteristicPropertyWrite. That is what i did.
[peripheral writeValue:dataToWrite forCharacteristic:characteristic *type:CBCharacteristicPropertyWrite*];
Thank you again! Paulw11
try to print error inside following method:
-(void)peripheral:(CBPeripheral *)peripheral
didWriteValueForCharacteristic:(CBCharacteristic *)characteristic
error:(NSError *)error
{
NSLog(#"%#",error.localizedDescription);
}
If the error is "Writing is not permitted", then you might not writing the data correctly.Convert the string value in this format
NSData* data = [#"string_to_write" dataUsingEncoding:NSASCIIStringEncoding];
And try this:
[self.peripheral writeValue:data forCharacteristic:self.characteristic type:CBCharacteristicWriteWithoutResponse];
Hope it works!!
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.