WICED 20719 BLE Central Custom Profile w/LED & CapSense – Part 1

Summary

Last year I posted an article about making a BLE Central using PSoC 4 BLE.  Recently, I got a comment from a reader who was interested in the source code to the PSoC 4 BLE project which made me think of BLE Centrals again, especially because in the last several months I have spent a significant amount of time writing a book about WICED BLE.  Given all that, it only made sense to create a WICED BLE Central that mimics the PSoC Central from the original article.

In the original article I made a connection to a PSoC4 BLE that was acting as a Peripheral with a Vendor Specific Service which I called “ledcapsense”.  Then Central could then turn on/off an LED, and get notifications when the CapSense changed.  In this series of articles I will make a connection to that same PSoC 4 BLE device, except that I will use a WICED CYW920719Q40EVB_01.

CYW920719Q40EVB_01 20719

I will breakup this article into three parts

  1. Find the Peripheral, make a connection, write the GATT database to set the LED to 0 & 1
  2. Add the ability set the the CCCD for the CapSense Characteristic
  3. Perform Service Discovery

This first article will be broken up into the following steps

  1. Make a New Project Using Bluetooth Designer
  2. Remove all of the unused Advertising Code
  3. Add a PUART Command Line Handler
  4. Make the Central Scan for Peripheral Devices
  5. Make the Connection & Disconnect
  6. Write the LED Characteristic

Make a New Project Using Bluetooth Designer

It is easiest to let the Bluetooth Designer create a template project for me.  To do this, pick WICED Bluetooth Designer from the File->New menu.

PSoC Creator BLE Customizer

Give a project name of ex01ScanConnect and choose the 20719-B1

WICED Studio

Turn off the GATT database and then press Generate Code

WICED Studio Bluetooth Designer

This will make a project in the top level Apps folder, but I want i to be in the WICED_Central directory, so cut and paste it.

WICED Studio Bluetooth Designer

Now it looks like this:

WICED Studio Bluetooth Designer

I want to make sure the project will build, so Ill set the debug traces to go to the the PUART

Then I create a make target for the project

WICED Studio Make Target

Next, lets make sure that it works.

WICED Studio

Everything seems OK… although it is advertising, which I don’t want to do.  But that is easy enough to fix.

WICED 20719 Test

Remove all of the Advertising code

Lets get rid of all of the advertising code.  First Ill remove the function prototypes for “…_set_advertisement_data” and “…_advertisement_stopped”

Then Ill delete everything from “…set_pairable_mode” on line 128 down through the two functions ending on line 169

In the Bluetooth Management Callback function you dont need the local variable p_adv_mode (line 145) so delete it.

And, because you are not advertising, you don’t need to handle that callback so delete this block of code.

Now run the make target again to make sure you didn’t break anything.

After programming, things still seem to work.

WICED 20719 Test

Add PUART Command Line Handler

In this project I am going to make keyboard commands to do the different things.  In order to make all of that work, Ill include the HAL for the PUART.

Then Ill add a function prototype for the callback for the receive data handler (line 59)

In the application init function Ill initialize the PUART and setup a callback for keys from the serial port.

And create a new function called “rx_cback” which will be called when a key is pressed.  In this case the only key to process is ‘?’ which will print out the help.

Program it again and make sure that the ‘?’ works

WICED 20719 Test

Make the Central Scan for Peripheral Devices

You might recall that the PSoC 4 CapSense BLE Peripheral is advertising a “Service UUID” that is my custom service.  Here is a picture of the advertising packet customizer from PSoC Creator.

PSoC Creator Component Customizer

If you look in the PSoC Creator project in the Generated Source file ble_gatt.c you will find C-Declarations of the UUIDs for the ledcapsense service, the led characteristic and the capsense characteristic.

I copy that byte array for ledcapsense into my project so that I can match against it.

The way that the WICED scanner works is that it will give you a callback every time it hears a Peripheral advertisement packet.  It passes you the pointer to some information about what device it heard (p_scan_result), as well as the raw bytes of the advertising packet (p_adv_data).  WICED has a function called “wiced_bt_ble_check_advertising_data” which will search through the raw advertising data looking for a field of the type you specify.  If found, the function will return a pointer to the raw data.  In this case I’m looking for a field of type “BTM_BLE_ADVERT_TYPE_128SRV_COMPLETE”, in other words, a device that is advertising that it has a 128-uuid service as available on that device.

