5.3.3 BLE and LCC Transparent UART

This section explains how to integrate a Low Cost Controllerless (LCC) graphics display with Bluetooth® Low Energy (BLE) technologies using the PIC32-BZ6 Curiosity Board. The guide provides step-by-step instructions on setting up a BLE central thermostat device capable of communicating with up to eight peripheral devices that support transparent service, including smartphones running the Microchip Bluetooth Data (MBD) application. Users will learn how to utilize the Microchip Graphics Composer to create a simple thermostat application using various widgets. The application provides real-time temperature measurements using the onboard temperature sensor.

This demonstration highlights how data received from peripheral devices can be displayed on the screen, and how multiple devices can be managed through the graphical user interface (GUI). Users will also learn how to send BLE packets from the PIC32-BZ6 Curiosity Board to any of the connected peripheral devices.

Throughout the section, users will explore various GUI widgets and discover how the PIC32-BZ6 Curiosity Board can support complex applications that display multiple data points simultaneously. This comprehensive guide ensures that users can effectively leverage the capabilities of the PIC32-BZ6 Curiosity Board for advanced BLE and display integration projects.

Hardware Requirement

Table 5-72. Hardware Requirement
S. No.ToolQuantity
1PIC32-BZ6 Curiosity Board 3
2USB-C cable3
3RGB332 Adapter 1
44.3’’ WQVGA Display1

SDK Setup

Refer to Getting Started with Software Development from Related Links.

Software Requirement

  1. To install Tera Term tool, refer to the Tera Term web page in Reference Documentation from Related Links.

Smart phone App

  1. Microchip Bluetooth Data (MBD)

Programming the Precompiled Hex File or Application Example

Using MPLAB® X IPE:

  1. Import and program the precompiled hex file: <Harmony Content Path>\wireless_apps_pic32_bz6\apps\ble\peripheral_applications\lcc_central_trp_uart\precompiled_hex.
  2. For detailed steps, refer to Programming a Device in MPLAB® IPE in Reference Documentation from Related Links.
    Note: Ensure to choose the correct Device and Tool information.

Using MPLAB® X IDE:

  1. Perform the following the steps mentioned in Running a Precompiled Example. For more information, refer to Running a Precompiled Application Example from Related Links.
  2. Open and program the application lcc_central_trp_uart.X located in <Harmony Content Path>\wireless_apps_pic32_bz6\apps\ble\peripheral_applications\lcc_central_trp_uart \firmware.
  3. For more details on how to find the Harmony Content Path, refer to Installing the MCC Plugin from Related Links.

Demo Description

The following diagram shows the basic flow of the demonstration.

To highlight the graphics controlling capabilities, we present a simple thermostat that will display the temperature of the onboard temperature sensor.

There are various screens the user can navigate to (home, BLE options, and settings) via button presses. There are other GUI components such as buttons to control the fan, mode, and to increase or decrease the temperature. The semicircular gauge in the center of the screen will rotate clockwise with increasing temperature readings and counter clockwise with decreasing temperature readings.

If the “Set To” temperature is greater than the onboard temperature reading, then the thermostat will transition to “Heat” mode and the color scheme will be orange. Conversely, if the “Set To” temperature is less than the onboard temperature reading, then the thermostat will transition to “Cool” mode and the color scheme will be blue.

This system acts as a BLE central device that is capable of scanning, connecting, and communicating with up to 8 peripherals. Within the “Scan” page, devices scanned will be added to a list widget. When devices in the list are selected by the user, a connection will attempt to be made. A mobile phone with the MBD app or devices like WBZ351, WBZ451, or another PIC32-BZ6 Curiosity Board that support transparent service can be connected to, otherwise connection will fail. In either case a message will display announcing the connection status.

If a WBZ351, WBZ451, or PIC32-BZ6 device is being used with the default peripheral_uart_trp application, the user must comment out the lines in app_ble.c that assign the MAC address in the peripheral_uart_trp application code. These devices must be reprogrammed after making these changes in the peripheral_uart_trp application code. In order for a connection to be made, the MAC address must be unique and the default peripheral_trp_uart applications for these devices set the MAC address to the same address.
A scan filter has been implemented that will filter out devices that are not advertising with “0xDAFE” as the service UUID.

