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

How to send data from the central to multiple peripherals?

Hello everybody !

My code is based on the code of the "ble_app_multilink_central" on which, I added some of the code "ble_app_uart_c" for the initialization and the event manager on the uart. I have a nrf52832 development board as a central and 2 rf52832 developpemtn boards as a peripheral. Each peripheral consists of 4 characteristics.

I am currently using the following code to be able to manage by my PC the connection between the central and the peripherals :

void uart_event_handle(app_uart_evt_t * p_event)
{
    static uint8_t data_array[30];
    static uint16_t index = 0;
    uint32_t ret_val;

    static char const start[] = "1";
    static char const acquisition[] = "2";
    static char const disconnect[] = "3";
    
    UNUSED_VARIABLE(app_uart_get(&data_array[index]));

    if (memcmp(start, data_array, sizeof(start)) == 0){
           //printf("start");
           scan_start();
    }
    if (memcmp(acquisition, data_array, sizeof(acquisition)) == 0){
           //function to acquire values "characteristic"
           printf("LEDdebug");
           bsp_board_led_invert(LEDTEST);
    }
    if (memcmp(disconnect, data_array, sizeof(disconnect)) == 0){
           //stop function BLE
           printf("disconnect");
           sd_ble_gap_disconnect(numconn_handle1,BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
           sd_ble_gap_disconnect(numconn_handle2,BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
    }
data_array[index] = 0;
}

In my uart event handle, I created several commands that I manage from my PC.
For example by pressing "1", I start scanning, and "3" i disconnect the link between central and peripherals.

My goal is to add a function by pressing, for example "2", writing the message "0x01"  on a feature of each peripheral, which could for example be interpreted by my 2 devices by "change status of one of their LED.

What does my peripheral do when you write about one of its values :

static void on_write(ble_cus_t * p_cus, ble_evt_t const * p_ble_evt)
{
    ble_gatts_evt_write_t const * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
    
    // Custom Value Characteristic Written to.
    if (p_evt_write->handle == p_cus->custom_value_handles.value_handle)
    {
        if(*p_evt_write->data == 0x01)
        {
            nrf_gpio_pin_toggle(LED_4); 
        }
        else
        {
          //Do nothing
        }
    }
}

Thank you in advance for your assistance !

Parents
  • Hi,

    I suggest that you look at the ble_nus_c_string_send() function that is being used in the BLE NUS central example. That function uses sd_ble_gattc_write() to write data to a peripheral.

  • Hmm ... yes it seems like a good idea. I had just thought of that. But the problem is that I currently have a problem I would like to write on a single characteristics and if we look good on the code:

    uint32_t ble_nus_c_string_send(ble_nus_c_t * p_ble_nus_c, uint8_t * p_string, uint16_t length)
    {
        VERIFY_PARAM_NOT_NULL(p_ble_nus_c);
    
        if (length > BLE_NUS_MAX_DATA_LEN)
        {
            NRF_LOG_WARNING("Content too long.");
            return NRF_ERROR_INVALID_PARAM;
        }
        if (p_ble_nus_c->conn_handle == BLE_CONN_HANDLE_INVALID)
        {
            NRF_LOG_WARNING("Connection handle invalid.");
            return NRF_ERROR_INVALID_STATE;
        }
    
        ble_gattc_write_params_t const write_params =
        {
            .write_op = BLE_GATT_OP_WRITE_CMD,
            .flags    = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE,
            .handle   = p_ble_nus_c->handles.nus_rx_handle,
            .offset   = 0,
            .len      = length,
            .p_value  = p_string
        };
    
        return sd_ble_gattc_write(p_ble_nus_c->conn_handle, &write_params);
    }

    write_params needs the handle of characteristic ("handles.nus_rx_handle" in ble_nus" so to find.

    So to find this handle I have to discover the service and these characteristics with such a decourverte there?

    void ble_nus_c_on_db_disc_evt(ble_nus_c_t * p_ble_nus_c, ble_db_discovery_evt_t * p_evt)
    {
        ble_nus_c_evt_t nus_c_evt;
        memset(&nus_c_evt,0,sizeof(ble_nus_c_evt_t));
    
        ble_gatt_db_char_t * p_chars = p_evt->params.discovered_db.charateristics;
    
        // Check if the NUS was discovered.
        if (    (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE)
            &&  (p_evt->params.discovered_db.srv_uuid.uuid == BLE_UUID_NUS_SERVICE)
            &&  (p_evt->params.discovered_db.srv_uuid.type == p_ble_nus_c->uuid_type))
        {
            for (uint32_t i = 0; i < p_evt->params.discovered_db.char_count; i++)
            {
                switch (p_chars[i].characteristic.uuid.uuid)
                {
                    case BLE_UUID_NUS_RX_CHARACTERISTIC:
                        nus_c_evt.handles.nus_rx_handle = p_chars[i].characteristic.handle_value;
                        break;
    
                    case BLE_UUID_NUS_TX_CHARACTERISTIC:
                        nus_c_evt.handles.nus_tx_handle = p_chars[i].characteristic.handle_value;
                        nus_c_evt.handles.nus_tx_cccd_handle = p_chars[i].cccd_handle;
                        break;
    
                    default:
                        break;
                }
            }
            if (p_ble_nus_c->evt_handler != NULL)
            {
                nus_c_evt.conn_handle = p_evt->conn_handle;
                nus_c_evt.evt_type    = BLE_NUS_C_EVT_DISCOVERY_COMPLETE;
                p_ble_nus_c->evt_handler(p_ble_nus_c, &nus_c_evt);
            }
        }
    }

    Thank you in any case for your answer ! Slight smile

  • Yes, that is correct. You need to get hold of the handle in ble_nus_c_on_db_disc_evt(), and then use that handle in ble_nus_c_string_send() later on. 

Reply Children
No Data
Related