Skip to main content
Ctrl+K

SimpleLink™ data_stream examples#

Texas Instruments

24 min read

Introduction#

This workshop offers a first experience in the data_stream example project. The purpose is to have a better understanding of the device’s functionalities. Here it will dive into echoing a value entered by the user and plenty of features around this principle. This project is the perfect entrance for UART over Bluetooth® LE. It can also easily handle data transfer and can be used for data streaming.

Prerequisites#

Hardware#

  • SimpleLink CC2340R5 LaunchPad Target

  • SimpleLink™ LaunchPad™ XDS110 Debugger

  • USB cable

  • SmartPhone or Tablet with a GATT Table viewer application installed (such as TI SimpleLink Connect app)

Note

Have a look at the following lab to have more information on the TI SimpleLink Connect App.

Software#

  • SIMPLELINK-LOWPOWER-F3-SDK Software Development Kit (SDK)

  • Code Composer Studio CCS / CCS Cloud or IAR

    • See Dependencies section of SDK release notes for required version.

Readings#

  • BLE5 Stack User’s Guide

    You should particularly have a look at the Generic Access Profile (GAP) and Generic Attribute Profile (GATT) sections, it will help you to understand a bit more about the theory behind Bluetooth™ Low Energy protocol.

Agenda#

In this training, we will discuss how to prepare the data_stream example for custom development.

1. Discuss how to set up the environment and how it works

2. A brief explanation of the GATT concepts

3. Working principle of the project

4. How to change basic device configurations

5. Some help to customize your project

Preparation#

Initial Setup#

If your system is already setup skip this part and go directly to the first connection using GATT table.

Initial Setup (Click here to expand)

All the collaterals required are available on TI website.

  1. Download and Install the SDK found in the software section above.

  2. Follow the Quick Start Guide found inside the BLE5 Stack User’s Guide

PATH =

  C:/ti/simplelink_lowpower_f3_sdk_x_xx_xx_xx/docs/ble5stack/ble_user_guide/html/quickstart-guide/quickstart-intro-cc23xx.html

Setting up the Serial terminal

If you already have a functional serial terminal setup skip this part and go directly to the first connection using GATT table.

  1. Identify the COM port used by the SimpleLink CC2340R5 LaunchPad.

  • Disconnect all the LaunchPads™ you may have connected to your computer leaving only the SimpleLink CC2340R5 LaunchPad.

  • Open the Device Manager. You can do so by typing Device Manager in the Windows start menu.

  • In the Device manager, find the menu Ports (COM & LPT) and unroll it.

  • Observe the line called XDS110 Class Application/User UART. Note down the COM port this interface is using. In my case (see below), the COM port used is called COM27.

../../_images/identify_the_com_port_used.png

Identify the COM port used#

  1. Open your preferred serial terminal to observe the COM port identified previously. For this example, PuTTY will be used, but you can use your favorite serial terminal provider.

  • In PuTTY, click on Serial for connection type.

  • Then select the following settings:

    • Serial Line: The serial port identified before (COM27 for me)

    • Speed: 115200

../../_images/putty_example.png

Set up the serial terminal#

  • Once done, click Open.

  • To finish, reset the SimpleLink CC2340R5 LaunchPad by pressing the reset button on the emulator.

../../_images/lp_reset.png

Reset#

Note

At this point open Code Composer Studio, and import the data_stream project. Then build and flash the code on the device.

If you need help for this, make sure to review Quick Start Guide!

Hint

Once the LaunchPad is ready, the green LED (labeled Green DIO15) turns on.

To test the Bluetooth LE communication, a connection should be formed between a central device and the CC2340RX running the data_stream example. An easy way to do this is by using a Smartphone or Tablet device with a GATT Table viewer application. With one of these applications, one should be able to scan and connect to the device as well as interact with the characteristics present in the project.

More details on the way of testing the Bluetooth communication between the CC2340 and a smartphone are provided in the following sections.

Introduction of the GATT concepts#