The default peripheral_trp_uart application for WBZ451 does not include “0xDAFE” as the service UUID. To scan the default peripheral_trp_uart WBZ451 devices, the user can disable the scan filter OR modify the service UUID in the BLE Stack MCC Configuration Options under the “Service UUID” section in the peripheral_trp_uart project graph. The code must be regenerated and programmed to the peripheral device for the changes to take place.

The scan filter can be enabled or disabled within the “Settings” page.

The scan filter is enabled by default.

To add custom names to the peripheral devices, this must be done within the peripheral application code. For Microchip BLE devices (WBZ351, WBZ451, PIC32-BZ6) this can be done by changing the “Local Name” in the “Advertisement Data” section in the BLE stack MCC configuration options. The code must be regenerated and programmed to the peripheral device.

Within the BLE options page, we present an environment to scan/connect, communicate, and manage up to 8 peripheral devices.

Within the “Data Communication” page, devices that have been connected to will be displayed within another list.

Once a device is selected from this list, another page will show allowing the user to send packets to the selected device and view received packets from all connected peripherals. Received packets are distinguished with a green arrow and a small number indicating which peripheral sent the packet, whereas sent packets are distinguished only with a red arrow. The device name at the top of the page is the peripheral that will receive the packet sent from the GUI.
Users can quickly switch between connected peripherals to indicate which device the GUI will send to by selecting the device and displaying a popup with a list of connected peripherals.
Within the “Manage Connected Devices” page, users can choose to disconnect from devices.
Meanwhile, various information will also be printed on a terminal application like Teraterm via UART.

The output will show when scanning was initiated and completed. It will also show which devices were scanned and their address. When a connection is attempted, the connection status will also be printed. The data received from the peripheral (“123” in the image) will be shown. Finally, when the device is disconnected, a “Disconnected” message will also be printed.

Besides the disconnect message, all these messages will also be displayed somehow in the GUI. To know if a device was disconnected, it will be removed from the list on the Manage Connected Devices page.

Testing

Hardware setup:

Make sure the cable is connected to a correct position of the LCD module as shown in the above picture.

This demo utilizes two additional PIC32-BZ6 Curiosity Boards configured as BLE Transparent UART and one smartphone device with MBD installed (See BLE Transparent UART from Related Links). These devices act as peripherals that advertise and connect to our central PIC32-BZ6 Curiosity Board.

Board1 = PIC32-BZ6 Curiosity Board with lcc_central_trp_uart application programmed

Board2 = PIC32-BZ6 Curiosity Board with peripheral_trp_uart application programmed

Board3 = PIC32-BZ6 Curiosity Board with peripheral_trp_uart application programmed

Phone1 = smartphone with MBD installed

Board2 and Board3: Open TeraTerm @ (Speed: 115200, Data: 8-bit, Parity: none, stop bits: 1 bit, Flow control: none). Reset the board. Upon reset, the devices will automatically begin advertising and “Advertising” message is displayed on the TeraTerm.
iOS MBD Steps

Phone1: To begin advertising on the MBD app, follow the below sequence of events:

Select BLE UART:
Select PIC32CXBZ:
Select Start:
Switch to the Peripheral page, set the device name to “MBD_Device” and start advertising.

Android MBD Steps

Select BLE UART:
Select PIC32CXBZ(Peripheral):
Set device name to “MBD_device”:
Select “Legacy Advertising” then select “Start” to begin advertising.

Board 1: Open TeraTerm @ (Speed: 115200, Data: 8-bit, Parity: none, stop bits: 1 bit, Flow control: none). Reset the board.

Upon reset, an initial startup screen will be displayed before the home screen.
After a small animation, the home screen will be displayed. The temperature will be temporarily hidden until valid temperatures are read from the onboard temperature sensor. Temperature readings are based off averages over a period of time. Since this is the initial startup, the system needs time to take initial measurements and compute the first average.
After a short period, an accurate temperature reading will be displayed:
Navigate to the BLE options page by selecting the center left button with the BLE icon. This will display the following page.

