Category:KeyFobDemo

Bluetooth Low Energy Wiki Main Page

Introduction
This section will guide you through the steps required to run the Bluetooth® low energy KeyFobDemo application on the CC2540DK-MINI kit.

The keyfobdemo application will demonstrate the following.
 * Report battery level
 * Report 3 axis accelerometer readings.
 * Report proximity changes.
 * Report key press changes

Please note that the profiles presented in this document are intended as a guideline only and are not yet aligned with any SIG profile specifications.

Source Code and Hex Files
''' NOTE: This is for version 1.0 release Oct 2010. '''   For 1.1 release and newer version of KeyFobDemo download 1.1 installer at ti.com/blestack 

- KeyFobDemo.zip OBSOLETE - Please use version 1.1 at ti.com/blestack

Installation
Download and unzip on top of existing CC2540DK Mini Kit BluetoothLE.exe installation directory. The default is usually C:\Texas Instruments\BLE-CC2540

Running from the hex binaries
Using the pre-compiled hex files is the easiest way to get started. These are located in the directory C:\Texas Instruments\BLE-CC254x-A.B.C\Accessories\HexFiles where A.B.C is the current version (e.g. 1.2.1).

Use the Smart RF Flash Programmer to load the following images. On pre-1.2.1 versions of the stack, use:


 * cc2540_ble1.0_slave_keyfobdemo.hex --&gt;KeyFob
 * cc2540_ble1.0_master_usb_dongle.hex --&gt;USB Dongle

On post-1.2.1 versions of the stack, use:


 * CC2540MiniDkDemoSlave.hex --&gt;KeyFob
 * CC2540_USBdongle_HostTestRelease_All.hex --&gt;USB Dongle

Source Project
The source project file for IAR 7.51A is located in typically this is
 * \Projects\ble\KeyFob\CC2540DB
 * C:\Texas Instruments\BLE-CC2540\Projects\ble\KeyFob\CC2540DB

Use BTool to make a Connection
BTool is a PC Application that allows a user to form a connection between two BLE devices. BTool works by communicating with the CC2540 by means of HCI vendor specific commands. The USB Dongle software (when running the HostTestRelease project) and driver create a virtual serial port over the USB interface. BTool, running on the PC, communicates with the USB Dongle through this virtual serial port.

More info on setting up BTool and making a connection are found here.

Using the Profiles
The KeyFobDemo software contains four service profiles that can be used: Proximity, Battery, Accelerometer, and Simple Keys. This section details how BTool can be used to make use of these profiles.

Battery
The battery profile allows for the USB Dongle to read the percentage of battery remaining on the keyfob. To find out the percentage of battery power remaining on the keyfob, select the option “Read Using Characteristic UUID” under the “Sub-Procedure” option in the “Characteristic Read” section at the top of the screen.



Every characteristic value in Bluetooth Low Energy has a “UUID” assigned to it, which defines the type of data that the characteristic represents. In the keyfob sample application, the UUID for the battery percentage is 0xFFB1 (hex value; this value is for example only and does not comply with any actual values defined by the Bluetooth SIG). To read the battery percentage, enter “B1:FF” in the “Characteristic UUID” box, and click the “Read” button. A read request gets sent over the air from the dongle to the keyfob, and a read response gets sent back from the keyfob to the dongle with the return data value. The value is displayed in the “Value” box. It is recommended to set the format to “Decimal”, since the value represents a percentage between 0 and 100. NOTE: On BLEStack versions 1.2.1 and above, this UUID has been updated. It is now 0x2A19 to match the official Bluetooth SIG Battery Profile. So, to read the battery percentage, enter “19:2A” in the “Characteristic UUID” box, and click the “Read” button.

