Connection Monitor (CM) Examples Guide
Table of Contents
Introduction
The Connection Monitor (CM) project utilizes the monitor role from the TI Micro BLE Stack (uBLE-Stack) to collect connection data from external BLE connections without having to formally participate in a BLE connection. The monitor role is not an official BLE Specification defined role. It is designed to follow an active BLE connection given the following parameters:
- Access address
- Connection Interval
- Hop Increment Value
- Channel Map
- Master Sleep Clock Accuracy (mSCA)
The connection monitor performs an initial scan and listens on a data channel to capture a packet and establish an anchor point for the specified connection. Once established, it will continue to monitor the connection by capturing the master and slave packets involved in the connection. It is able to return information such as the respective packet’s RSSI value and timestamp.
For more information on the TI Micro BLE Stack see BLE-Stack User’s Guide for Bluetooth 4.2.
There are two projects/configurations:
App Build Configuration | Description |
---|---|
CM_FlashOnly_MultiMode | Base application showing how to use Micro BLE Stack in the Connection Monitor Role |
uNPI_CM_FlashOnly_MultiMode | Same as the CM_FlashOnly_MultiMode project, with unified NPI built in to receive data from a host |
The CM_FlashOnly_MultiMode (embedded) configuration requires the Connection Information parameters to be hard-coded into the Connection Monitor project, while the uNPI_CM_FlashOnly_MultiMode configuration uses uNPI (unified NPI) to receive the Connection Information parameters from the host.
Due to having a large delay from establishing the connection to inputting the connection information parameters, the CM_FlashOnly_MultiMode configuration’s initial scan is on a set data channel. This is currently on data channel 0. The uNPI_CM_FlashOnly_MultiMode configuration has the benefit of having the Connection Information parameters provided near instantly on connection establishment. This means it uses the current data channel that the connection was established on to quickly establish an anchor point.
Limitations
The current implementation of the Connection Monitor is designed only for the LAUNCHXL-CC2640R2 with the following limitations:
- The current µBLE-Stack does not support 2M PHY/Coded PHY
- Only supports Channel Selection Algorithm #1
- Performance can degrade with number of connections being monitored and an increased disparity in size between connection intervals
- RAM and flash constraints limit the max number of sessions monitored at a time
Hardware Prerequisites
Both CM_FlashOnly_MultiMode and uNPI_CM_FlashOnly_MultiMode is designed to use LAUNCHXL-CC2640R2.
2 additional LAUNCHXL-CC2640R2 will be required to create a connection to monitor. One of these launchpads will be running host_test or simple_central to act as a central. Another LaunchPad will be flashed with simple_peripheral to act as a peripheral for host_test to connect to. This can be replaced with another peripheral, such as a phone.
- Two LAUNCHXL-CC2640R2 is required.
- One Computer able to utilize its Serial Ports is required.
- One Peripheral is required. (Or an additional LAUNCHXL-CC2640R2)
Software Prerequisites
For information on what versions of Code Composer Studio and IAR Embedded Workbench to use, see the Release Notes located in the docs/blestack folder. For information on how to import this project into your IDE workspace and build/run, please refer to The CC2640R2F Platform section in the BLE-Stack User’s Guide for Bluetooth 4.2.
In order to utilize ‘npi_cm_host.py’ for the uNPI_CM_FlashOnly_MultiMode configuration you will need a valid installation of
Required Python Modules
The ‘npi_cm_host.py’ script utilizes modules that need to be installed
The ‘requirements.txt’ contains a list of the modules required; can be used with
pip install -r requirements.txt
‘requirements.txt’ and ‘npi_cm_host.py’ are located in
/tools/blestack/connection_monitor/
Usage
Setup and User Guide For uNPI_CM_FlashOnly_MultiMode
Set Up
The uNPI_CM_FlashOnly_MultiMode project utilizes the UART peripheral through unified NPI. This requires the computer to be connected to the LaunchPad through USB. Flash uNPI_CM_FlashOnly_MultiMode project onto a LaunchPad and connect it the computer.
Flash another LaunchPad with the host_test project, connect this LaunchPad to the computer.
Each LaunchPad connected to the computer will enumerate as 2 COM ports. Always use the port labeled as “XDS110 Class Application/User UART”, this interfaces Application UART.
Take note of which COM port belongs to the LaunchPad running uNPI_CM_FlashOnly_MultiMode and which COM port belongs to the LaunchPad running host_test.
Optionally, if using a third LaunchPad as a peripheral - flash the final LaunchPad with simple_peripheral. After flashing is completed, record the Bluetooth Device Address. This can be found in the UART terminal. Once the Bluetooth Device Address is noted the LaunchPad is only required to be powered, no need to connect to the computer through the debugger.
Running the Script Manually with No Arguments
Some modifications to ‘npi_cm_host.py’ are required prior to running the project. These modifications are to configure the script to control the correct devices and connect host_test to the right peripheral.
- Update ‘host_port’ with the COM Port of the LaunchPad running host_test.
- Update ‘cm_port’ with the COM Port of the LaunchPad running uNPI_CM_FlashOnly_MultiMode.
- Update ‘strPeerAddress’ with the Bluetooth Device Address of the peripheral to be connected to.
- Run the script using Python. This requires calling the python executable with the path to ‘npi_cm_host.py’ passed in as an argument.
if __name__ == '__main__':
global peerAddrs
version_control()
rtn_args = parse_args()
if(len(sys.argv) < 4):
print '\nUsing Default Hardcoded Values: '
print 'or enter 3 default(cm_port host_port peerAddress) arguments.'
print 'See -h help.\n'
#set your own hard coded com ports
host_port = 'COM104'
cm_port = 'COM105'
strPeerAddress = '0xB0912265CBE2'
C:\Python27\python.exe [sdk]\tools\blestack\connection_monitor\npi_cm_host.py
Note ‘sdk’ refers to the Software Development Kit installation directory.
The script will send commands to the LaunchPad running host_test to act as a central device and connect to the peripheral. Then it will query the central for the current connection parameters. Finally it will launch the connection monitor with the retrieved connection parameters. A continuous stream of RSSI data and timestamps from the connection monitor of master and slave devices at each connection event will appear in the terminal after a short delay. The default connection interval of connection events is 100ms.
Running the Python Script or Executable with Command Line arguments
To run the script without editing the python code, the configuration information can be passed into the script as arguments. An executable is also provided, allow the user to utilize uNPI_CM_FlashOnly_MultiMode project without having Python installed. Similar to the python script, arguments need to passed in when being invoked.
The arguments are expected to be in the following order:
Argument 1 | Argument 2 | Argument 3 |
---|---|---|
CM COM PORT | host_test COM PORT | Peripheral Bluetooth Address |
[sdk]\tools\blestack\connection_monitor\npi_cm_host.exe COM4 COM5 0xB0912265CBE2
Or alternatively the same command line will also work with a direct call to the python script.
C:\Python27\python.exe [sdk]\tools\blestack\connection_monitor\npi_cm_host.py COM4 COM5 0xB0912265CBE2
Note ‘sdk’ refers to the Software Development Kit installation directory.
The script will send commands to the LaunchPad running host_test to act as a central device and connect to the peripheral. Then it will query the central for the current connection parameters. Finally it will launch the connection monitor with the retrieved connection parameters. A continuous stream of RSSI data and timestamps from the connection monitor of master and slave devices at each connection event will appear in the terminal after a short delay. The default connection interval of connection events is 100ms.
Additional Information
The script ‘npi_cm_host.py’ contains in-line comments - these comments describe script behavior.
Setup and User Guide For CM_FlashOnly_MultiMode
Set Up
CM_FlashOnly_MultiMode does not utilize unified NPI, thus has no transport layer interface to the UART Module. In order to configure the connection monitor, connection parameters must be manually placed into application code and compiled. Connect a LaunchPad which will be flashed with CM_FlashOnly_MultiMode to the computer. This will be the Connection Monitor LaunchPad.
Another LaunchPad will be acting as a central device. Flash this LaunchPad with simple_central and connect to it’s COM Port using a serial terminal emulator such as Putty. See Simple Central Guide for instructions on how to utilize and get the project working.
Optionally, if using a third LaunchPad as a peripheral - flash this final LaunchPad with simple_peripheral. After flashing is completed, record the Bluetooth Device Address. This can be found in the UART terminal. Once the Bluetooth Device Address is noted, the LaunchPad is only required to be powered, no need to connect to the computer through the debugger.
Form a connection between the simple_central and simple_peripheral through the simple_central’s two button interface. In other words, scan for devices, and connect to the advertising simple_peripheral by verifying the Bluetooth Device Address noted earlier.
Once a connection is formed, use the ‘Connection Info’ menu option to extract the Connection Information required by the Connection Monitor. Ensure that the connection is maintained.
Open the CM_FlashOnly_MultiMode project; in the ‘micro_cm_demo.c’ source file, the ‘MicroCmDemo_init’ function, input the Connection Information retrieved, such as the Access Address, Connection Interval, and Hop Value.
/* Initialize Connection Monitor */
if (ubCm_init() == true)
{
/*
* The ubCM_Start() is called here to kick off CM sessions as a demo.
* This API should be called from host uNPI once the uNPI host
* if available. The currentStartTime, access address, and scan duration
* are hard-coded. They should be provided by the host. In this demo, the
* very first ubCM_start() call will cover UB_MAX_MONITOR_DURATION.
*/
ubCMConnInfo.ArrayOfConnInfo[0].accessAddr = 0x87318ba3;
ubCMConnInfo.ArrayOfConnInfo[0].currentStartTime = 0;
ubCMConnInfo.ArrayOfConnInfo[0].nextStartTime = RF_getCurrentTime() + 100 * BLE_TO_RAT;
ubCMConnInfo.ArrayOfConnInfo[0].scanDuration = UB_MAX_MONITOR_DURATION; // 40.96s
ubCMConnInfo.ArrayOfConnInfo[0].connInterval = 1600;
ubCMConnInfo.ArrayOfConnInfo[0].hopValue = 15;
ubCMConnInfo.ArrayOfConnInfo[0].combSCA = 90; // Master+Slave = 50+40
ubCMConnInfo.ArrayOfConnInfo[0].chanMap[0] = 0xFF;
ubCMConnInfo.ArrayOfConnInfo[0].chanMap[1] = 0xFF;
ubCMConnInfo.ArrayOfConnInfo[0].chanMap[2] = 0xFF;
ubCMConnInfo.ArrayOfConnInfo[0].chanMap[3] = 0xFF;
ubCMConnInfo.ArrayOfConnInfo[0].chanMap[4] = 0x1F;
Build the project and flash the Connection Monitor LaunchPad with the updated CM_FlashOnly_MultiMode project.
Observing the Monitored Information
Open Putty on the computer, and connect to the “XDS110 Class Application/User UART” COM Port that corresponds to the Connection Monitor LaunchPad. After about 40 seconds RSSI and timestamp information should appear as the Connection Monitor LaunchPad following the connection between the central and the peripheral.
Keeping Track of the Connection
ubCM_ConnInfo_t struct
The following is the main struct that keeps track of the values required to monitor a connection and also stores the information gathered from a scanned packet:
typedef struct
{
uint8_t sessionId; //! Number 1-255 assigned as they are created identifying each connection monitor session
uint8_t timesScanned; //! track count of recent events monitored to determine next priority CM session to avoid starvation
uint8_t timesMissed; //! missed count of recent events monitored
uint32_t accessAddr; //! return error code if failed to get conn info
uint16_t connInterval; //! connection interval time, range 12 to 6400 in 625us increments (7.5ms to 4s)
uint16_t scanDuration; //! Required scan window to capture minimum of 1 packet from Master and Slave up to max possible packet size
uint8_t hopValue; //! Hop value for conn alg 1, integer range (5,16)
uint16_t combSCA; //! mSCA + cmSCA
uint8_t prevChan; //! previous channel
uint8_t currentChan; //! current data channel
uint8_t nextChan; //! next data channel
uint8_t chanMap[CM_NUM_BYTES_FOR_CHAN_MAP]; //! bitmap of used channels, use to reconstruct chanTableMap
uint8_t masterAddress[CM_DEVICE_ADDR_LEN]; //! BLE address of connection master
uint8_t slaveAddress[CM_DEVICE_ADDR_LEN]; //! BLE address of connection slave
uint8_t rssiMaster; //! last Rssi value master
uint8_t rssiSlave; //! last Rssi value slave
uint32_t timeStampMaster; //! last timeStamp master
uint32_t timeStampSlave; //! last timeStamp slave
uint32_t currentStartTime; //! Current anchor point
uint32_t nextStartTime; //! Record next planned scan anchor point to compare with competing CM sessions
uint32_t timerDrift; //! Clock timer drift
} ubCM_ConnInfo_t;
Generally, these members should not be modified as they are already being self-maintained by the connection monitor.
However, in the case that fine tuning is needed for the scan window the following should be understood:
For the scans after the initial scan, ubCM_setupNextCMEvent() of micro_ble_cm.c updates the scanDuration, currentStartTime, nextStartTime, and the currentChan.
These members are in the units of RAT (Radio Timer) ticks. The conversion from milliseconds to RAT ticks is as follows: x ms/ 0.625 ms = RAT ticks where x is the desired time in ms.
The scanDuration takes account for timing factors such as the timerDrift, the Radio RX Settle Time, and other processing delays. If an increase or decrease to the scan length is needed, adjust scanDuration accordingly.
The currentStartTime determines where the scan will begin. It is determined by the anchor point from the last Master packet’s timestamp and shifts that timestamp forward based on the connInterval multiplied by how many connection events have passed. To guarantee a captured packet, the currentStartTime will shift slightly to open earlier than the expected time. If the head of the scan needs to shift left or right, adjust currentStartTime appropriately.
The nextStartTime records the next planned scan anchor point to compare with competing CM sessions. The RF driver uses this value to decide if the scan will be scheduled or not. If a scan is absent, this can be the cause.
The currentChan will simply update to the next channel.