Navigate to the Scan page by selecting the Scan menu button.

Before scanning, recall that the scan filter is enabled by default, which will only display devices that are advertising with “0xDAFE” as the service UUID. To enable or disable this feature, navigate to the settings page by selecting the gear icon at the bottom left of the screen.

Begin scanning for peripherals by selecting the Scan button. The scan limit is 1 minute 40 seconds. After this, scanning will stop. Advertising devices will begin displaying on the list:
Select the Stop button to complete the scan.
Begin selecting the devices “dev_1_pic32cx-bz6”, “dev_2_pic32cx-bz6”, “MBD_Device”. Once a device is selected, scanning will stop if it was still enabled. Status messages will display in the bottom right corner.
Board2 and Board3 will show a “Connected” message.
Phone1 will automatically switch to this screen upon connection.
After all three peripherals are connected, navigate to the data communication page either by selecting the Go Back button or selecting the BLE icon on the center left of the screen, then selecting the Data Communication menu button shown on the BLE options page.
Select “dev_1_pic32cx_bz6” the following page will display.
On Board2’s terminal window, begin typing characters into the window and the characters will display on the list. The most recently received message will be displayed at the top of the list. Only the latest 30 messages will be displayed on the list.
Select the input field at the top of the page below the device name to display the keyboard. Enter characters and press Send to send to the peripheral device. The maximum input character is 26.
The sent data will be displayed on the list and distinguished with a red arrow, whereas green arrows signify received packets.
The received data on the peripheral will be displayed on Board2’s Teraterm window.

The received data from all connected peripherals will be displayed on the list. The green arrows have a small number that indicates which device sent the packet.

To send packets from MBD to be received by the GUI do the following:

On Phone1, select text mode and ensure “Display data” is turned on in the settings.
Exit the settings page by selecting Done. Then, begin entering and sending messages in the Input String field on MBD.

The message will display on Board1’s GUI with a green arrow and a number 2. Received packets with data longer than 25 bytes will be split into multiple lines on the GUI.

To send data to MBD from the GUI, the device must be selected first.

Press the device name text at the top of the page (“1. dev_1_pic32cx-bz6”) to display a popup menu that displays the connected devices. Select MBD_Device to send messages to MBD.

The device name at the top of the page will be updated to show the device that the GUI will send packets to.
Select the input field at the top of the page below the device name to display the keyboard. Enter characters and press Send to send to the peripheral device.
The sent message will be displayed on Board1 and on MBD on Phone1.
dev_2_pic32cx-bz6 will perform the same as dev_1_pic32cx-bz6. Switch to dev_2_ pic32cx-bx6 as was done before when the MBD_Device was selected. Sending and receiving data for dev_2_ pic32cx-bx6 is exactly the same as dev_1_ pic32cx-bx6 except the GUI will distinguish the received packets with small numbers within the green arrows.
By default, the list will not clear unless the “Clear” button is pressed but a maximum of 30 most recent messages will be displayed on the list.
Next, navigate to the Manage Connected Devices page by selecting the Go Back button and selecting the Manage Connected Devices button.
Ensure “MBD_Device” is selected as shown in the image above and select the Disconnect button. The device will be removed from the list and MBD will show the following message.

Notice that the index associated with dev_2_pic32cx-bz6 was updated from 3 to 2 once MBD_Device was disconnected. If messages are received from dev_2_pic32cx-bz6 at this point, Commented [AB35]: updated then the number within the green arrow will also be updated to 2 from 3. The indices are only updated when peripheral devices are disconnected.

Disconnect from the other two peripherals and their terminal will display a “Disconnected” message.

Developing the Application from Scratch using the MPLAB Code Configurator