Accelerometers
The keyfob contains a 3-axis accelerometer. The accelerometer profile provides a means for the keyfob to send the accelerometer data over the air to the USB Dongle. Just like the battery profile, the accelerometer profile contains characteristic values that relate to its operation and use. One characteristic of the accelerometer profile is the accelerometer enable. This value must be changed from 0 to 1 in order to turn the accelerometer on the keyfob on. The UUID of the accelerometer enabler is 0xFFA1. Before the value of the characteristic can be changed, the “handle” of the characteristic value must first be discovered. Every attribute, including characteristic values, have a “handle”, which essentially is the address of the attribute in the server. To discover the handle of the accelerometer enabler, select the option “Discover Characteristic by UUID”. Enter “A1:FF” in the “Characteristic UUID” box, and click the “Read” button. A discovery request gets sent over the air from the dongle to the keyfob, and a response gets sent back from the keyfob to the dongle with the return data value. A 5-byte value “0A 21 00 A1 FF” should get displayed in the “Value” box (it is recommended to set the format to “Hex”).



This 5-byte value is called the “characteristic declaration”. The exact details of the meaning of the 5-bytes in a characteristic declaration can be found in the Bluetooth Core Specification v4.0 (Volume 3, Part G, Section 3.3.1). The second and third bytes (“00 21”) represent the handle of the characteristic value (0x0021). To turn the accelerometer, enter “0x0021” into the “Attribute Handle” box in the “Attribute Write” section, and enter “01” in the “Value” section. The format can be set to either “Decimal” or “Hex”. Click the “Write Value” button to send the write request over the air. When the keyfob receives the request, it will turn on the accelerometer, and send a write response to indicate success.



With the accelerometer on, the next step is to set up notifications of the accelerometer data. To receive notifications every time the keyfob is rotated along the x-axis, you will need to enable notifications of the x-axis data characteristic. The UUID of the x-axis accelerometer data is 0xFFA3. Using the same discovery process as before with the “Discover Characteristic by UUID” command, it can be determined that the handle of the x-axis data is 0x0027. The x-axis data is a “configurable” characteristic, in that the client device can configure the server to send notifications of the characteristic value. The handle immediately following the characteristic value is the “characteristic configuration”. The characteristic configuration of the x-axis data is the attribute at handle 0x0028. To turn on notifications, enter 0x0028 into the “Attribute Handle” box in the “Attribute Write” section, and enter “01 00” in the “Value” section. The format must be set to “Hex”. Click the “Write Value” button to send the write request over the air. When the keyfob receives the request, it will turn on notifications of the x-axis accelerometer data, and send a write response to indicate success. With notification enabled, you should now see notifications sent over the air to the USB Dongle as you physically tilt the keyfob. The notifications should show up in the message window and will look like this:



Y-axis and z-axis notifications can be set up accordingly. The UUID of the y-axis characteristic value data is 0xFFA4. . The UUID of the z-axis characteristic value data is 0xFFA5. Note that when using the accelerometer, if the keyfob is moved around very quickly a large number of notifications will be sent over the air to the dongle. This is especially true when notifications of more than one axis of the accelerometer are enabled simultaneously. It will appear that the messages are “lagging” from the time that the keyfob is moved until the time that the messages are displayed in the message window. It is important to understand that this delay is not due to over-the-air latency of the messages, but is actually a buffering delay due to the slow UART baud rate of 57600.

Keys
The simple keys service on the keyfob allows the device to send notifications of key presses and releases to a central device. The UUID of the simple keys data characteristic value is 0xFFE1. Using the same discovery process as before with the “Discover Characteristic by UUID” command, it can be determined that the handle of the simple keys data is 0x0034. Like the accelerometer axes data, the simple keys data is a “configurable” characteristic, in that the client device can configure the server to send notifications of the characteristic value. The handle immediately following the characteristic value is the “characteristic configuration”. The characteristic configuration of the simple keys data is the attribute at handle 0x0035. To turn on notifications, enter 0x0035 into the “Attribute Handle” box in the “Attribute Write” section, and enter “01 00” in the “Value” section. The format must be set to “Hex”. Click the “Write Value” button to send the write request over the air. When the keyfob receives the request, it will turn on notifications of the simple keys data, and send a write response to indicate success. With notification enabled, you should now be see notifications sent over the air to the USB Dongle as you press or release either of the buttons on the keyfob. The notifications should show up in the message window. A value of “00” indicates that neither key is pressed. A value of “01” indicates that the left key is pressed. A value of “02” indicates that the right key is pressed. A value of “03” indicates that both keys are pressed.

