NAV Navbar

WICED CYW920819EVB-02 BLE_MESH_Light_Dimmable

This document shows a simple implementation of a dimmable light. The app is based on the snip/mesh/mesh_light_lightness sample, which implements BLE Mesh Light Lightness Server Model. The Light lightness Server Model extends Generic OnOff and Generic Level; the dimmable light can be controlled by a switch (Generic OnOff Client), a Dimmer (Generic Level Client), and an application which implements the Light lightness Client. The WICED Mesh Models library takes care of the translation of OnOff and level messages and the application layer processes the messages of the Light lightness Model.

MESH Initialization

Code Snippet (light_dimmable.c):

void mesh_app_init(wiced_bool_t is_provisioned)
{
    mesh_prop_fw_version[0] = 0x30 + (WICED_SDK_MAJOR_VER / 10);
    mesh_prop_fw_version[1] = 0x30 + (WICED_SDK_MAJOR_VER % 10);
    mesh_prop_fw_version[2] = 0x30 + (WICED_SDK_MINOR_VER / 10);
    mesh_prop_fw_version[3] = 0x30 + (WICED_SDK_MINOR_VER % 10);
    mesh_prop_fw_version[4] = 0x30 + (WICED_SDK_REV_NUMBER / 10);
    mesh_prop_fw_version[5] = 0x30 + (WICED_SDK_REV_NUMBER % 10);
    mesh_prop_fw_version[6] = 0x30 + (WICED_SDK_BUILD_NUMBER / 10);
    mesh_prop_fw_version[7] = 0x30 + (WICED_SDK_BUILD_NUMBER % 10);

    led_control_init();

    wiced_init_timer(&attention_timer, attention_timer_cb, 0, 
    WICED_SECONDS_PERIODIC_TIMER);

wiced_bt_mesh_model_light_lightness_server_init(MESH_LIGHT_LIGHTNESS_SERVER_ELEMENT_INDEX, mesh_app_message_handler, is_provisioned);
    wiced_bt_mesh_model_property_server_init(MESH_LIGHT_LIGHTNESS_SERVER_ELEMENT_INDEX, NULL, is_provisioned);
}

This function initializes the MESH functionality, which calls the LED functionality (led_control_init()). The wiced_init_timer() function registers a callback attention_timer_cb(), is executed every second and the alert is sent to the user. The brightness is switched between 0 and 100% here. The application callback wiced_bt_mesh_model_light_lightness_server_init() is executed by the Model Library when it is required to set amount of light emitted to a certain level. It invokes a mesh_app_message_handler() handler function which sets the light brightness level.wiced_bt_mesh_model_property_server_init() is called to initialize property module.

LED Functionality

Code Snippet (led_control.c):

void led_control_init(void)
{
    pwm_config_t pwm_config;

#ifdef CYW20819A1
    wiced_hal_gpio_select_function(WICED_GPIO_PIN_LED_2, WICED_PWM0);
#endif
    wiced_hal_aclk_enable(PWM_INP_CLK_IN_HZ, ACLK1, ACLK_FREQ_24_MHZ);
    wiced_hal_pwm_get_params(PWM_INP_CLK_IN_HZ, 0, PWM_FREQ_IN_HZ, &pwm_config);
    wiced_hal_pwm_start(PWM_CHANNEL, PMU_CLK, pwm_config.toggle_count, pwm_config.init_count, 1);
}

An LED is configured using wiced_hal_gpio_select_function() and performs the PWM operation. wiced_hal_aclk_enable() starts to ACLK the configured GPIO pin. The PWM operation processes using the functions wiced_hal_pwm_get_params() and wiced_hal_pwm_start().

Code Snippet (led_control.c):

void led_control_set_brighness_level(uint8_t brightness_level)
{
    pwm_config_t pwm_config;

    WICED_BT_TRACE("set brightness:%d\n", brightness_level);

        if (brightness_level == 100)
        brightness_level = 99;

    wiced_hal_pwm_get_params(PWM_INP_CLK_IN_HZ, brightness_level, PWM_FREQ_IN_HZ, &pwm_config);
    wiced_hal_pwm_change_values(PWM_CHANNEL, pwm_config.toggle_count, pwm_config.init_count);
}

The LED brightness is controlled using the function led_control_set_brighness_level. WICED PWM functions wiced_hal_pwm_get_params() and wiced_hal_pwm_change_values() carry out these functionality.

Attention Timer Functions

Code Snippet (light_dimmable.c):

    void mesh_app_attention(uint8_t element_idx, uint8_t time)
{
    WICED_BT_TRACE("dimmable light attention:%d sec\n", time);

    if (time == 0)
    {
        wiced_stop_timer(&attention_timer);
        led_control_set_brighness_level(last_known_brightness);
        return;
    }
    wiced_start_timer(&attention_timer, 1);
    attention_time = time;
    attention_brightness = (last_known_brightness != 0) ? 0 : 100;
    led_control_set_brighness_level(attention_brightness);
}

Brightness is set using the function led_control_set_brighness_level(), depending on the time value. If time is set to 0, alerts are stopped and the last known brightness level is restored.

Code Snippet:

void attention_timer_cb(TIMER_PARAM_TYPE arg)
{
    WICED_BT_TRACE("dimmable light attention timeout:%d\n", attention_time);

    if (--attention_time == 0)
    {
        wiced_stop_timer(&attention_timer);
        led_control_set_brighness_level(last_known_brightness);
        return;
    }
    attention_brightness = (attention_brightness == 0) ? 100 : 0;
    led_control_set_brighness_level(attention_brightness);
}

The user is sent alerts when the Attention timer callback is executed; this functionality sets the brightness of the LED.

Message Handler Callback

Code snippet (light_dimmable.c):


void mesh_app_message_handler(uint8_t element_idx, uint16_t event, void *p_data)
{
    switch (event)
    {
    case WICED_BT_MESH_LIGHT_LIGHTNESS_SET:
        mesh_app_process_set_level(element_idx, 
        (wiced_bt_mesh_light_lightness_status_t *)p_data);
        break;

    default:
        WICED_BT_TRACE("dimmable light unknown msg:%d\n", event);
        break;
    }
}

When the server model is initialized, the function mesh_app_message_handler() is called to respond to the event WICED_BT_MESH_LIGHT_LIGHTNESS_SET. The event is received from Models library. A new level is set after the occurrence of this event using mesh_app_process_set_level().

Code Snippet:

void mesh_app_process_set_level(uint8_t element_idx, wiced_bt_mesh_light_lightness_status_t *p_status)
{
    WICED_BT_TRACE("mesh light srv set level element:%d present actual:%d linear:%d remaining_time:%d\n",
        element_idx, p_status->lightness_actual_present, p_status->lightness_linear_present, p_status->remaining_time);

    last_known_brightness = (uint8_t)((uint32_t)p_status->lightness_actual_present * 100 / 65535);
    led_control_set_brighness_level(last_known_brightness);

    wiced_stop_timer(&attention_timer);
}

The led_control_set_brighness_level() function is received from the level client and called when the brightness of the LED is set to a new level.