Follow the steps below to build the application manually:
Note: It is recommended for the new users of the MPLAB Code Configurator to refer MPLAB® Code Configurator (MCC) User’s Guide in Reference Documentation from Related Links.
  1. Create a new harmony project. For more details, see Creating a New MCC Harmony Project from Related Links.

  2. Import component configuration – This step helps users setup the basic components and configuration required to develop this application. The imported file is of format .mc3 and is located in the path “<Harmony Content Path>\wireless_apps_pic32_bz6\apps\ble\peripheral_applications\lcc_central_trp_uart \firmware\lcc_central_trp_uart.X”.
  3. Accept dependencies or satisfiers when prompted.
  4. Verify if the Project Graph window has all the expected configuration.

The following components are from the GFX library:

  • Gfx Core LE
  • Input System Service
  • MaxTouch Controller
  • PDA TM4301B
  • LE LCC
  • Legato

This project utilizes the GFX library to generate the code needed for graphics projects. Refer Harmony guide Getting Started with Microchip Graphics Suite (MGS) Harmony in Reference Documentation from Related Links for graphics projects. Additionally, it is recommended that users refer to Getting Started with a New Harmony Graphics Application in Reference Documentation from Related Links to learn how to utilize the library to create projects.

Microchip Graphics Suite (MGS) Harmony Composer is a GUI design tool used to create widgets and configure various screens. For more information about the MGS Composer, refer to Microchip Graphics Suite (MGS) Harmony Composer User Guide in Reference Documentation from Related Links.

For more information on the BLE related components, see BLE Transparent UART from Related Links.

GUI Design Decisions

For high resolution displays, one of the main contributors of RAM usage will be the frame buffer which is dictated by the pixel count and cannot be minimized.

Additionally, the scratch buffer contributes heavily to RAM usage. It is used for drawing segments of the screen on page refreshes. This can be increased or decreased but will impact refreshing performance. For detailed information on the scratch buffer, see Adjusting Scratch Buffer Size in Reference Documentation from Related Links.

Lastly, the fixed heaps also contribute to the RAM usage but are dictated by the number of widgets used. for further information about fixed heaps, see Optimizing the Memory Manager Settings in Reference Documentation from Related Links.

Frame Buffer:

Since we are using Hardware setup 3 for this application, our frame buffer will be allocated within the PIC32-BZ6 Curiosity Board. Additionally, we are using RGB332 so we only require a single byte for each pixel. For our 480x272 display, the frame buffer will require 480*272*1byte = 130,560 bytes.

Scratch Buffer:

To minimize our scratch buffer, we recognize that our design mainly updates the center most part of the screen whereas the left of the screen is a secondary update that just changes the button that is selected. Therefore, we implement a ‘single screen’ design that hides and reveals different panels to create the illusion that screens are changing. Specifically, we only update the portion of the screen shown below which is 338x252 pixels large.

Since the largest part of the screen to be updated is 338x252 pixels, we only need to allocate a scratch buffer of size 338*252*1byte = 85,176 bytes.

In MGS Harmony Composer, each ‘screen’ is a panel sized 338x252, with the exception of the home page. To display the home page, all panels are hidden and only the home widgets will display. When another screen is intended to be shown by pressing one of the three buttons on the left of the screen, the panel will display. For example, when the BLE icon button is selected, an event will be generated and the following panel will be made visible and will become enabled.

Navigating withing MGS Harmony Composer for the Thermostat GUI

  • Since everything is implemented on one screen, the other pages are not visible by default. To view another page, select the panel you would like to view in the Screen Tree, then select visible in the Object Editor. For example, if we want to see the BLE options page, the procedure is as follows:
  • Adding Widgets: Refer to Widgets Guide in Reference Documentation from Related Links.
    New widgets can be dragged and dropped into the MGC screen. Widgets:
    Events are disabled for new widgets by default, so they must be enabled if needed. Also, if an event is enabled, the event handler must be defined in the code otherwise the build will fail. See below for details about events.
  • Fixed Heaps: If a new widget is added, you must increase the number of fixed heaps and reoptimize later (notes on optimization later). Increase all fixed heap sizes by a large amount during development to avoid crashes. Fixed heaps can be increased in the Memory portion of the Project Settings:
    If the fixed heaps are increased in the project settings, the code must be regenerated to reflect the changes in the code.
  • Events: Refer to Creating a Dynamic UI with Event Handling in Reference Documentation from Related Links.
    Events can be enabled or disabled in MGC in the Event Manager under Project:
    Events can also be enabled or disabled in the Object Editor when a widget is selected.
  • Events are handled in the app_screen_splash.c and app_screen_main.c files found in the lcc_central_trp_uart\firmware\src folder. For example, when the BLE button is pressed, the event handler is as follows:

    In this code, all other panels are disabled and made invisible, and only the BLE options panel is enabled and made visible.

  • Images, fonts, and strings can be added and managed in their respective pages found under Asset:

    MGC Assets Guide: Refer to Microchip Graphics Suite (MGS) Harmony Graphics Assets Guide in Reference Documentation from Related Links.

  • Color Schemes Guide: Refer to About the Schemes and Scheme Editor in Reference Documentation from Related Links.
    The available schemes in the project can also be used.

    LightMode is used for the background color of the panels. GrayScheme is used for the gray color of text. HeatingScheme is used for the orange color of text. CoolScheme is used for blue color of text. WhiteScheme is used for white color of text.