Proximity
The fourth profile on the keyfob is the proximity profile, which is based on the Bluetooth SIG draft document Proximity Use Case, Requirements, and Design Document D05r06. The functionality implemented on the keyfob is the role of the “Proximity Reporter” as defined by the document. A mobile phone or PC would typically implement the role of “Proximity Monitor”; however this full functionality has not yet been implemented in the USB Dongle software or BTool. One of the services of the proximity profile is the link loss service, which allows the proximity reporter to begin an alert in the event the connection drops. The handle of the characteristic value of the link loss alert is 0x0011. The default alert value setting is “00”, which indicates “no alert.” To turn on the alert, write a 1-byte value of “01” (low alert) or “02” (high alert). By default, the link does not timeout until 20 seconds have gone by without receiving a packet. This “Supervision Timeout” value can be changed in the “Connection Services” tab; however the timeout value must be set before the connection is established. After completing the write, move the keyfob device far enough away from the USB Dongle until the link drops. Alternatively, you can disconnect the USB Dongle from the PC, effectively dropping the connection. Once the timeout on the keyfob expires, the alarm will be triggered. If a low alert was set, the keyfob will make a low pitched beep. If a high alert was set, the keyfob will make a high pitched beep and the LED will blink. In either case, the keyfob will beep ten times and then stop. Alternatively to stop the beeping, either a new connection can be formed with the keyfob, or the button can be pressed.

Proximity
The functionality of the proximity profile is based on the Bluetooth SIG draft document Proximity Use Case, Requirements, and Design Document D05r06. Note that even though the profile functionality is based on a Bluetooth SIG document, the UUID values that are used by the profile are custom, and do not conform to any values defined by the Bluetooth SIG. This is because the SIG has not yet assigned any UUID values for the proximity profile. The functionality implemented on the keyfob is the role of the “Proximity Reporter” as defined by the document. A mobile phone or PC would typically implement the role of “Proximity Monitor”; however this full functionality has not yet been implemented in the USB Dongle software or BTool.

The profile maintains three GATT services. The full profile contains the following nine attributes:



The primary API function prototypes for the proximity profile can be found in the file proxreporter.h. The API provides functions to get and set certain proximity profile parameters: ProxReporter_GetParameter and ProxReporter_SetParameter, respectively. Here are the proximity parameters: As the “Proximity Reporter”, the keyfob application must implement certain behaviour as defined by the draft of the use case document. First, it must make its power level value available to the proximity monitor. The KeyFobDemo application initializes the PP_TX_POWER_LEVEL attribute to 0, since the keyfob default transmit power is 0dBm. The idea behind the proximity profile is that by knowing the proximity reporter’s transmit power, the proximity monitor can calculate the path loss (in dBm) by measuring the RSSI of the signal that it receives. When the path loss exceeds a certain threshold (the exact threshold is at the discretion of the monitor device), the monitor writes to the path loss alert level characteristic value on the reporter, triggering a low or high alarm. When the path loss drops below the threshold, the monitor writes to the reporter to stop the alert. The monitor behavior (continuously measure the RSSI, calculate the path loss, and automatically send write request for path loss alert as needed) is not yet implemented in the USB Dongle or in BTool; however the KeyFobDemo application has all of the reporter functionality implemented. It is possible to manually trigger a path loss alarm using BTool by writing to the path loss alert characteristic value. An additional feature of the proximity profile is the link loss alert. The proximity profile allows the proximity monitor to set a link loss alert on the proximity reporter. In doing so, the proximity reporter begins an alert if the BLE connection drops due to a supervision timeout. The profile dictates that the monitor automatically attempt to re-connect with the reporter, and that the reporter stop the link loss alert once the connection is back up. Again, the KeyFobDemo application has the proper reporter behavior implemented, while the USB Dongle / BTool does not have the monitor behavior (automatic reconnect upon supervision timeout). Once again, the behavior can be emulated manually, by using BTool to re-establish the connection. The proximity profile uses a callback function to notify the application one of the GATT writeable characteristic values has been changed by a GATT write from another device. The callback function is set up by means of the function ProxReporter_RegisterAppCBs. This function should only be called once. Its single parameter is a pointer to a variable of type proxReporterCBs_t, which is a structure containing one function pointer: It is up to the application to create the actual callback function. In the case of the KeyFobDemo application, the function is called proximityAttrCB (named the same as the pointer in the type definition). The proximity profile setup occurs during the KeyFobDemo application’s second phase of initialization
 * PP_LINK_LOSS_ALERT_LEVEL – This parameter corresponds to the link loss alert characteristic value.
 * PP_IM_ALERT_LEVEL – This parameter corresponds to the path loss alert characteristic value.
 * PP_TX_POWER_LEVEL – This parameter corresponds to the transmit power characteristic value.
 * proximityAttrCB – this function gets called every time that the value of the link loss alert level or immediate alert level has been changed.

