iBeacons on the TI CC2541
There are a few things you can do with an iBeacon:
- Turn it on/off
- Vary the output power, if your hardware supports it
- Vary how often it advertises
- Vary the advertisement
That’s about it. Now we just need to figure out how to implement it.
Some general hints when working with the BLE Examples
Here’s a few pointers to save you time when trying to find your way through the stack. This is not meant to scare you off, but to help guide you as you go through the code.
- There are lots of global variables that are typed static and limited to the file they are declared in. Often it is easier to remove the static typing so that you can declare them as external variables in the other files and access them than trying to figure out how to pass the information through the application structure.
- The same goes with
#define. Some are not in header files and you will have to copy them from elsewhere.
- Lots goes on by passing pointers to variables. You will spend time tracking down the variable that a pointer points to.
- You will spend time learning the application structure. It’s basically its own RTOS. There is a lot of documentation about how it works, but there is a steep learning curve. It would be really nice if TI had the libraries setup so that you initialized them and then went about things as you normally would and just called a function to send an advertisement (anyone from TI listening?). It does not work that way.
- The ways I got things working for the first proof-of-concept are ugly and I am pretty sure not how it is intended to work, but that’s how I did it. I didn’t get a week long training course on the BLE stack and associated RTOS.
Trigger on Keypress
With the demo kit the easiest way to test changing the different things is using the buttons on the dev board. We can insert logic to do our bidding where the keypresses are handled in the code. By default the project does not have the compiler define
CC2540_MINIDK defined. Without this set the logic for switch 1 and 2 will not be compiled in. We need to set this under Project -> Options -> C/C++ Compiler and then in the Preprocessor tab add
CC2540_MINIDK to the Defined Symbols. Note, doing this will cause the devboard to not transmit until one of the switches is pressed. From there you can hook into
and put in our logic.
Changing the Advertisement
The tutorial linked to earlier explains how to setup your advertisement so that it is recognized as an iBeacon. In the iBeacon we have two unsigned shorts (16-bit) to play with the Major and Minor. Changing the UUID in the Advertisement will cause your data to get sent to another program, or to nothing on an iDevice, depending on how your app is configured. The Major value is located at index 22 & 23 of
advertData. The Minor value is located at index 24 & 25 of
advertData. Both are big endian (high byte first).
Changing the memory there is not enough. The BLE stack needs to have the data copied into it. To do that we need to call
. Here’s the catch, we will be calling it from outside the file advertData is defined in, so
sizeof(advertData) will throw an error. We can change it to
and that will work. We need to remove the static keyword from the declaration of advertData so that it is accessible from other files and declare
extern uint8 advertData; in the file we are updating the advertising data from as well.
GAPRole_SetParameter() also needs slight modification. Inside the function in the
GAPROLE_ADVERT_DATA case we need to add
so that it is loaded for the next advertisement. Much of this came from discussions on e2e.ti.com.
Adding this all together, this is how it looked in the iBeacon Locate app:
Next we are going to look at how to set a timeout timer to turn off the iBeacon.