This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nRF5 SDK for Mesh v2.2.0: Light Switch Demo - Where Next?

So I have successfully built & deployed the Light Switch Demo - and it works.

But where do we go next?

The documentation seems far too close-in focussed on the microscopic details of functions, types, etc - I can't see anything which gives a macroscopic overview of how to create a system.

It's like a car handbook which describes each cog in the gearbox in fine details - but doesn't tell you how to drive the car!

For example, the Server controls just 1 LED on the DK.

How would we expand that to give independent control of all 4 LEDs?

In BT Mesh terminology, I think that would mean making each LED an "Element" ?

So how would we instantiate these - as instances of the Generic On/Off model?

Parents
  • No,  solutions are not much help - they are just "giving a man a fish"

    What we need is proper fishing lessons!

  • Sorry for the delayed response. As it seems you have gone through the light switch demo with a provisioner, a client & a server & read the documentation, I would recommend the following:

    Take a look at the light switch proxy client & proxy server examples & use the video in next link to get acquainted with the nRF Mesh application (iOS & Android).

    Essentially, all you need to do in the app is to bind the appkey to the generic on/off models & set the publish & subscription addresses. This is, in my opinion, the easiest way to get started. 

    Then, I would make a few changes to the proxy client example. I believe the button_event_handler function should look like this out of the box (please correct me if I am wrong, as I may have made changes to this function):

    static void button_event_handler(uint32_t button_number)
    {
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Button %u pressed\n", button_number);
    
        uint32_t status = NRF_SUCCESS;
        generic_onoff_set_params_t set_params;
        model_transition_t transition_params;
        static uint8_t tid = 0;
    
        /* Button 1: ON, Button 2: Off, Client[0]
         * Button 2: ON, Button 3: Off, Client[1]
         */
    
        switch(button_number)
        {
            case 0:
            case 2:
                set_params.on_off = APP_STATE_ON;
                break;
    
            case 1:
            case 3:
                set_params.on_off = APP_STATE_OFF;
                break;
        }
    
        set_params.tid = tid++;
        transition_params.delay_ms = APP_CONFIG_ONOFF_DELAY_MS;
        transition_params.transition_time_ms = APP_CONFIG_ONOFF_TRANSITION_TIME_MS;
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Sending msg: ONOFF SET %d\n", set_params.on_off);
    
        switch (button_number)
        {
            case 0:
            case 1:
                /* Demonstrate acknowledged transaction, using 1st client model instance */
                /* In this examples, users will not be blocked if the model is busy */
                (void)access_model_reliable_cancel(m_clients[0].model_handle);
                status = generic_onoff_client_set(&m_clients[0], &set_params, &transition_params);
                hal_led_pin_set(BSP_LED_0, set_params.on_off);
                break;
    
            case 2:
            case 3:
                /* Demonstrate un-acknowledged transaction, using 2nd client model instance */
                status = generic_onoff_client_set_unack(&m_clients[1], &set_params,
                                                        &transition_params, APP_UNACK_MSG_REPEAT_COUNT);
                hal_led_pin_set(BSP_LED_1, set_params.on_off);
                break;
          }
    
        switch (status)
        {
            case NRF_SUCCESS:
                break;
    
            case NRF_ERROR_NO_MEM:
            case NRF_ERROR_BUSY:
            case NRF_ERROR_INVALID_STATE:
                __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Client %u cannot send\n", button_number);
                hal_led_blink_ms(LEDS_MASK, LED_BLINK_SHORT_INTERVAL_MS, LED_BLINK_CNT_NO_REPLY);
                break;
    
            case NRF_ERROR_INVALID_PARAM:
                /* Publication not enabled for this client. One (or more) of the following is wrong:
                 * - An application key is missing, or there is no application key bound to the model
                 * - The client does not have its publication state set
                 *
                 * It is the provisioner that adds an application key, binds it to the model and sets
                 * the model's publication state.
                 */
                __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Publication not configured for client %u\n", button_number);
                break;
    
            default:
                ERROR_CHECK(status);
                break;
        }
    }
    

    As the documentation states, buttons 1 & 3 are used to turn the app state on, whereas buttons 2 & 4 turn the app state off. Buttons 1 & 2 then send an acknowledged message to the servers, whereas 3&4 send an un-acknowledged message. I would recommend taking a look at the button_event_handler function from mesh sdk v2.1.1 if you want to send group messages to a specific group:

    static void button_event_handler(uint32_t button_number)
    {
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Button %u pressed\n", button_number);
    
        uint32_t status = NRF_SUCCESS;
        switch (button_number)
        {
            case 0:
            case 1:
                /* send unicast message, with inverted GPIO pin value */
                status = simple_on_off_client_set(&m_clients[button_number],
                                                  !hal_led_pin_get(BSP_LED_0 + button_number));
                break;
    
            case 2:
            case 3:
                /* send a group message to the ODD group, with inverted GPIO pin value */
                status = simple_on_off_client_set_unreliable(&m_clients[button_number],
                                                             !hal_led_pin_get(BSP_LED_0 + button_number),
                                                             GROUP_MSG_REPEAT_COUNT);
                if (status == NRF_SUCCESS)
                {
                    hal_led_pin_set(BSP_LED_0 + button_number, !hal_led_pin_get(BSP_LED_0 + button_number));
                }
                break;
            default:
                break;
        }
    
        switch (status)
        {
            case NRF_SUCCESS:
                break;
    
            case NRF_ERROR_NO_MEM:
            case NRF_ERROR_BUSY:
            case NRF_ERROR_INVALID_STATE:
                __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Cannot send - client %u is busy\n", button_number);
                hal_led_blink_ms(LEDS_MASK, LED_BLINK_SHORT_INTERVAL_MS, LED_BLINK_CNT_NO_REPLY);
                break;
    
            case NRF_ERROR_INVALID_PARAM:
                /* Publication not enabled for this client. One (or more) of the following is wrong:
                 * - An application key is missing, or there is no application key bound to the model
                 * - The client does not have its publication state set
                 *
                 * It is the provisioner that adds an application key, binds it to the model and sets
                 * the model's publication state.
                 */
                __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Publication not configured for client %u\n", button_number);
                break;
    
            default:
                ERROR_CHECK(status);
                break;
        }
    }

    I have another case here which could be interesting to see.

     

    How would we expand that to give independent control of all 4 LEDs?

    In BT Mesh terminology, I think that would mean making each LED an "Element" ?

    So how would we instantiate these - as instances of the Generic On/Off model?

    I am working on an example that will be able to use multiple LEDs on a server. Currently, I still have a few issues that I am trying to iron out, but I will let you know when I am done.

    Kind Regards,

    Bjørn

  • Thanks for all that

    I am working on an example that will be able to use multiple LEDs on a server.

    am I on the right lines of these being separate "Elements" in the BT Mesh lingo?

  • Yes, an element is essentially a controllable part of the device. So each LED would be a different element.