Battery Profile
The battery profile that is included in the Beta release is a custom designed profile, and does not conform to any existing specification. The battery profile contains the following seven attributes:

The primary API function prototypes for the battery profile can be found in the file battery.h. The API provides functions to get and set certain battery profile parameters: Battery_GetParameter and Battery_SetParameter, respectively. Here are the battery parameters: It is up to the application to actually set and update this data; the profile simply acts as a means for maintaining the data within the GATT server. In the case of the KeyFobDemo application, the function checkBattery handles this
 * BATTERY_ATTR_LEVEL – This parameter corresponds to the battery level characteristic value.
 * BATTERY_ATTR_STATE – This parameter corresponds to the battery state characteristic value.

Accelerometer Profile
The accelerometer profile that is included in the Beta release is a custom designed profile, and does not conform to any existing specification. The accelerometer profile contains the following 19 attributes:



The primary API function prototypes for the accelerometer profile can be found in the file accelerometer.h. The API provides functions to get and set certain accelerometer profile parameters: Accel_GetParameter and Accel_SetParameter, respectively. Here are the accelerometer parameters: Just as with the battery profile, it is up to the application to actually set and update this data; the profile simply acts as a means for maintaining the data within the GATT server. The application, however, must be notified when the accelerometer has been enabled. This handled by means of the accelEnablerChangeCB function, which the application registers with the profile by calling the function Accel_RegisterAppCBs during the second phase of initialization. In the KeyFobDemo application, once the accelerometer has been enabled, an OSAL timer is used to read the accelerometer data for all three axes. The data is then written to the attribute table using the Accel_SetParameter function. If notifications have been enabled for one of the coordinate data characteristic attributes (which would be set by writing a value of 0x0001 to their corresponding characteristic configurations), then the profile will “push” the data out to the GATT client device every time that the coordinate data gets set.
 * ACCEL_ENABLER – This parameter corresponds to the accelerometer enabler characteristic value.
 * ACCEL_X_ATTR – This parameter corresponds to the accelerometer x-axis data characteristic value.
 * ACCEL_Y_ATTR – This parameter corresponds to the accelerometer y-axis data characteristic value.
 * ACCEL_Z_ATTR – This parameter corresponds to the accelerometer z-axis data characteristic value.
 * ACCEL_RANGE – This parameter corresponds to the accelerometer range characteristic value.

Simple Keys
The accelerometer profile that is included in the Beta release is a custom designed profile, and does not conform to any existing specification. The accelerometer profile contains the following five attributes:



The primary API function prototypes for the accelerometer profile can be found in the file simplekeys.h. The API provides functions to get and set certain simple keys profile parameters: SK_GetParameter and SK_SetParameter, respectively. Here are the simple keys parameters: Just as with the other profiles, it is up to the application to actually set and update the attribute data; the profile simply acts as a means for maintaining the data within the GATT server. In the KeyFobDemo application, every time one of the keys is pressed or released, the HAL sends an OSAL message to the application. This causes a SYS_EVENT_MSG event to occur, which is handled in the application by the function keyfobapp_ProcessOSALMsg. In the current KeyFobDemo application, the only OSAL message that is recognized (additional types can be defined) is the KEY_CHANGE message. This causes the function keyfobapp_HandleKeys is then called, which checks the state of the keys and sets the appropriate profile parameter value to the attribute table using the SK_SetParameter function. Note that keyfobapp_HandleKeys has additional functionality when the device is not in a connected state (see section 10.6). If notifications have been enabled for keys state characteristic attribute (which would be set by writing a value of 0x0001 to its characteristic configuration), then the profile will “push” the data out to the GATT client device every time that the keys state data gets set.
 * SK_KEY_ATTR – This parameter corresponds to the simple keys state characteristic value.

KeyFobDemo Application Software
The keyFobDemo is an application that reads the battery level, sets the alarm and the trigger values, and activates the LED and buzzer when necessary.

Initialization
The initialization of the application occurs in two phases: first, the KeyFobApp_Init function is called by the OSAL. This function sets up the GAP role, GAP bond manager, and battery profile parameters. It also initializes each of the GATT profiles, the buzzer, LED’s, and ADC, and sets an OSAL timer to delay the second phase of the initialization by 500ms. After the 500ms delay, a KEYFOB_START_DEVICE_EVT OSAL event occurs. This triggers the second phase of the initialization, which can be found within the KeyFobApp_ProcessEvent function. During this phase, the GAPRole_StartDevice function is called, which sets up the GAP functions of the application. Note, the keyfob will not start advertising as a peripheral device until the key in pressed to toggle advertising state. Once the key is pressed, the keyfob begins advertising and waits up to 30 seconds for a central device to establish a link with it. In addition, the peripheral role, proximity, and accelerometer application callback functions are registered with their profiles. An OSAL timer is also set in order to check the battery voltage in five seconds.

GAP Role Callbacks
The peripheralStateNotificationCB functions is a callback from the GAP Role. This function updates the application variable gapProfileState. It also sets the keyfobProximityState value appropriately as the GAP state changes between being connected and unconnected. If the device goes from an unconnected state to a connected state, the keyfobProximityState value is set to either KEYFOB_PROXSTATE_CONNECTED_IN_RANGE or KEYFOB_PROXSTATE_PATH_LOSS, depending on whether the proximity profile path loss alert level has been set. If the device goes from a connected to an unconnected state due to a supervision timeout, the keyfobProximityState value is set to KEYFOB_PROXSTATE_LINK_LOSS. This function also will trigger a link loss or path loss alert if the corresponding alert is enabled.

Proximity Callback
The proximityAttrCB function is a callback function from the proximity profile. It is called to indicate that one of the proximity profile GATT characteristic values has changed as a result of a GATT write from another device (the USB Dongle in the case of the demo application). The function updates the values of the application local variables keyfobProxLLAlertLevel and keyfobProxIMAlertLevel by calling ProxReporter_GetParameter. Based on the value of keyfobProximityState, an alert may be triggered.

