- What You Need for This Project
- Building the Application
- Querying the SensorTag for Services
- Previewing the Camera
- Taking Snapshots
- Summary
- Appendix: Listing for ViewController.swift
Querying the SensorTag for Services
Once the SensorTag is connected, you should query it for services. In particular, you should query it for the service that lets you know if one of the two buttons is pressed. For the SensorTag, the service for the button presses has the UUID FFE0.
Add the following statements in bold to the ViewController.swift file:
import UIKit import CoreBluetooth class ViewController: UIViewController, CBCentralManagerDelegate, CBPeripheralDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate { @IBOutlet weak var btnLeft: UIButton! @IBOutlet weak var btnRight: UIButton! @IBOutlet weak var txtStatus: UILabel! var serviceKeyPressesUDID: CBUUID! var connectedSensorTag: CBPeripheral! var centralManager: CBCentralManager! ... override func viewDidLoad() { super.viewDidLoad() //---the UUID for the button presses--- serviceKeyPressesUDID = CBUUID(string:"FFE0") self.centralManager = CBCentralManager(delegate: self, queue: nil) } ... func centralManager(central: CBCentralManager!, didConnectPeripheral peripheral: CBPeripheral!) { println("Peripheral connected: \(peripheral.name)") peripheral.delegate = self //---discover the specified service--- var services = [serviceKeyPressesUDID] peripheral.discoverServices(services) } //---fired when services are discovered--- func peripheral(peripheral: CBPeripheral!, didDiscoverServices error: NSError!) { for service in peripheral.services { println( "P: \(peripheral.name) - Discovered service S:'\(service.UUID)'") } }
Deploy the application to the device again. When the service is discovered, the following output should appear in the Output window:
centralManagerDidUpdateState: CBCentralManagerStatePoweredOn Discovered TI BLE Sensor Tag
NSUUID string AFAAAFD7-0573-3B76-4202-031393542B15
Peripheral connected: TI BLE Sensor Tag
P: TI BLE Sensor Tag - Discovered service S:'FFE0'
Querying the Services for Characteristics
When the required service has been found, you need to query the characteristics of the service to obtain the value indicating which button on the SensorTag is pressed. For the SensorTag, the characteristic for the value of the button presses has the UUID FFE1.
Add the following statements in bold to the ViewController.swift file:
import UIKit import CoreBluetooth class ViewController: UIViewController, CBCentralManagerDelegate, CBPeripheralDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate { @IBOutlet weak var btnLeft: UIButton! @IBOutlet weak var btnRight: UIButton! @IBOutlet weak var txtStatus: UILabel! var serviceKeyPressesUDID: CBUUID! var characteristicKeyPressesUDID: CBUUID! var connectedSensorTag: CBPeripheral! var centralManager: CBCentralManager! ... override func viewDidLoad() { super.viewDidLoad() serviceKeyPressesUDID = CBUUID(string:"FFE0") characteristicKeyPressesUDID = CBUUID(string:"FFE1") self.centralManager = CBCentralManager(delegate: self, queue: nil) } func peripheral(peripheral: CBPeripheral!, didDiscoverServices error: NSError!) { for service in peripheral.services { println( "P: \(peripheral.name) - Discovered service S:'\(service.UUID)'") if service.UUID == serviceKeyPressesUDID { //---discover the specified characteristic of the service--- var characteristics = [characteristicKeyPressesUDID] //---discover the characteristics of the service--- peripheral.discoverCharacteristics( characteristics, forService: service as CBService) } } } ... //---fired when characteristics are found--- func peripheral(peripheral: CBPeripheral!, didDiscoverCharacteristicsForService service: CBService!, error: NSError!) { }
When the specific characteristic is discovered, this method is fired:
peripheral:disDiscoverCharacteristicsForService:error:
Subscribing to the Characteristic for KeyPressed
For a characteristic that you have discovered, you can typically perform three operations with it:
- Read its value
- Write a value to it
- Subscribe to it so that you can be notified whenever the characteristic's value changes
Because you don't know when a button is pressed, you need to subscribe to the characteristic so that you will be notified whenever the button is pressed.
Add the following statements in bold to the ViewController.swift file:
func peripheral(peripheral: CBPeripheral!, didDiscoverCharacteristicsForService service: CBService!, error: NSError!) { for characteristic in service.characteristics { //---look for the characteristic that allows you to subscribe to--- if characteristic.UUID == characteristicKeyPressesUDID { //---subscribe to the characteristic--- peripheral.setNotifyValue(true, forCharacteristic:characteristic as CBCharacteristic) } } }
Add the following method to the ViewController class so that it can be fired when you've subscribed to a characteristic:
func peripheral(peripheral: CBPeripheral!, didUpdateNotificationStateForCharacteristic characteristic: CBCharacteristic!, error: NSError!) { if (error != nil) { println( "Error changing notification state: \(error.localizedDescription)") } else { println("Characteristic's value subscribed") } }
Deploy the application to the device again. When you've subscribed to a characteristic, the following code will appear in the Output window:
centralManagerDidUpdateState: CBCentralManagerStatePoweredOn Discovered TI BLE Sensor Tag
NSUUID string AFAAAFD7-0573-3B76-4202-031393542B15
Peripheral connected: TI BLE Sensor Tag
P: TI BLE Sensor Tag - Discovered service S:'FFE0'
Characteristic's value subscribed
Receiving Updates When Buttons Are Pressed
When a button is pressed on the SensorTag, the following method will be fired:
peripheral:didUpdateValueForCharacteristic:error:
Add the following method to the ViewController class:
func peripheral(peripheral: CBPeripheral!, didUpdateValueForCharacteristic characteristic: CBCharacteristic!, error: NSError!) { if characteristic.UUID == characteristicKeyPressesUDID { var keyPressed:UInt16 = 0 characteristic.value.getBytes(&keyPressed, length: sizeof(UInt16)) //---legends--- // 1 - right button // 2 - left button // 0 - button released // 3 - both buttons pressed println("\(keyPressed)") switch (keyPressed) { case 0: //---a button is lifted--- self.btnLeft.selected = false self.btnRight.selected = false case 1: //---right button pressed--- self.btnRight.selected = true self.btnLeft.selected = false case 2: //---left button pressed--- self.btnLeft.selected = true self.btnRight.selected = false case 3: //---both buttons pressed--- self.btnLeft.selected = true self.btnRight.selected = true default: return } return } }
The following table shows the values that the characteristic for the keypresses will send.
Value Sent |
Occurrence |
1 |
Right button is pressed |
2 |
Left button is pressed |
3 |
Both buttons are pressed |
0 |
A button is released |
When two buttons are pressed and a button is released, the characteristic will send a value of 0 followed by another value indicating which button is still pressed.
Deploy the application to the device again and connect the SensorTag to the device. Pressing the buttons on the SensorTag should cause the images on the buttons to change (see Figure 7).