Reply Children
  • I realize this is 4 months too late, but better late than never. I have created an example showing how you can create two generic on off server models with one element each. That way, it is possible to provision & configure the server example from the nRF Mesh smartphone app & control the LEDs 1 & 2 from the app itself. Unfortunately, there is a bug at the moment in the iOS app, which means that the state set message only gets sent to the first on off server unicast address & never to the second one.

    However, this works fine with the Android nRF Mesh app.

    I made a copy of the generic on off server light switch example from mesh sdk v3.1.0. The main changes were the following:

    - increased the ACCESS_MODEL_COUNT & ACCESS_ELEMENT_COUNT by one since I have added an extra element. The ACCESS_SUBSCRIPTION_LIST_COUNT has also been increased by one. All of these defines are found in nrf_mesh_config_app.h.

    - in main.c, I added another APP_ONOFF_SERVER_DEF() for the second on off server model

    - also changed the app_onoff_server_set_cb() to either change the LED state of LED 0 or LED 1 depending on which server model state is changed

    - app_model_init() has also been updated to initialize two generic on off models instead of one.

    I have added a comment //added by BK behind each line I have changed, so it should be easy to make search for the different changes.

    In nRF Mesh, just provision & configure the node similar to this Youtube video, find the first server model, bind the app key & then change the state at the bottom of the same window. The same procedure applies for the second on off server model.

    I would recommend to run a debug session by pressing F5 to get additional logging info in SES.

    Unfortunately, I was unable to upload the zip file to DevZone, but I found a workaround. I have only tested on a 52832 DK.

    Just unzip the folder like this: nrf5_SDK_for_Mesh_v3.1.0_src\examples\light_switch\server_4_generic_on_off

    It should then look similar to this:

  • Thanks - I will have to find some time to look at it again!

Related