BLE Swift write characterisitc

2020-06-18 03:36发布

问题:

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?

回答1:

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.