All this function does is, if I find that field in the advertising packet and the service UUID matches the capsenseled UUID, then I print out that I found it.

At the bottom of the project, Ill add ‘s’ to start scanning and ‘S’ to stop scanning.

And don’t forget to update the help.

When I run the make target everything appears to be working.  First I press ‘?’ and the help is correct.  Then I press ‘s’ to start scanning.  It immediately (and repeatedly) finds my device.

WICED 20719 Test

What is the unhandled Bluetooth Management Event: 0x16 (22)?  You can find the answer to that question by right clicking on the wiced_bt_management_event_t and “Open Declaration”

WICED Studio

That will take you to the “wiced_bt_dev.h” file in this enumeration.  On line 683 you will see the “BTM_BLE_SCAN_STATE_CHANGED_EVT” which you are getting a callback every time the scan state changes.

You notice that the event parameter is of type “wiced_bt_ble_scan_type_t”.  When I right click, I find its definition is this:

Now I can add a case to the Bluetooth Management callback to handle the case “BTM_BLE_SCAN_STATE_CHANGED_EVT”.  All it does it look at the parameter and print it out.

OK now when I run the program and start scanning I get this.  Which makes good sense.

WICED 20719 Test

But if I run the scanning for a while, I get this.  Why does it do this transition to “BTM_BLE_SCAN_TYPE_LOW_DUTY”?

WICED 20719 Test

The answer to that question can be found on line 53 of “wiced_bt_cfg.c”.  That “5” means scan at high duty cycle for 5 seconds, then go to low duty cycle scanning for 5 more seconds then stops scanning.  This is done to save power as scanning is very current consuming.  If you want to keep scanning forever, change those values to 0 (which means stay in that mode forever)

Make the Connection

Now that I have found a device, how do I make a connection?  Simple, call wiced_bt_gatt_connect.  The other thing that you want to do is turn off the scanning by calling wiced_bt_ble_scan with “BTM_BLE_SCAN_TYPE_NONE”.

All of the functions that let you exchange data require a connection id.  The 20719 lets you handle multiple BLE (and Bluetooth Classic) connections and each connection will have a different connection id.  At the top of your project the easiest thing to do is create a global variable to keep track of the connection id.  Initialize it  to 0 meaning no connection.

You might have noticed that the connection api was “…gatt_le_connect”.   This means that while you are connected, almost all of the interaction will happen with a gatt callback which looks like this.  Add it to the function declarations at the top of your project.

And in the application_init register your callback.

Now we need to actually create the callback function.  This function will just be a switch to look at what type of gatt event just happened.  We will start with the only case being the connection event.  If this event is a connection, save the connection id and print out the bd address of the peripheral.  If this is a disconnect, then set the connection id back to 0.

The last thing you need to do to get the connection to work is modify wiced_bt_cfg.c and increase the .client_max_links to at least 1.

We setup all of the code to make a connection.  How about the disconnect?  That is also easy.  Il add a new case the user interface ‘d’ to call wiced_bt_gatt_disconnect.

Now when I program and test you can see that I can make a connection (which barfs out a bunch of messages about pairing not working) and then I can disconnect.

WICED 20719 Test

Write the LED Characteristic

Finally we are ready to write the LED.  You might recall from the original peripheral project that it has a Service with two characteristics, one for an LED and one for a CapSense value.  Here is the customizer screen.

PSoC Creator BLE Customizer

You might recall that all BLE transactions take place in reference to a handle (just a 16 bit number in the Attribute Database).  But what is the handle of the LED characteristic? You can see from the PSoC Creator project in file ble_custom.c that the handle of the LED characteristic is 0x0E.  Note: this is a seriously bad way to find out the handle for a characteristic.  The correct way is to use service discovery which Ill show you in the third article.

In order to write the characteristic I will create a new function that will let me write a 0 or 1.  This function simply

  • Checks to make sure that there is a connection
  • Allocates a block of memory to hold the structure required to send the write
  • Sets up the structure with the handle, offset, length and value
  • Send the write
  • Frees the buffer

I want to use the buffer allocation functions, so at the top of my program Ill include the wiced_memory.h header file.

To make the writes work I just call the “writeLed” function in the keyboard handler.

Now when I test, everything is working.

WICED 20719 Test

And here are the two development kits talking nice to each other (at least it works from 2 inches away 🙂 )

WICED 20719 and PSoC 4 BLE

You can find all of the source code for these projects at github.com/iotexpert/PSoc4BLE-Central