Several months ago I published a UWP app on GitHub that interacted with a Texas Instruments CC2650STK SensorTag using the Bluetooth Low Energy (BLE) API. It was based upon a previous Microsoft sample UWP app for interacting with an earlier TI SensorTag. Whilst the new app ran well on the Windows 10 Desktop and Windows 10 Phone, it was found to be erratic on the Raspberry Pi3 running Windows 10 IoT-Core.. working well some times but errant other times. Windows 10 Creators Edition added a key feature to BLE, namely the ability to connect to a device that is advertising without being paired. This blog examines the erratic nature of the RPi3 with BLE and investigates whether this is solved with the Creators Edition. In so do a comparison is made between between BLE Paired and Unpaired connectivity in the UWP app development context..
UWP: Universal Windows Platform. Apps developed using UWP can be compiled for all Windows 10 platforms (desktop, phone, IoT-Core, Holo Lens, XBox etc). You can though have extensions that restrict the applicability across platforms. For example adding GPIO extensions are only applicable to IoT-Core.
BLE: Bluetooth Low Energy is a wireless personal area network technology. Compared to Classic Bluetooth, Bluetooth Smart is intended to provide considerably reduced power consumption and cost while maintaining a similar communication range. BLE has broad range of Profiles, such as Heart Rate Monitor, Sensor, Proximity etc. Each has a standardised set of services, which have characteristics that deliver standardised data. So if you have, for example, a BLE Heart Rate Monitor, you can develop apps for it based upon Bluetooth Sig documentation without regard to the manufacturer. A BLE device will typically implement a number of profiles starting with the BLE Generic Access Profile.
GATT/GAP: Generic Attributes/Generic Profile. The Generic Attributes define a hierarchical data structure that is exposed to connected BLE devices. GATT profiles enable extensive innovation while still maintaining full interoperability with other Bluetooth® devices. A profile describes a use case, roles and general behaviours based on the GATT functionality. Services are collections of characteristics and relationships to other services that encapsulate the behaviour of part of a device. This also includes hierarchy of services, characteristics and attributes used in the attribute server.
GATT Client and Servers: A BLE sensor would be a server as it servers up data on request or as available (on change/periodically) to clients. A desktop or phone app would be a client. GATT procedures can be considered to be split into three basic types: Discovery procedures, Client-initiated procedures and Server-initiated procedures. The GATT server stores the data transported over the ATT and accepts ATT requests, commands and confirmations from the GATT client. The GATT server sends responses to requests and sends indications and notifications asynchronously to the GATT client when specified events occur on the GATT server. GATT also specifies the format of data contained on the GATT server.
djaus2/CC2650SensorTag-cs project is a port of the Microsoft sample UWP ms-iot/Samples/BluetoothGatt/CS GitHub project to support the Texas Instruments CC2650STK, the CC2650 SensorTag. The Microsoft code only supports the TI CC2541 Sensor Tag. This code has been refactored and extended to only support the CC2650. The code establishes a connection to the service for each of the BTE characteristics and displays their values in real time. A major difference from the CC2541 is that the Gyroscope, Magnetometer and Accelerometer are one characteristic, Motion. Also this tag has a reed switch. By default, sensors run in Notification mode where they periodically update their values to the UI through a UI Callback. There is an option to manually read sensor values. This code also supports the IO Characteristic enabling turning on/off of the LEDs 1 & 2 as well as the Buzzer on and off. Whilst the sensor services and there characteristics are TI specific, the app has been also extended to read Battery Voltage using the GATT Battery Service profile and the SensorTag system information is read using the BLE GATT Device Information profile.
The code has been specifically refactored so that the CC2650 functionality is defined in a separate class. The UI for displaying data and for user input is in the MainPage class. Code for handling Bluetooth connectivity, characteristic metadata, service code and event handlers are all in the CC2650 class. The class uses a Callback mechanism to update data in the UI.
At “full-bore” the app receives about 90 data update events per 15 second period from the SensorTag.
The SensorTag was required to be paired over Bluetooth with the app's host. Bluetooth SIG does not require participants in a BLE exchange to be paired. Windows 10 previously has required devices to be paired in UWP code. You could either pair the devices outside of the app (eg in Settings or Device Portal) or in-app. The original Microsoft sample app used this in-app pairing. This was found to be problematic with IoT-Core as in-app pairing requires a PopUp dialog as the user has to confirm acceptance of pairing and of use of Bluetooth in the app. The PopUp API is not supported with IoT-Core. Whilst there was an XAML UI workaround with the Microsoft code for this, the workaround stopped working (at least in the CC2650SensorTag-CS app) on IoT-Core circa the Anniversary edition of Windows 10. At this point the CC2650SensorTag-CS had pairing removed from the app, requiring the user to do the pairing in IoT-Core using Device Portal.
The service characteristics with the SensorTag are:
This app:(a) Is for Windows 10 Anniversary Edition (Build 14393) Desktop, Phone and IoT-Core
(b) Requires the SensorTag to be paired with the app's host(b) You are not discovering services and characteristics; you are requesting access to specific BT Sig known services and their known characteristics as well as known TI services and characteristics.
djaus2/CC2650SensorTag-CE specifically targets the Creators Edition of Windows 10 as it makes uses of Advertisement by the SensorTag to connect without pairing. The most recent update for Windows 10, Creator edition (version 1503), including for IoT-Core has implemented unpaired BLE connectivity. Rather that running a DeviceWatcher with an AQS filter for the known device classes (through their UUIDs), the app looks for Advertisements from the SensorTag using a BluetoothLEAdvertisementWatcher class instance. (A filter can be applied to the the watcher to narrow the BLE classes that the app is receptive ) These advertisements can be noticed when the tag is Advertisement/Pairing mode which is entered by a short press on tag's power button (on the left).
This app:(a) Is for Windows 10 Creators Edition (Build 15053) Desktop, Phone and IoT-Core
(b) Does not require pairing, only needs SensorTag in Advertising mode at start.(b) You discover services and characteristics; which then are referred to BT Sig known services and their known characteristics as well as known TI services and characteristics.
There have been two problems evident in differing ways with both apps:
When the first app stats, it runs a watcher that is looking for a paired SensorTag to connect and be listed. The user then initiates connection through the UX and then sets up the services (one for each sensor on the SensorTag) and their characteristics.. Each Notify characteristic (action when a sensor provides new data) is hooked up to its handler. In logging, these notify counted and logged. When the second app starts, the user initiates connectivity by starting a watcher which picks up on the SensorTag advertisement and launches the service/characteristics interrogation.with the SensorTag.
Connectivity: It has been found that connectivity can be a bit problematic with the first app particularly with the Raspberry Pi3, which has built in BLE capability. On moving to unpaired connectivity it was hoped that this was improved and it is a big improvement. It works every time with the desktop, phone and Dragonboard 410c. It is more reliable withe the RPi3 but still not 100%.
For performance, the apps were tested by running the SensorTag such that all sensors are delivering updates at the default update rate of one update every second (every 0.8s for Luminosity sensor). This amounts to 79 updates per 15 seconds. With the second app an addition update is received from the SensorTag system making 94 updates per 15 seconds. Each sensor’s update is a separate update and the processing for each involves converting a binary array into one or more floats (actually doubles). At issue is whether the target system where the app runs can cope with these data updates.
Loss of Events; With the first app it was noticed that with the RPi3 there are seemingly random periods of random length where no update events are received. It can stop receiving for a few of more seconds. When this happens all sensors on the SensorTag stop sending data, but it generally does recover. Long term we get about 90-95% of expected events. This does not occur on the phone and desktop (Dragonboard 2Do) with the exact same code.
Update events per 15 second period with with first app running on a RPi3 showing dropouts (from nominal 79 events/15s)
With the second app when data reception is lost, it does not recover. This has only been noticed on the RPi3: The Dragonboard ran at “full-bore” for over 10 hours not missing a single event, and the phone has run for in excess of 6 hours without a hiccup. The desktop similarly ran for over 12 hours without fault.
The possible causes of this anomaly are:
The first thing investigated was the app code with some code modifications to improve asynchronous functionality of the app. Secondly it was suggested that the SensorTag battery voltage might be at issue. Button cells are used with a starting voltage of 3.3V (100%) and dropping to 80%. The SensorTag was directly connected to the 3.3v on the RPi3. Both of these actions did not solve the dropout issue. Also various operating system builds were tested but none exhibited and better or worse performance
Further testing found (as stated above) that the dropout issue was confined to the RPi3, eliminating possible causes 1 to 5. This also eliminates the SensorTag So the finger is pointed at the RPi3 Bluetooth hardware or the OS as it specifically runs on the RPi3. It seems that in these timeout periods, that the device is “sleeping” as (with the first app) is comes alive again after a random period. Could it be that the OS is doing some housekeeping, such as downloading updates? Perhaps system functionality could be logged. Also a Bluetooth sniffer could be log BLE transmission against time and be compared app logs.The RPI3 Bluetooth hardware could be tested by running a similar app using Linux on the RPI3.