Notes about reoptimizing fixed heaps:

Refer to Optimizing the Memory Manager Settings in Reference Documentation from Related Links.

After adding more widgets to the design, the fixed heaps can be increased and reoptimized. The GFX library provides a function called leMemoryPrintReport() that can print out the fixedHeap usage of the GUI to a terminal.

Below is an example of how the fixedHeaps can be optimized with this thermostat GUI using Debug mode and breakpoints rather than printing out the fixedHeap usage report.

  • First increase all heap sizes by at least 5 for each new widget added.
  • Second, uncomment the following line in app_screen_main.c.
  • Then, enable a breakpoint in the leMemoryPrintReport() function in legato_memory.c.
  • Add a watch to the fixedHeaps array.
  • Run the project in Debug mode.
  • Run through the entire GUI, selecting all buttons and making all panels visible at least once. Do not press the temperature down button until the very end.

    Once the down button is pressed, the program will break, and you can analyze the fixedHeaps array to see the max usage.

  • After all buttons are pressed and the down button is pressed last, the program will break. In the “Watches” tab, you can view the fixedHeaps array. Here you can view each fixed heaps logical block size and their max usage:

    fixedHeaps[0] corresponds to LE_FIXEDHEAP_SIZE_16 in legato_config.h. fixedHeaps[1] corresponds to LE_FIXEDHEAP_SIZE_32. fixedHeaps[2] corresponds to LE_FIXEDHEAP_SIZE_64 and so on.

  • Set the fixed heap sizes to the maxUsage number.

    Reprogram the device not in debug mode and run through the entire GUI to ensure there are no crashes.

Tasks and Task Priority

The above diagram shows the multiple tasks running simultaneously. Input system service, LCC, Legato, and MaxTouch Controller all come from GFX while BLE and App core do not. Legato and LCC have higher priority than MaxTouch to prioritize screen updates over touch events but lower priority than BLE to avoid throughput deterioration.

Files and Routines Automatically generated by the MCC

For details about the BLE configuration that is generated, see BLE Transparent UART from Related Links.

For details about GFX code generation, see Getting Started with a New Harmony Graphics Application in Reference Documentation from Related Links.

User Application Development

Include

  • definitions.h in all the files where UART will be used to print debug information.
Note: definitions.h is not specific to just UART peripheral, instead it must be included in all application source files where peripheral functionality will be exercised.
  • Include the user action. For more information, refer to User Action from Related Links.

Pin Settings

Verify the following pin settings:

Unique Files

The following list of files were either edited or added to the project.
FileAdded or EditedNotes
app.cEditedMaintains app state machine. Added OSAL queue callbacks for trp service and a timer callback for the clock. Added to the initialization.
app.hEdited
app_ble.cEditedAdded a function to update and store scanned devices. Configured as active scan.
app_ble.hEdited
app_ble_handler.cEditedMaintain a connection handle list when connections are established and destroyed. Maintain a scanned device list.
app_ble_handler.hEdited
app_ble_utility.cEditedAdded two functions. One for parsing advertisements and extracting the name of the device. The other function converts hex to ascii.
app_ble_utility.hEdited
app_trspc_handler.cEditedUpdates the GUI when data is received. Maintains a list GUI that displays the received data
app_trspc_handler.hEdited
default_design.zipAddedMGS Composer design
app_macros.hAddedHolds macros for gfx library
app_screen_main.cAdded Holds GUI event handling for the main screen
app_screen_main.hAdded
app_screen_splash.cAdded Holds GUI event handling for the initial screen.

