| nRF5 SDK v12.0.0 |

Choose documentation: | nRF5 SDK | S130 SoftDevice API | S132 SoftDevice API | S212 SoftDevice API | S332 SoftDevice API

All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
Bicycle Power Monitor
This information applies to the following SoftDevices: S212, S332

This module implements the Bicycle Power ANT+ device profile. The API for this module is available here: Bicycle Power profile

During initialization, the module configures the selected channel and resets the profile data.

# Compile time configuration options

The module traces profile-specific information to UART using the logger.

The following configuration options are available at compile time to assist in the development phase of the Bicycle Power Receiver implementation:

- TRACE_BPWR_GENERAL_ENABLE: Output page number of the current page.
- TRACE_BPWR_PAGE_1_ENABLE: Output page 1 data.
- TRACE_BPWR_PAGE_16_ENABLE: Output page 16 data.
- TRACE_BPWR_PAGE_17_ENABLE: Output page 17 data.
- TRACE_BPWR_PAGE_18_ENABLE: Output page 18 data.
- TRACE_COMMON_PAGE_80_ENABLE: Output common page 80 data.
- TRACE_COMMON_PAGE_81_ENABLE: Output common page 81 data.

The above macros must be defined on the project settings level.

# Bicycle Power Receiver (display)

This module covers the full receiver implementation (PWR):

- Receive all power pages: 0x10, 0x11, 0x12.
- Provide the user a means to initiate and confirm a calibration procedure (throw page 0x01).
- Receive manufacturer and product information (ANT+ common data page 0x50, 0x51).

The following code snippets show how to initialize the profile:

void ant_bpwr_evt_handler(ant_bpwr_profile_t * p_profile, ant_bpwr_evt_t event);
BPWR_DISP_CHANNEL_CONFIG_DEF(m_ant_bpwr,
BPWR_CHANNEL_NUMBER,
WILDCARD_TRANSMISSION_TYPE,
WILDCARD_DEVICE_NUMBER,
ANTPLUS_NETWORK_NUMBER);
BPWR_DISP_PROFILE_CONFIG_DEF(m_ant_bpwr,
ant_bpwr_evt_handler);
ant_bpwr_profile_t m_ant_bpwr;
uint32_t err_code;
err_code = ant_bpwr_disp_init(&m_ant_bpwr,
BPWR_DISP_CHANNEL_CONFIG(m_ant_bpwr),
BPWR_DISP_PROFILE_CONFIG(m_ant_bpwr));
APP_ERROR_CHECK(err_code);
err_code = ant_bpwr_disp_open(&m_ant_bpwr);
APP_ERROR_CHECK(err_code);
err_code = ant_state_indicator_channel_opened();
APP_ERROR_CHECK(err_code);

The following snippet shows how to propagate ANT events to the profile's event handler:

void ant_evt_dispatch(ant_evt_t * p_ant_evt)
{
ant_bpwr_disp_evt_handler(&m_ant_bpwr, p_ant_evt);
ant_state_indicator_evt_handler(p_ant_evt);
bsp_btn_ant_on_ant_evt(p_ant_evt);
}

After opening the profile instance channel, the module keeps the profile structure updated.

The sample application that uses the Bicycle Power Profile to implement a display is available here: Receiver

# Bicycle Power Transmitter (sensor)

This module implements the power and torque sensor features:

- Transmit power-only main data page (0x10).
- Transmit torque at wheel main data page (0x11).
- Transmit torque at crank main data page (0x12).
- Transmit manufacturer and product information (ANT+ common data page 0x50, 0x51).
- Confirm a calibration procedure (0x01).

You can configure which type of sensor is implemented: power-only sensor, torque sensor at wheel, or torque sensor at crank.

The following code snippets show how to initialize the profile:

void ant_bpwr_evt_handler(ant_bpwr_profile_t * p_profile, ant_bpwr_evt_t event);
void ant_bpwr_calib_handler(ant_bpwr_profile_t * p_profile, ant_bpwr_page1_data_t * p_page1);
BPWR_SENS_CHANNEL_CONFIG_DEF(m_ant_bpwr,
BPWR_CHANNEL_NUMBER,
CHAN_ID_TRANS_TYPE,
CHAN_ID_DEV_NUM,
ANTPLUS_NETWORK_NUMBER);
BPWR_SENS_PROFILE_CONFIG_DEF(m_ant_bpwr,
(ant_bpwr_torque_t)(SENSOR_TYPE),
ant_bpwr_calib_handler,
ant_bpwr_evt_handler);
ant_bpwr_profile_t m_ant_bpwr;
uint32_t err_code;
err_code = ant_bpwr_sens_init(&m_ant_bpwr,
BPWR_SENS_CHANNEL_CONFIG(m_ant_bpwr),
BPWR_SENS_PROFILE_CONFIG(m_ant_bpwr));
APP_ERROR_CHECK(err_code);
// fill manufacturer's common data page.
m_ant_bpwr.page_80 = ANT_COMMON_page80(BPWR_HW_REVISION,
BPWR_MANUFACTURER_ID,
BPWR_MODEL_NUMBER);
// fill product's common data page.
m_ant_bpwr.page_81 = ANT_COMMON_page81(BPWR_SW_REVISION_MAJOR,
BPWR_SW_REVISION_MINOR,
BPWR_SERIAL_NUMBER);
m_ant_bpwr.BPWR_PROFILE_auto_zero_status = ANT_BPWR_AUTO_ZERO_OFF;
err_code = ant_bpwr_sens_open(&m_ant_bpwr);
APP_ERROR_CHECK(err_code);
err_code = ant_state_indicator_channel_opened();
APP_ERROR_CHECK(err_code);

The following snippet shows how to propagate ANT events to the profile's event handler:

void ant_evt_dispatch(ant_evt_t * p_ant_evt)
{
ant_bpwr_sens_evt_handler(&m_ant_bpwr, p_ant_evt);
ant_state_indicator_evt_handler(p_ant_evt);
}

The following snippet shows how to handle calibration request:

void ant_bpwr_calib_handler(ant_bpwr_profile_t * p_profile, ant_bpwr_page1_data_t * p_page1)
{
switch (p_page1->calibration_id)
{
case ANT_BPWR_CALIB_ID_MANUAL:
m_ant_bpwr.BPWR_PROFILE_calibration_id = ANT_BPWR_CALIB_ID_MANUAL_SUCCESS;
m_ant_bpwr.BPWR_PROFILE_general_calib_data = CALIBRATION_DATA;
break;
case ANT_BPWR_CALIB_ID_AUTO:
m_ant_bpwr.BPWR_PROFILE_calibration_id = ANT_BPWR_CALIB_ID_MANUAL_SUCCESS;
m_ant_bpwr.BPWR_PROFILE_auto_zero_status = p_page1->auto_zero_status;
m_ant_bpwr.BPWR_PROFILE_general_calib_data = CALIBRATION_DATA;
break;
case ANT_BPWR_CALIB_ID_CUSTOM_REQ:
m_ant_bpwr.BPWR_PROFILE_calibration_id = ANT_BPWR_CALIB_ID_CUSTOM_REQ_SUCCESS;
memcpy(m_ant_bpwr.BPWR_PROFILE_custom_calib_data, p_page1->data.custom_calib,
sizeof (m_ant_bpwr.BPWR_PROFILE_custom_calib_data));
break;
case ANT_BPWR_CALIB_ID_CUSTOM_UPDATE:
m_ant_bpwr.BPWR_PROFILE_calibration_id = ANT_BPWR_CALIB_ID_CUSTOM_UPDATE_SUCCESS;
memcpy(m_ant_bpwr.BPWR_PROFILE_custom_calib_data, p_page1->data.custom_calib,
sizeof (m_ant_bpwr.BPWR_PROFILE_custom_calib_data));
break;
default:
break;
}
}

After opening the profile instance channel, the module broadcasts the data from the profile structure. The user application should keep this structure updated.

The sample application that uses the Bicycle Power Profile to implement a sensor is available here: Sensor

Note
  The application must propagate ANT stack events to the ANT Bicycle Power module by calling ant_bpwr_sensor_evt_handle() or ant_bpwr_display_evt_handle() from the ant_event_handler callback.

Warning
  The ant_event_handler is called from an interrupt. Therefore, the profile structure is changed asynchronously.