I am using the following code to write the 0xDE value for a Bluetooth Caracteristic (Reset Device) using the IOS Core Bluetooth :
...
NSData *bytes = [@\"0xDE\"
What you are, in fact, doing here is writing the string "0xDE" to the characteristic. If you want to use binary/octal notation, you need to stay away from strings.
int integer = 0xDE;
NSData *data = [[NSData alloc] initWithBytes:&integer length:sizeof(integer)];
[peripheral writeValue:data
forCharacteristic:characteristic
type:CBCharacteristicWriteWithResponse];
Swift 3.0: In case anyone is wondering the format for Swift is slightly different as writeValue can get the count from the array.
let value: UInt8 = 0xDE
let data = Data(bytes: [value])
peripheral.writeValue(data, for: characteristic, type: .withResponse)
This code will fix the problem :
NSData * data = [self dataWithHexString: @"DE"];
[peripheral writeValue:data forCharacteristic:characteristic
type:CBCharacteristicWriteWithResponse];
dataWithHexString implementation :
- (NSData *)dataWithHexString:(NSString *)hexstring
{
NSMutableData* data = [NSMutableData data];
int idx;
for (idx = 0; idx+2 <= hexstring.length; idx+=2) {
NSRange range = NSMakeRange(idx, 2);
NSString* hexStr = [hexstring substringWithRange:range];
NSScanner* scanner = [NSScanner scannerWithString:hexStr];
unsigned int intValue;
[scanner scanHexInt:&intValue];
[data appendBytes:&intValue length:1];
}
return data;
}
Try creating your data with an array of single byte values.
const uint8_t bytes[] = {0xDE};
NSData *data = [NSData dataWithBytes:bytes length:sizeof(bytes)];
This is a useful approach for creating arbitrary constant data. For more bytes,
const uint8_t bytes[] = {0x01,0x02,0x03,0x04,0x05};
NSData *data = [NSData dataWithBytes:bytes length:sizeof(bytes)];
If you want to create data to send using variables, I would recommend using NSMutableData and appending the bytes that you need. It isn't very pretty, but it is easy to read / understand, especially when you are matching a packed struct on the embedded side. Example below is from a BLE project where we were making a simple communication protocol.
NSMutableData *data = [[NSMutableData alloc] init];
//pull out each of the fields in order to correctly
//serialize into a correctly ordered byte stream
const uint8_t start = PKT_START_BYTE;
const uint8_t bitfield = (uint8_t)self.bitfield;
const uint8_t frame = (uint8_t)self.frameNumber;
const uint8_t size = (uint8_t)self.size;
//append the individual bytes to the data chunk
[data appendBytes:&start length:1];
[data appendBytes:&bitfield length:1];
[data appendBytes:&frame length:1];
[data appendBytes:&size length:1];
The answer by bensarz is almost correct. Except one thing: you shouldn't use sizeof(int)
as the length for NSData
. The size of int
is 4 or 8 bytes (depending on the architecture). As you want to send 1 byte, use uint8_t
or Byte
instead:
uint8_t byteToWrite = 0xDE;
NSData *data = [[NSData alloc] initWithBytes:&byteToWrite length:sizeof(&byteToWrite)];
[peripheral writeValue:data
forCharacteristic:characteristic
type:CBCharacteristicWriteWithResponse];
Of courser you could also use int
as the variable's type, but you have to initialize NSData
with the length of 1.