Implementation#
Silicon Labs provides five examples to demonstrate this feature, one for every NLC Profile (except the Energy Monitor NLC Profile). All the examples and their main functionality logics are detailed below.
Bluetooth Mesh - NLC Basic Lightness Controller#
btmesh_soc_nlc_basic_lightness_controller - This is an example of a Bluetooth Mesh application providing the functionality of the Basic Lightness Controller NLC Profile. It demonstrates how to control a light source, an LED mounted on a mainboard, and a radio board or similar hardware, connected to a Bluetooth Mesh network. The light source lightness can be controlled with a Generic Level Client, e.g. another radio board running the Bluetooth Mesh - NLC Dimming Control application, or with Bluetooth Mesh smartphone application.
The device listens to messages from other NLC devices, namely Occupancy Sensor, Ambient Light Sensor, Dimming Control, and Basic Scene Selector nodes. Only a very simple implementation is needed on the application level.
/*******************************************************************************
* Callback for setting Light Lightness by PWM level (0x0001 - FFFE)
******************************************************************************/
void sl_btmesh_lighting_level_pwm_cb(uint16_t level)
{
app_led_set_level(level);
}
/*******************************************************************************
* Callback for setting Light Color by PWM level (0x0001 - FFFE)
******************************************************************************/
void sl_btmesh_lighting_color_pwm_cb(uint16_t color)
{
app_led_set_color(color);
}Bluetooth Mesh - NLC Basic Scene Selector#
btmesh_soc_nlc_basic_scene_selector - This is an example of a Low Power Node-enabled Bluetooth Mesh application providing the functionality of the Basic Scene Selector NLC Profile. Once the node is provisioned and a Basic Lightness Controller subscribes to the client, the two buttons of the mainboard are used to publish the messages that will recall stored scenes on the server. The example provides this recall functionality for scenes #1 and #2. The scene store functionality is provided by the mobile application.
Push Button presses control Basic Lightness Controllers in the network by scene recall requests. This requires the scene selection logic to be implemented in the button handler function.
/*******************************************************************************
* Button press Callbacks
******************************************************************************/
void app_button_press_cb(uint8_t button, uint8_t duration)
{
(void)duration;
char scene[SCENE_BUF_LEN];
#if SL_SIMPLE_BUTTON_COUNT == 1
if (button == BUTTON_PRESS_BUTTON_0) {
// Switch between scene 1 and 2
current_scene = current_scene == 1 ? 2 : 1;
sl_btmesh_select_scene(current_scene);
}
#endif
#if SL_SIMPLE_BUTTON_COUNT >= 2
// Select scene by pushed button
current_scene = button == BUTTON_PRESS_BUTTON_0 ? 1 : 2;
sl_btmesh_select_scene(current_scene);
#endif
// Create unique device name using the last two bytes of the device UUID
snprintf(scene, SCENE_BUF_LEN, "Selected scene: %d", current_scene);
lcd_print(scene, SL_BTMESH_WSTK_LCD_ROW_CURRENT_SCENE_CFG_VAL);
}Bluetooth Mesh - NLC Dimming Control#
btmesh_soc_nlc_dimming_control - This is an example of a Low Power Node-enabled Bluetooth Mesh application providing the functionality of the Dimming Control NLC Profile. Once the node is provisioned and a Basic Lightness Controller subscribes to the client, the two buttons of the mainboard are used to publish the messages that will change the state of the Basic Lightness Controller node.
Buttons can control the following models:
Generic On/Off Client model can turn the light on and off or toggle
Generic Level Client model can control the light brightness
Push Button presses control Basic Lightness Controllers in the network by Generic Level Delta or Generic On/Off messages. A slightly more complex logic is needed for the dimming in the button handler function.
/*******************************************************************************
* Button press Callbacks
******************************************************************************/
void app_button_press_cb(uint8_t button, uint8_t duration)
{
#if SL_SIMPLE_BUTTON_COUNT == 1
if (button == BUTTON_PRESS_BUTTON_0) {
switch (duration) {
// Handling of button press less than 0.25s
case APP_BUTTON_PRESS_DURATION_SHORT: {
sl_btmesh_generic_level_client_ext_delta_set_unack(delta);
} break;
// Handling of button press greater than 0.25s and less than 1s
case APP_BUTTON_PRESS_DURATION_MEDIUM: {
sl_btmesh_generic_level_client_ext_delta_set_unack(-delta);
} break;
// Handling of button press greater than 1s
case APP_BUTTON_PRESS_DURATION_LONG:
case APP_BUTTON_PRESS_DURATION_VERYLONG: {
sl_btmesh_change_switch_position(SL_BTMESH_LIGHTING_CLIENT_TOGGLE);
} break;
default:
break;
}
}
#endif
#if SL_SIMPLE_BUTTON_COUNT >= 2
// Selecting action by duration
switch (duration) {
// Handling of button press less than 0.25s
case APP_BUTTON_PRESS_DURATION_SHORT: {
int32_t delta_set;
delta_set = button == BUTTON_PRESS_BUTTON_0 ? -delta : delta;
sl_btmesh_generic_level_client_ext_delta_set_unack(delta_set);
break;
}
// Anything more than 0.25s
case APP_BUTTON_PRESS_DURATION_MEDIUM:
case APP_BUTTON_PRESS_DURATION_LONG:
case APP_BUTTON_PRESS_DURATION_VERYLONG: {
uint8_t on_off = button == BUTTON_PRESS_BUTTON_0 ? SL_BTMESH_LIGHTING_CLIENT_OFF : SL_BTMESH_LIGHTING_CLIENT_ON;
sl_btmesh_change_switch_position(on_off);
break;
}
default:
break;
}
#endif
}Bluetooth Mesh - NLC Ambient Light Sensor#
btmesh_soc_nlc_sensor_ambient_light - This example makes ambient light sensor measurements and forwards them to another node implementing the Basic Lightness Controller NLC Profile.
The device measures ambient light and sends these measurements to the network. Properly configured NLC Basic Lightness Controllers then can act on the received data. This example contains a Mock sensor logic in the button handler, in case there is no actual light sensor present on the board, thus revealing a possible logic to implement.
/*******************************************************************************
* Callback for button press
******************************************************************************/
void app_button_press_cb(uint8_t button, uint8_t duration)
{
#if defined(SL_CATALOG_SENSOR_LIGHT_LUX_MOCK_PRESENT)
float uvi;
float lux;
sl_status_t sc;
sc = sl_sensor_light_get(&lux, &uvi);
app_assert_status_f(sc, "Failed to get lux and uvi");
#if (SL_SIMPLE_BUTTON_COUNT >= 2)
// button pressed
if (duration == APP_BUTTON_PRESS_DURATION_SHORT) {
if (button == BUTTON_PRESS_BUTTON_0) {
app_log("PB0 pressed" APP_LOG_NL);
sl_sensor_light_set(lux - LUX_SMALL_CHANGE, uvi);
} else if (button == BUTTON_PRESS_BUTTON_1) {
app_log("PB1 pressed" APP_LOG_NL);
sl_sensor_light_set(lux + LUX_SMALL_CHANGE, uvi);
}
} else if (duration == APP_BUTTON_PRESS_DURATION_MEDIUM) {
if (button == BUTTON_PRESS_BUTTON_0) {
app_log("PB0 medium pressed" APP_LOG_NL);
sl_sensor_light_set(lux - LUX_LARGE_CHANGE, uvi);
} else if (button == BUTTON_PRESS_BUTTON_1) {
app_log("PB1 medium pressed" APP_LOG_NL);
sl_sensor_light_set(lux + LUX_LARGE_CHANGE, uvi);
}
}
#elif (SL_SIMPLE_BUTTON_COUNT == 1)
(void)duration;
if (button == BUTTON_PRESS_BUTTON_0) {
app_log("PB0 pressed" APP_LOG_NL);
sl_sensor_light_set(lux + LUX_LARGE_CHANGE, uvi);
}
#endif // SL_SIMPLE_BUTTON_COUNT
#else
(void)duration;
(void)button;
#endif // SL_CATALOG_SENSOR_LIGHT_MOCK_PRESENT
}Bluetooth Mesh - NLC Occupancy Sensor#
btmesh_soc_nlc_sensor_occupancy – This example makes Occupancy Sensor measurements and forwards them to another node implementing the Basic Lightness Controller NLC Profile. This measurement can be faked by pressing the buttons on the mainboard:
BTN1 increases people count
BTN0 decreases people count
In case of only one button, a shorter press increases, while a longer one decreases the people count.
Push Button presses imitate people count changes which can control a properly configured NLC Basic Lightness Controller. Here as well, buttons simulate the increase/decrease of people, implemented in the button press handler function.
/*******************************************************************************
* Callback for button press
******************************************************************************/
void app_button_press_cb(uint8_t button, uint8_t duration)
{
(void)duration;
// button pressed
if (duration == APP_BUTTON_PRESS_DURATION_SHORT) {
if (button == BUTTON_PRESS_BUTTON_0) {
app_log("PB0 pressed" APP_LOG_NL);
sl_btmesh_people_count_decrease();
} else if (button == BUTTON_PRESS_BUTTON_1) {
app_log("PB1 pressed" APP_LOG_NL);
sl_btmesh_people_count_increase();
}
} else if (duration == APP_BUTTON_PRESS_DURATION_MEDIUM) {
if ( (button == BUTTON_PRESS_BUTTON_0)) {
app_log("PB0 medium pressed" APP_LOG_NL);
sl_btmesh_people_count_increase();
}
}
}