This section will provide a quick introduction of the GATT the concepts you should know to handle properly this example. Feel free to skip this section if you are already familiar with these concepts.

Attributes and Characteristics#

An Attribute is the smallest addressable unit of data used by ATT and GATT. It is addressed via a 16-bit handle, it has a type, which is an UUID that can be 16, 32 or 128 bits long, and it has a data field which can be up to 512 bytes long. Note that all 32-bit UUIDs should be converted to 128-bit before sending over the ATT protocol.

Summarized, the Attribute Protocol defines an attribute to consist of

  • Handle – The ‘address’ of the Attribute when accessed via the Attribute Protocol

  • UUID – The ‘type’ of the Attribute

  • Value – Array of bytes interpreted differently depending on the UUID (type).

Handle

UUID

Value

16 bits

16 or 128 bits

1 to 512 bytes.

Several of these attributes are needed to define a Characteristic. A Characteristic always consists of at least a Value attribute and a Declaration attribute. The meaning of the Value attribute is defined in the Profile. The Declaration always comes before the value attribute and describes whether the value attribute can be read or written, contains the UUID of the Characteristic and the handle of the Characteristic Value’s attribute.

Other attributes of a characteristic can give a description of the characteristic in string format, or describe how the Value should be interpreted, or configure whether the GATT Server may send Notifications about value changes. These are called Descriptors.

Handle#

In the TI BLE5-Stack, unique handles are assigned starting from 1 when the attribute is registered with the GATT Server. This usually happens during initialization. If the firmware doesn’t change, the handle is always the same.

UUID#

The Universal Unique Identifier (UUID) tells a peer device how the value of the Attribute should be interpreted. For example, 0x2803 is defined in the specification to mean Characteristic Declaration. Multiple attributes may share the same UUID so handles are needed to identify a particular attribute instance.

Warning

Proprietary (non-SIG-adopted) services must use 128-bit UUIDs to avoid collision, unless a 16- or 32-bit UUID is acquired from the SIG.

First connection using GATT table#

Data_stream Operational Principles#

The following steps will showcase how to connect, write and receive a value by using the TI SimpleLink Connect application on an Android device. Note that these steps are almost the same for iOS smartphone.

  1. Scan and locate the Data Stream device

../../_images/ScanningDataStreamSmartPhone.png

Smartphone Scanning View#

Note

Add a filter on the proximity of the device by pressing the settings menu (three dots on the top right hand corner) or swiping to the right. Then activate the RSSI filter and update its value.

This feature will help you to filter out any faraway devices and make it easier to find the data_stream device in a crowded BLE environment.

../../_images/ScanDeviceFilter.png

Settings Menu#

../../_images/FilterRSSI.png

Smartphone Filter View#

  1. Connect to the Data Stream device by tapping on the arrow and expand the TI Terminal tab which has the UUID 0xF000C0C0-0451-4000-B000-000000000000.

Note

A common practice is to choose a base UUID for the custom service and then increment the 3rd and 4th Most Significant Bytes (MSB) within the UUID of each included characteristic. Here the 3rd and 4th MSB is set to 0xC0C0 for the base UUID. The characteristic UUIDs are then formed by incrementing 0xC0C0. To improve the readability of this lab, we may only mention the 3rd and 4th MSB of the UUIDs.

../../_images/TITerminalCharacteristic.png

Smartphone Services View#

  1. First, on the characteristic Server Data which has the UUID 0xC0C2, turn the switch on to enable Bluetooth Low Energy notification. This button will turn green after the notifications have been enabled.

../../_images/NotifyDataStreamSmartPhone.png

Smartphone Notification Characteristic View#

  1. Then, on Characteristic Write Data which has the UUID 0xC0C1, press the Write button to write the string value to echo. Note to change the format in the combo box. To write an ASCII string you have to change it to UTF-8. A string should be written and the OK button should be pressed. This will write the data to the characteristic.

../../_images/UTF8DataStreamSmartPhone.png

Smartphone Changing inputs View#