Battery Check
The checkBattery function is called every time the OSAL event BATTERY_CHECK_EVT occurs. The event is initially set to occur five seconds after the second phase of initialization, and then continues to get set once every five seconds thereafter. Every time it is called, it measures the current state of the coin cell battery, and updates the battery profile attributes. This function uses the CC2540’s integrated ADC. It sets the ADC reference voltage to 1.25V and sets the ADC input to one-third of VDD. The 10-bit conversion is performed with a call to the API function HalAdcRead. From the results of the calculation, the battery percentage level is calculated. For the keyfob, a 3V CR2032 coin cell battery is being used. Therefore, a VDD value of three volts is considered 100% battery level. The CC2540 specification requires a minimum VDD of 2.0V for operation. Therefore, a VDD value of 2.0V is considered to be 0%. Note: A detailed explanation of the calculations used to get a percentage value from the ADC reading can be found in comments in the source code within the checkBattery function definition. After the calculation is completed, the calculated battery percentage value is compared to the current value of batteryLevel. If the measure and calculated value is higher than the current value of batteryLevel (indicating that the voltage has actually gone up), then we do not update the attribute. This is because in a discharging battery, the voltage can actually fluctuate up and down. For this application, we want the user to know the “worst-case” state of the battery, so we only update the attribute if the level has dropped. The batteryState is also updated. If the batteryLevel value has dropped below 20 (this number is defined by the constant BATTERY_LEVEL_CRITICAL_PCT), then the batteryState value is set to BATTERY_STATE_CRITICAL_REPLACE_NOW. At the end of the function, the Battery_SetParameter function is called to update the profile.

Key Handling
Each time one of the keys on the keyfob gets pressed or released, the HAL sends an OSAL message to the application. This causes a SYS_EVENT_MSG event to occur, which is handled in the application by the function keyfobapp_ProcessOSALMsg. In the current KeyFobDemo application, the only OSAL message that is recognized (additional types can be defined) is the KEY_CHANGE message. This causes the function keyfobapp_HandleKeys to be called, which checks the state of the keys. In addition to notifications, the keys on the keyfob have two other functions: advertisement toggling and silencing the buzzer. When the device is in an advertising state (before a connection), pressing of the right key will toggle the advertising on and off. This is done via a call to GAPRole_GetParameter to read the current advertising state, and a call to GAPRole_SetParameter to set a new state. If the device is in a connection, the appropriate profile parameter value in the attribute table is set using the SK_SetParameter function. While the buzzer is beeping as a result of a path loss alert or a link loss alert, pressing of the left key will stop the alert. Note that this will not reset the alert parameter in the profile; it simply silences the buzzer and turns of the LED, even if the maximum number of beeps have not yet occurred.

Accelerometer
The accelEnablerChangeCB function is a callback function from the accelerometer profile. It is called to indicate that the accelerometer enabler attribute from the accelerometer profile has changed as a result of a GATT write from the other device (the USB Dongle in the case of the demo application). The function sets up an OSAL timer for the ACCEL_READ_EVT, which causes a call to the accelRead function every 50ms. accelRead simply reads the value of the accelerometer for all three axes. For each axis, it checks the previously stored profile value, and checks whether the value has changed beyond a threshold value. If it has, the function sets the new value for the parameter within the profile accordingly. Note that if notifications are enabled for the attributes, then the profile will send out a notification each time that the value gets set. The default threshold for changes is five; however the value can be redefining the preprocessor constant ACCEL_CHANGE_THRESHOLD.

Alerts
The keyfobapp_PerformAlert function gets called anytime that an alert is triggered (either due to path loss or link loss). First it checks the keyfobProximityState value to know which alert to trigger. It then checks the alert level for the appropriate alert. If the alert is “low”, the buzzer is started with a low pitched beep. If the alert is “high”, the buzzer is started with a high pitched beep, and the LED is set to blink. If sleep mode is enabled, the device must turn off power savings mode before sounding the buzzer, as the buzzer relies on a PWM signal from the CC2540 to make its sound. When the buzzer is turned on, an OSAL timer gets set to toggle the buzzer off in 200ms. After 200ms, the TOGGLE_BUZZER_EVT OSAL event occurs. This event turns the buzzer, off and sets another OSAL timer for a TOGGLE_BUZZER_EVT in 800ms to start the buzzer again. This cycle causes the buzzer to beep on and off repeatedly. The buzzer_beep_count variable keeps a running count of the number of beeps that have occurred since the alert was triggered. When this count reaches the value of BUZZER_MAX_BEEPS, the beeping stops. The default value of BUZZER_MAX_BEEPS is 10. The keyfobapp_StopAlert function simply stops the buzzer and turns the LED off. It may be called if the GAP state changes causing alerts to be stopped, or if the left key is pressed while an alert is active.