BLE Swift write characterisitc

17,241

The Swift code written by you is not equivalent to the Objective-C example. The data parameter should be initialized with binary "1" instead of a string "01:00":

var parameter = NSInteger(1)
let data = NSData(bytes: &parameter, length: 1)
peripheral.writeValue(data, for: characteristic, type: .withResponse)

I think that whenever TI docs specify a value in quotes like "01:00" they really mean a hexadecimal value like 0x0100, which is a bit confusing.

Share:
17,241

Related videos on Youtube

gimba
Author by

gimba

Updated on June 04, 2022

Comments

  • gimba
    gimba almost 2 years

    I am trying hard to get my TI sensortag temperature sensor to notify. According to http://processors.wiki.ti.com/images/a/a8/BLE_SensorTag_GATT_Server.pdf I need to set the value of the characteristic with UUID F000AA02-0451-4000-B000-000000000000 to "01:00". Here is what I do:

    import UIKit
    import CoreBluetooth
    
    class ViewController: UIViewController, CBCentralManagerDelegate, CBPeripheralDelegate{
    
        var centralManager:CBCentralManager!
        var blueToothReady = false
        var connectingPeripheral: CBPeripheral!
    
        @IBOutlet weak var textField: UITextView!
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
        }
    
        override func viewDidLoad() {
            super.viewDidLoad()
            startUpCentralManager()
        }
    
        func startUpCentralManager() {
            centralManager = CBCentralManager(delegate: self, queue: nil)
        }
    
        func discoverDevices() {
            centralManager.scanForPeripheralsWithServices(nil, options: nil)
        }
    
        func centralManager(central: CBCentralManager!, didDiscoverPeripheral peripheral: CBPeripheral!, advertisementData: (NSDictionary), RSSI: NSNumber!) {
    
            output("Discovered", data: peripheral.name)
    
            self.connectingPeripheral = peripheral
            centralManager.stopScan()
            self.centralManager.connectPeripheral(peripheral, options: nil)
    
        }
    
        func centralManagerDidUpdateState(central: CBCentralManager!) { //BLE status
            var msg = ""
            switch (central.state) {
            case .PoweredOff:
                msg = "CoreBluetooth BLE hardware is powered off"
                println("\(msg)")
    
            case .PoweredOn:
                msg = "CoreBluetooth BLE hardware is powered on and ready"
                blueToothReady = true;
    
            case .Resetting:
                var msg = "CoreBluetooth BLE hardware is resetting"
    
            case .Unauthorized:
                var msg = "CoreBluetooth BLE state is unauthorized"
    
            case .Unknown:
                var msg = "CoreBluetooth BLE state is unknown"
    
            case .Unsupported:
                var msg = "CoreBluetooth BLE hardware is unsupported on this platform"
    
            }
            output("State", data: msg)
    
            if blueToothReady {
                discoverDevices()
            }
        }
    
        func centralManager(central: CBCentralManager!,didConnectPeripheral peripheral: CBPeripheral!)
        {
            peripheral.delegate = self
            peripheral.discoverServices([CBUUID.UUIDWithString("F000AA00-0451-4000-B000-000000000000")])
            output("Connected", data: peripheral.name)
    
        }
    
        func peripheral(peripheral: CBPeripheral!, didDiscoverServices error: NSError!)
        {
    
            if let servicePeripherals = peripheral.services as? [CBService]
            {
                for servicePeripheral in servicePeripherals
                {
                    output("Service", data: servicePeripheral.UUID)
                    peripheral.discoverCharacteristics(nil, forService: servicePeripheral)
    
                }
    
            }
        }
    
        @IBAction func refreshBLE(sender: UIButton) {
            centralManager.scanForPeripheralsWithServices(nil, options: nil)
        }
    
        func peripheral(peripheral: CBPeripheral!, didDiscoverCharacteristicsForService service: CBService!, error: NSError!) {
            if let charactericsArr = service.characteristics  as? [CBCharacteristic]
            {
                for charactericsx in charactericsArr
                {
                    peripheral.setNotifyValue(true, forCharacteristic: charactericsx)
    
                //                *************************
                if charactericsx.UUID.UUIDString == "F000AA02-0451-4000-B000-000000000000"{
                    output("Characteristic", data: charactericsx)
                    let data: NSData = "01:00".dataUsingEncoding(NSUTF8StringEncoding)!
                    peripheral.writeValue(data, forCharacteristic: charactericsx, type: CBCharacteristicWriteType.WithResponse)
                    output("Characteristic", data: charactericsx)
                }
                //                *************************
    
                    peripheral.readValueForCharacteristic(charactericsx)
                }
    
            }
        }
    
        func peripheral(peripheral: CBPeripheral!, didUpdateValueForCharacteristic characteristic: CBCharacteristic!, error: NSError!) {
            if var data :NSData = characteristic.value {
                output("Data", data: characteristic.value)
            }
    
        }
    
        func output(description: String, data: AnyObject){
            println("\(description): \(data)")
            textField.text = textField.text + "\(description): \(data)\n"
        }
    
    }
    

    Problem is that peripheral.writeValue... doesn't seem to change anything. I looked at the objective c example found here http://www.ti.com/tool/sensortag-sw and think the corresponding lines to

    let data: NSData = "01:00".dataUsingEncoding(NSUTF8StringEncoding)!
    peripheral.writeValue(data, forCharacteristic: characteric, type: CBCharacteristicWriteType.WithResponse)
    

    are these:

    uint8_t data = 0x01;
    [BLEUtility writeCharacteristic:self.d.p sCBUUID:sUUID cCBUUID:cUUID data:[NSData dataWithBytes:&data length:1]];
    

    What am I missing?

  • gimba
    gimba over 9 years
    IT S ALIVE! =D thank you very much, this really gave me a headache
  • Nikhil Gupta
    Nikhil Gupta over 8 years
    @Michal Ciuba Instead of 1 if I want to write "0802". Can I simply do var parameter = NSInteger(0802)?
  • Webber Lai
    Webber Lai almost 8 years
    @NikhilGupta Try this : var parameter = 0x0802 let data = NSData(bytes: &parameter, length: 2)
  • atlantach_james
    atlantach_james over 6 years
    @Michal Ciuba. Do you know if this method works with the new CC2650 SensorTag now that the gyro/acc/mag are organised under one MovementData UUID? If it says that the notify value needs to be set to 0x0001 to enable notifications for these sensors do I simply replace the following code from your example? Obv I know it cant be an integer but appreciate your feedback on this one as its not working for me. var parameter = NSInteger(0x0001)
  • Michał Ciuba
    Michał Ciuba over 6 years
    Unfortunately I know nothing about CC2650 SensorTag. The only thing that comes to my mind is "endianness": maybe you can change the order of bytes? I mean, write: var parameter = NSInteger(0x0100). Other than that, I'm afraid I can't help you.
  • atlantach_james
    atlantach_james over 6 years
    Thanks Michal. No luck with that unfortunately. Have tried lots of different iterations of this but no matter what I can't get this characteristic to notify.