Hint

At this point the green led should be turn off and the red one turn on, to indicate that the data has been received.

  1. The value that appears in the Server Data characteristic section will be an echo of what is written to the Write Data characteristic. The response is sensitive case, a message in capital letters will be in small letters in response and vice versa.

../../_images/EchoDataStreamSmartPhone.png

Smartphone Echoing View#

Note

If the string value exceed 20 characters, a second request is sent and two packets are visible in the notifications field. Thus, the led toggle twice.

To summarize, when we write to the characteristic, the SmartPhone device sends the data via Bluetooth LE to the SimpleLink CC2340R5 LaunchPad which receives it, processes it, packages it, and sends it back to the SmartPhone to the other characteristic. Thus, data are transmitted both ways, from the SmartPhone to LaunchPad and vice-versa.

Changing device configurations#

This section describes how to customize your device configurations:

  • Change the Data Stream Service and Characteristics UUID - This is useful when the central expects specific UUIDs or you want to deploy the system with your own UUIDs.

Change UUIDs#

This section will touch upon UUIDs and how to change them for your project.

Currently our Characteristic UUIDs for Data_stream Service, In Characteristic and Out Characteristic are as the following picture shows:

../../_images/PreviousUUIDSmartPhone.png

Smartphone Initial UUID View#

Note

In this guide, we’ll consider this point of view for the inputs/outputs for the TI_BASE_UUID_128:

Data Stream Server Service UUID: 0xC0C0

Data In characteristic UUID: 0xC0C1

Data Out characteristic UUID: 0xC0C2

To change that we need first to modify the advertising UUID:

  1. Open the .syscfg file on CCS (located at the project’s root). Inside the app folder of the data_stream project. Expand RF Stacks Section → BLE → Broadcaster Configuration → Advertisement Set 1 → Advertisement Data 1 → UUID 0 (128-bit More) and change by an other UUID

Note

For this example

0x9ECADC240EE5A9E093F3A3B50100406E
../../_images/advUUIDchangedSyscfg.png

UUID Advertisment Sysconfig View#

  1. Then, make a copy of the data_stream_server.c file, as for the moment this file is a Linked File. Thus, to avoid to change all your future projects, as it will directly impact the roots of all your projects, we need to create a local copy of this file.

To do so:

  • First, write down the location of the file by memorize its path:

    • Open data_stream_server.c located in common →Services → data_stream in your file project.

    • Right click → Open in integrated terminal

  • Delete the file in the Project Explorer view.

  • Drag and drop the data_stream_server.c file from your System Explorer to the exact same location you deleted it once step before, but tick the copy option.

Hint

At this point you should see in the properties of your file that the Type of your file is no longer a Linked File type.

  1. Change the UUID base, open data_stream_server.c, at the beginning of the file add the following code in the CONSTANTS section and modify it with the UUID base we want for this example.

Content to add to the CONSTANTS section of the data_stream_server.c file#
  /// @brief Customer Base 128-bit UUID: 6E40XXXX-B5A3-F393-E0A9-E50E24DCCA9E
  #define CUSTOMER_BASE_UUID_128( uuid )  0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, \
                                    0x93, 0xF3, 0xA3, 0xB5, LO_UINT16( uuid ), HI_UINT16( uuid ), \
                                    0x40, 0x6E 
  /// @brief GATT Custom UUID
  #define GATT_UUID_C(name, UUID) CONST uint8 name[ATT_UUID_SIZE] =\
  {\
    CUSTOMER_BASE_UUID_128(UUID)\
  }    
  1. Modify the LOCAL VARIABLES section with your GATT Custom new value by adding the _C characters at the end of the data name: GATT_UUID