Widgets within app_screen_main.c

The following table shows the widgets with their accompanying event handlers.

WidgetEvent handlerNotes
N/AThis displays the current temperature reading from the onboard temperature sensor. It is read every one second, but the temperature displayed is an average of 5 measurements. The small blue circle will move along the white arc with increasing or decreasing temperature readings.
N/AThis displays the desired temperature.
event_Main_UpButton_OnPressed(leButtonWidget* btn)This increases the “Set To” temperature on the home screen. If the “Set To” temperature is greater than the onboard temperature reading, then the thermostat will transition to “Heat” mode and the color scheme will be orange.
event_Main_DownButton_OnPressed(leButtonWidget* btn)This decreases the “Set To” temperature on the home screen. If the “Set To” temperature is less than the onboard temperature reading, then the thermostat will transition to “Cool” mode and the color scheme will be blue.
event_Main_home_button_OnPressed(leButtonWidget* btn)Hides all other panels and shows home screen
event_Main_ble_button_OnPressed(leButtonWidget* btn)Hides all other panels and displays BLE options panel
event_Main_settings_button_OnPressed(leButtonWidget* btn)Hides all other panels and displays the settings panel
event_Main_fan_button_OnPressed(leButtonWidget* btn)Changes the Fan Mode String (Auto, On, Off)
Main_mode_button_OnPressed(leButtonWidget* btn)Changes the Mode string (Cool, Heat) and changes the color scheme.
event_Main_ScannedDevs_0_OnSelectionChanged(leListWidget* wgt, uint32_t idx, leBool selected)On the Manage Connected Devices screen. Used to set the ID for the disconnect event/
event_Main_DisconnectButton_OnPressed(leButtonWidget* btn)Manually disconnect from a device. Updates the GUI and generates Disconnect event. BLE_GAP_EVT_DISCONNECTED in app_ble_handler.c will maintain the connection handle list and handle cases where the GUI was busy when a spontaneous disconnect occurs.
event_Main_GoBackButton_OnPressed(leButtonWidget* btn)Hides other subpanels and displays BLE options page.
event_Main_scan_option_OnPressed(leButtonWidget* btn)Display the Scan panel
event_Main_text_window_option_OnPressed(leButtonWidget* btn)Displays the Data Communication panel where users select a device they want to communicate with
event_Main_manage_option_OnPressed(leButtonWidget* btn)Displays the Manage Connected Devices panel where devices can be manually disconnected
event_Main_connectedDevs_OnSelectionChanged(leListWidget* wgt, uint32_t idx, leBool selected)Go to the BLE communication panel with the selected device as the title. Set the main index so trp service is associated with this device.
event_Main_scan_OnPressed(leButtonWidget* btn)Start the scan
event_Main_scan_OnReleased(leButtonWidget* btn)End the scan
event_Main_ScannedDevs_OnSelectionChanged(leListWidget* wgt, uint32_t idx, leBool selected)Attempt to establish a connection with the selected device. Add device to our connected device lists. BLE_GAP_EVT_CONNECTED event in app_ble_handler.c will maintain the connection handle list.
event_Main_InputField_OnFocusChanged(leTextFieldWidget* btn, leBool state)Displays the keyboard
event_Main_KeyPadWidget_0_OnKeyClick(leKeyPadWidget* wgt, leButtonWidget* cell, uint32_t row, uint32_t col)Checks if the shift key (“^”) was pressed. If it was, make the keyboard characters uppercase. For additional information, refer to How-To Create a Numeric Keypad in Reference Documentation from Related Links.
event_Main_send_OnPressed(leButtonWidget* btn)Queue an event to send the data using transparent service. Update the DataField list buffers.
event_Main_cancel_OnPressed(leButtonWidget* btn)Close the keyboard