Content to modify to the LOCAL VARIABLES section of the data_stream_server.c file#
  // Data Stream Server Service UUID: 0x0001
  GATT_UUID_C( dss_serv_UUID, DSS_SERV_UUID );
      
  // Data In Characteristic UUID: 0x0002
  GATT_UUID_C( dss_dataIn_UUID, DSS_DATAIN_UUID );

  // Data Out Characteristic UUID: 0x0003
  GATT_UUID_C( dss_dataOut_UUID, DSS_DATAOUT_UUID );  
  1. To change the different UUID, create a copy of the data_stream_server.h file as the same way as we did on step 2 with the data_stream_server.c file.

The data_stream_server.h file is located in common→Services→data_stream in the project explorer.

At the beginning of the file change the #defines: DSS_SERV_UUID DSS_DATAIN_UUID DSS_DATAOUT_UUID

Make sure to change the three lines with the right UUID part of the data_stream_server.h file#
  /*********************************************************************
  * CONSTANTS
  */
  // Service UUID
  #define DSS_SERV_UUID 0x0001

  // Characteristic defines
  #define DSS_DATAIN_ID   0
  #define DSS_DATAIN_UUID 0x0002

  // Characteristic defines
  #define DSS_DATAOUT_ID   1
  #define DSS_DATAOUT_UUID 0x0003

Note

Don’t forget to change the include of the data_stream_server.h, it needs to point on your local copy.

change this code in the INCLUDES section of the data_stream_server.c file#
  //#include <ti/bleapp/services/data_stream/data_stream_server.h>
  #include "data_stream_server.h" // change with this line

Hint

Test your changes, at this point you can build and flash the code on the device.

../../_images/UUIDdifferentSmartPhone.png

Smartphone final UUID View#

Hint

You should have a GATT table similar to the one above.

Note

If the GATT table still unchanged, you have to update the GATT Table by disabling-enabling the Bluetooth LE connection. If it still doesn’t work properly, reinitialize the GATT information cached by erasing the pairing connection, go to your device settings to dissociate it from the SimpleLink CC2340R5 LaunchPad

Customize the project#

After this section you will be able to use few features of the device such as using hardware to send data to your phone by different ways.

Handle LEDs#

First, we need to know how to set up LED. Open data_stream.syscfg → TI DRIVERS → GPIO.

../../_images/GreenLedConfigurationSysConfig.png

LED configuration Sysconfig View#

For this example, you should see 6 different GPIOs set up, you can choose the exact software name for each led, here for the green led we have chosen CONFIG_GPIO_LED_GREEN. Then you have to select bunch of parameters, pay attention to attach the right hardware device. You could find below several functions to interact with this led: CONFIG_GPIO_LED_GREEN.

Handle an LED#
  GPIO_write(CONFIG_GPIO_LED_GREEN, CONFIG_LED_ON); // turn on the LED
  GPIO_write(CONFIG_GPIO_LED_GREEN, CONFIG_LED_OFF); // turn off the LED
  GPIO_toggle(CONFIG_GPIO_LED_GREEN); // toggle the LED

Turn on both LED when receiving the expected keyword#

Here the goal is to turn on both led when the peripheral received a specific value from the writing characteristic. To do so, we need to analyze the content of the buffer and compare it to an expected keyword. Open the app_data_stream.c file, located in app → Profiles in the data_stream project. Find the DS_incomingDataCB( uint16 connHandle, char *pValue, uint16 len ).

First, turn off the led at start and disable the toggle when receiving data. To do so, comment the GPIO_write() functions in the DataStream_start() function in the app_data_stream.c file.

Comment the last two lines#
    bStatus_t DataStream_start( void )
    {
  bStatus_t status = SUCCESS;

  status = DSP_start( &ds_profileCB );
  if( status != SUCCESS )
  {
    // Return status value
    return status;
  }
  // Set LEDs
  //GPIO_write( CONFIG_GPIO_LED_RED, CONFIG_LED_OFF );
  //GPIO_write( CONFIG_GPIO_LED_GREEN, CONFIG_LED_ON );

To disable the toggle, comment the GPIO_toggle() functions in the DS_incomingDataCB() function in the app_data_stream.c file.

Comment the last two lines#
    // Clear lines
  MenuModule_clearLines(APP_MENU_PROFILE_STATUS_LINE1, APP_MENU_PROFILE_STATUS_LINE3);

  // Toggle LEDs to indicate that data was received
  //GPIO_toggle( CONFIG_GPIO_LED_RED );
  //GPIO_toggle( CONFIG_GPIO_LED_GREEN );

Add this code just before the change upper case to lower case and lower case to upper case section. This code will turn on both LEDs when the expected word is entered and turn off when is not.

Code to add before the changing case section in the DS_incomingDataCB() function of the app_data_stream.c file#
    if(len == (sizeof(keyWord) - 1))
    {
      if(!strncmp((const char*)pValue, (const char*)keyWord, len))
      {
        GPIO_write(CONFIG_GPIO_LED_RED, CONFIG_LED_ON);
        GPIO_write(CONFIG_GPIO_LED_GREEN, CONFIG_LED_ON);
      }
      else
      {
        GPIO_write(CONFIG_GPIO_LED_RED, CONFIG_LED_OFF);
        GPIO_write(CONFIG_GPIO_LED_GREEN, CONFIG_LED_OFF);
      }
    }

Don’t forget to add your expected word at the beginning of the function, here we are waiting for the word “red”.

Initialization of the expected word in the app_data_stream.c file#
  static void DS_incomingDataCB( uint16 connHandle, char *pValue, uint16 len )
  {
  bStatus_t status = SUCCESS;
  char dataOut[] = "Data size is too long";
  uint16 i = 0;
  uint8_t keyWord[] = "red";//add this line with your word 

Hint

Test your changes, at this point you can build and flash the code on the device.

Warning

The keyword is case sensitive !

Send Data to the Phone when pressing a button#

This section suggests new ways to send data to the central device. For this lab, the left button of the SimpleLink CC2340R5 LaunchPad is used but you could consider using any other peripheral (GPIO, UART, I2C, SPI, etc.). This section goes deeper in the code than the previous ones and takes about 30 minutes.

A new FreeRTOS task will be created and the button configured to trigger an interruption.

Merge the empty example into data_stream#

First you need to merge the empty example into the data_stream one.

Note

You could also basically create a new task, but the approach suggested reduces the amount of coding.

  1. Prepare the environment

Import the empty project example, making sure to select the same RTOS and Toolchain as for the data_stream project example. The empty project located at:

  C:\ti\simplelink_lowpower_f3_sdk_x_xx_xx_xx\examples\rtos\LP_EM_CC2340R5\drivers\empty

Note

All the code modifications will be done in the data_stream project example.

  1. Copy the empty.c file

  • empty.cis available at the root of the empty project example

    ../../_images/emptyfile.png
  • Paste the file into the data_stream project → app → empty.c

    ../../_images/CopyEmptyFile.png
  1. Copy the code used for task creation

  • In order to keep the main() function in main_freertos.c clear, all task creations are deferred to other files. The same will be done for our new task.

  • In the newly created empty.c (in the data_stream project), add the function emptyMain. This function can be placed at the end of the file.

  • Copy-paste into this function the code used in the empty project example to create the task. This code is located in the file main_freertos.c. Don’t forget to add all the includes, variable declarations and other global symbols to your file.

  • Make to ensure the BLEStack is always running with the highest priority. To do so, lower the priority assigned to the newly created function.

Here is the code you should get in empty.c
Header Files and Defines#
  /* POSIX Header files */
  #include <pthread.h>

  /* RTOS header files */
  #include <FreeRTOS.h>
  #include <task.h>

  /* Stack size in bytes */
  #define THREADSTACKSIZE 1024
Code to add in empty.c file inside the data_stream project. The emptyMain function handles task creation.#
  void emptyMain(void)
  {
    pthread_t thread;
    pthread_attr_t attrs;
    struct sched_param priParam;
    int retc;

    /* Initialize the attributes structure with default values */
    pthread_attr_init(&attrs);

    /* Set priority, detach state, and stack size attributes */
    priParam.sched_priority = 5; // Lower the priority of this task
    retc = pthread_attr_setschedparam(&attrs, &priParam);
    retc |= pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED);
    retc |= pthread_attr_setstacksize(&attrs, THREADSTACKSIZE);
    if (retc != 0)
    {
      /* failed to set attributes */
      while (1) {}
    }

    retc = pthread_create(&thread, &attrs, mainThread, NULL);
    if (retc != 0)
    {
      /* pthread_create() failed */
      while (1) {}
    }
  }
  
  1. Call the newly added code from the main() function in main_freertos.c

  • main_freertos.cis available at the root of the data_stream project example

  • Declare the emptyMain function as an extern function in main_freertos.c

Extern functions in main_freertos.c
The emptyMain function is declared as an extern function#
  /*******************************************************************************
    * EXTERNS
    */
  extern void appMain(void);
  extern void AssertHandler(uint8 assertCause, uint8 assertSubcause);
  extern void emptyMain(void); // Add this!
  • Call the emptyMain function right before turning on the RTOS

emptyMain() is called right before turning on the RTOS#
  /* Initialize all applications tasks */
  appMain();
  emptyMain(); // Add this!

  /* Start the FreeRTOS scheduler */
    vTaskStartScheduler();

Note

Merging is done, at this point we have an empty task, now we can use it.

Configure the button#

First, disable the hardware attached to CONFIG_BUTTON_0. Open the .syscfg file of the data_stream project, in TI DRIVER APPS →Button click on CONFIG_BUTTON_0 and change the value in the Use Hardware field by None. See the next image for reference.

../../_images/LeftButtonDisable.png

Disable the Left Button Sysconfig View#

Note

These previous steps disable the hardware left button for the data_stream menu.

Now, configure a new GPIO for our task. In the same file go to TI Drivers →GPIO click on the + icon to add a GPIO. Then configure the new GPIO as shown on the image below.

../../_images/LeftButtonConfigurationSysConfig.png

Configure a new Left Button Sysconfig View#

Add the trigger function LeftButtonPressed() at the end of the empty.c file.

Add this code at the end of the empty.c file#
    /*********************************************************************
    * @fn      LeftButtonPressed
    *
    * @brief   Send to notify the value only if the left button has been pressed
    *
    * @param   index
    *
    * @return  None.
    */
    void LeftButtonPressed(uint_least8_t index)
    {
  sem_post(&sem);
    }

In the previous code section, we have developed the function triggered when the left button is pressed. In this function you could see the function sem_post() which activate the semaphore when the button has been pressed.

Open the app_peripheral.c file located in the app folder. In the Peripheral_GAPConnEventHandler() function enables the button when the BLEAPPUTIL_LINK_ESTABLISHED_EVENT event is caught, see the code below.

code to add in the app_peripheral.c file#
    void Peripheral_GAPConnEventHandler(uint32 event, BLEAppUtil_msgHdr_t *pMsgData)
    {
  switch(event)
  {
    case BLEAPPUTIL_LINK_ESTABLISHED_EVENT:
    {
      //Enable the Left Button
      GPIO_setCallback(CONFIG_GPIO_BUTTON_LEFT, LeftButtonPressed); //add this line!
      GPIO_enableInt(CONFIG_GPIO_BUTTON_LEFT); // add this line!

Disable it in the same Peripheral_GAPConnEventHandler() function, but when the BLEAPPUTIL_LINK_TERMINATED_EVENT event is called.

add this code in the app_peripheral.c file, don’t forget to add the header #include < ti/drivers/GPIO.h> at the beginning#
  case BLEAPPUTIL_LINK_TERMINATED_EVENT:
  {
    GPIO_disableInt(CONFIG_GPIO_BUTTON_LEFT); // add this line!
    BLEAppUtil_advStart(peripheralAdvHandle_1, &advSetStartParamsSet_1);
    break;
  }

Implement the thread#

Now the most important part is to implement all these elements in the mainThread() function. Pay attention to place the BLEAppUtil_stackRegister() function at the very beginning of the mainThread, this function register callback in the ICALL for application events. Also, we create the semaphore, used in the trigger button function, with sem_init(). Then we call the function sem_wait() in order to wait if the button is triggered. Once it is thanks to the sem_post() function, the code can proceed and finally send the data with the DSP_sendData() function.

Find the mainThread code below:

Content of the mainThread function
Code of the mainThread() function in the empty.cfile#
  /*======== mainThread ========*/
  void *mainThread(void *arg0)
  {
    BLEAppUtil_stackRegister();
    int32_t semStatus;
    /* Create semaphore */
    semStatus = sem_init(&sem, 0, 0);
    if (semStatus != 0)
    {
      /* Error creating semaphore */
      while (1) {}
    }
    while (1)
    {
      /* Do not write until read callback executes */
      sem_wait(&sem);
      //Reset the toggle mode when both are ON
      if (GPIO_read(CONFIG_GPIO_LED_RED) == 1 && GPIO_read(CONFIG_GPIO_LED_GREEN) == 1)
      {
        GPIO_toggle( CONFIG_GPIO_LED_GREEN );
      }
      GPIO_toggle( CONFIG_GPIO_LED_RED );
      DSP_sendData(buttonWord,sizeof(buttonWord));
      GPIO_toggle( CONFIG_GPIO_LED_GREEN );
    }
  }

Make sure to declare all the right headers and differents using functions and variables before the mainThread function in the empty.c file

Others headers, functions and variables declarations in the empty.c file
  /*Bcomdef and semaphore include*/
  #include <semaphore.h>
  #include "bcomdef.h"

  /* External Function */
  extern bStatus_t DSP_sendData( uint8 *pValue, uint16 len );
  extern void BLEAppUtil_stackRegister();
    
  /* Local Function */
  void LeftButtonPressed(uint_least8_t index);

  /*Local Variable*/
  static sem_t sem;
  uint8 buttonWord[] = "LEFT";  
also add this function declaration in the app_peripheral.c file#
  void LeftButtonPressed(uint_least8_t index);

To summarize, this section allows you to send data using the notify characteristic when you are pressing a button on the device. We’re using semaphores when the function LeftButtonPressed() is triggered, it will send a string value to the characteristic with the DSP_sendData() function. With this example, once the button is pressed the content of buttonWord which contains the value LEFT is sending and both LEDs, green and red toggle to indicate that the data is received.

Hint

Test your changes, at this point you can build and flash the code on the device.

You should have a result similar to the one below, make sure to enable the notify by switching on the notification button. Press the left button in the LaunchPad and the value in the notify characteristic should be LEFT without entering anything in the writing characteristic.

Note

Pay attention to select UTF-8 in the combo box, otherwise the value will be in hexadecimal unit.

../../_images/LeftButtonNotifySmartPhone.png

Smartphone left word View#

Hint

Congratulations! You have completed this lab 🏆

References#

SimpleLink CC2340R5 LaunchPad
SIMPLELINK-LOWPOWER-F3-SDK
[CCS 12.7]
TI website
TI SimpleLink Connect App
BLE5 Stack User’s Guide
Quick Start Guide

previous

TI SimpleLink™ Connect App

next

SimpleLink™ basic_ble examples

On this page
  • Introduction
  • Prerequisites
    • Hardware
    • Software
    • Readings
  • Agenda
  • Preparation
    • Initial Setup
  • Introduction of the GATT concepts
    • Attributes and Characteristics
    • Handle
    • UUID
  • First connection using GATT table
    • Data_stream Operational Principles
  • Changing device configurations
    • Change UUIDs
  • Customize the project
    • Handle LEDs
    • Turn on both LED when receiving the expected keyword
    • Send Data to the Phone when pressing a button
      • Merge the empty example into data_stream
      • Configure the button
      • Implement the thread
  • References

© Copyright 2025, Texas Instruments.