event_Main_ClearButton_OnPressed(leButtonWidget* btn)

Clears the TX/RX list

event_Main_DevNameButton_OnPressed(leButtonWidget* btn)

Displays a popup menu listing all connected peripheral devices. Selecting a device from the list sets it as the target for outgoing BLE messages from the central GUI. The GUI will continue to receive data from all connected peripherals, but only the selected device will receive messages sent from the GUI.

event_Main_close_OnPressed(leButtonWidget* btn)

Close the popup window
  • event_Main_enable_filter_checkbox_OnUnchecked(leCheckBoxWidget* btn)
  • event_Main_enable_filter_checkbox_OnChecked(leCheckBoxWidget* btn)
Enables or disables a flag that controls whether to display scanned devices without service UUID “0xDAFE”

Additional GUI Interaction within app_main_screen.c

All interaction with the GUI should be implemented within app_main_screen.c. Therefore, there are additional functions defined within app_main_screen.c.

  • Lists that are dynamically updated require special care.
    • The contents of the scanned peripherals list are updated on a timer. Specifically, TimerCallback2()
    • The contents of the data field list are also updated on a timer.
      The timer callback is in app.c but the contents are updated while the GUI is in the APP_MAIN_STATE_PROCESSING state.
  • Additional helper functions
    • clearDevList() clears the contents of the scanned peripherals list.
    • clearSentList() clears the Data Field list when another device is selected for communication or upon disconnect.
    • shuffleDynamicStringListLeft() is used to maintain the connected device dynamic string list upon disconnect.
    • shuffleBLEListLeft() is used to maintain the connected device list of type APP_BLE_ScannedDev.
    • MainScrn_UpdateClock() is used to update the clock that is displayed on the main screen, it is called every second.
    • MainScrn_UpdateMode() is used to update the Mode string on the home page and change the color scheme.
    • MainScrn_UpdateFan() is used to update the fan string.
  • Screen event callbacks
    • The Main_OnShow() function is the function called only once when the screen is first shown.
    • Main_OnHide() is the function called when another screen is made visible. Since this design is a singe screen. implementation, this function will not be called.
    • Main_OnUpdate() is periodically called to update the GUI. A state machine is maintained to update certain parts of the GUI.

BLE Implementation

Active scanning mode is enabled to scan for MBD in app_ble.c. A struct called APP_BLE_ScannedDev holds the name, address, index, and connection handle for each scanned device and each connected device.

Additionally, only information involving the device name and address is extracted to display the name in the GUI and use the address to check if we are already connected. The functions associated with parsing the advertisements is APP_Adv_Parser() and APP_HexToAscii() in app_ble_utility.c. The name and address are associated with each APP_BLE_ScannedDev scanned.

On an advertisement report event, “BLE_GAP_EVT_ADV_REPORT,” if the scan filter is enabled, the system will parse the advertisement data to check if the service UUID is 0xDAFE. If it is, then the device will be stored and displayed on the GUI. If the scan filter is disabled, all scanned devices will be displayed on the GUI.

When a device is connected successfully, the connection handle is captured in a list so we can utilize each device’s connection handle when communicating.

When a disconnect occurs, the corresponding connection handle is removed from our list. These events are BLE_GAP_EVT_CONNECTED and BLE_GAP_EVT_DISCONNECTED in app_ble_handler.c.

When data is received from a peripheral, BLE_TRSPC_EVT_RECEIVE_DATA in app_trspc_handler.c handles the GUI DataField list update to display the new message.

Temperature Sensor Implementation

To utilize the onboard temperature sensor, the following components must be in the project graph.
Additionally, the following pin must be configured.
The file temp_sensor.c will be generated.

From here, the function MCP9700_Temp_Fahrenheit() can be called to get the temperature reading in Fahrenheit. Each second, this function will be called within the app_main_screen.c file to gather a single reading. The temperature displayed on the home page will be the computed average of the last 5 temperature readings, therefore the reading on the GUI will be updated every five seconds.