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

Large data transfer over ble.

Hi,

I would like to have a system such as follows:

  • Taking sensor data storing it locally till around 100 samples (Once per second)
  • Log this data to the SD with a time stamp
  • Then storing this data to an external SD card. (Utilising the fatfs example code in the SDK) Around  2 Mbytes
  • I then want a mobile device to request this data.

What therefore, is the best way of transferring the data from the SD card to BLE to be picked up by the mobile application.

Do I need to set up a GATT connection and wait on a notification change that I set in the Nordic board?

If so is there an example of this or a good starting point.

Would this post be a good starting point? : https://devzone.nordicsemi.com/f/nordic-q-a/553/dealing-large-data-packet-s-through-ble

If so what example is good to work from. Thanks

  • Hi

    Errors from the sd_ble_gap_adv_start should be returning an error message, like NRF_ERROR_INVALID_STATE, etc. These can be seen in ble_gap.h in C:\nordicsemi\SDK\nRF5_SDK_16.0.0_98a08e2\components\softdevice\s132\headers\ble_gap.h. I suggest you use the same advertising init function as in one of the examples already using connections in order to set up a "default" advertising that we know works.

    Do you want something like a service (for example the battery value) that updates between each advertisement as part of your advertising packet? To do so, you will likely have to use scan response packets, as the size of the advertisement itself is rather limited. You will then have to enable service data in both the advertisement packet and the scan response packet. You can check out this case and the guide Joakim links to for more information on how to use scan response packets.

    Best regards,

    Simon

  • Hi Simon,

    Basically the app functionality I want is this:

    • Read sensor data which, in previous code uses RTT and UART(Working on other project)
    • Store this sensor data to an external SD (not yet done)
    • Output once per second an advertisement with the sensor data within the advertisement packet
    • Be able to receive connections from a ble application to:
      • Set the time
      • Request logged data from the board via sd card

    Also I am using s140 p10056

    I am now using the gatt example. I have got a fixed advertisement using the app_adv.c and passing in my fixed variables for the advertisement packet. Now I want to have this data update every second from data comming inform the UART.

    My first question is how do I update this? Below is my code

    main:

    int main(void)
    {
        //Int values
        T1_data_1 = 0;T1_data_2 = 0;T2_data_1 = 0;T2_data_2 = 0;T3_data_1 = 0;
        T3_data_2 = 0;P1_data_1 = 0;P1_data_2 = 0;P2_data_1 = 0;P2_data_2 = 0;
        // Initialize.
        modules_init();
    
        // Start execution.
        NRF_LOG_INFO("GATT Service client started.");
        advertising_start(m_erase_bonds);
    
        // Enter main loop.
      
        counter++;//Int value
        advertising_update(counter,T1_data_1,T2_data_1,00,00,70,80,70,80);
        for (;;)
        {
            idle_state_handle();
        }
        
    }

    Advertising Init:

    void advertising_init(void)
    {
        ret_code_t             err_code;
        ble_advertising_init_t init;
    
        memset(&init, 0, sizeof(init));
        //Manufacturer data
        ble_advdata_manuf_data_t                  manuf_data; //Variable to hold manufacturer specific data
        uint8_t data[]                            = "test"; //Our data to advertise
       
        manuf_data.company_identifier             =  0x0487; //Centricas company ID
        manuf_data.data.p_data                    = m_beacon_info;
        //manuf_data.data.p_data                    = data;
        //manuf_data.data.size = sizeof((uint8_t *) m_beacon_info);
        //manuf_data.data.size                      = sizeof(data);
        manuf_data.data.size                      = 11;
        
        init.advdata.p_manuf_specific_data = &manuf_data;
        //
    
        init.advdata.name_type            = BLE_ADVDATA_FULL_NAME;
        //init.advdata.short_name_len = 6; // Advertise only first 6 letters of name
        init.advdata.include_appearance   = true;
        init.advdata.flags                = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
        
    
        init.config.ble_adv_fast_enabled  = true;
        init.config.ble_adv_fast_interval = ADV_INTERVAL;
        init.config.ble_adv_fast_timeout  = APP_ADV_DURATION;
    
        init.evt_handler = on_adv_evt;
    
        err_code = ble_advertising_init(&m_advertising, &init);
        APP_ERROR_CHECK(err_code);
    
        ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);
    }

    Finally my update code:

    When this code is run it goes to app error weak. I cant trace the error from debugging the error handler though. I happens after init.evt_handler = on_adv_evt;

    void advertising_update(int count, int T1_value,int T2_value,
                                           int t3_value_1,int t3_value_2, int p1_value_1, int p1_value_2,
                                           int p2_value_1,int p2_value_2)
    {
        ret_code_t             err_code;
        ble_advertising_init_t init;
    
        int t1_value_1 = (T1_value >>8) & 0XFF;//MSB shifting
        int t1_value_2 = T1_value & 0XFF;//LSB
    
        int t2_value_1 = (T2_value >> 8) & 0XFF;//MSB
        int t2_value_2 = T2_value & 0XFF;//LSB
    
        m_beacon_info[0]=(unsigned char) count;
        m_beacon_info[1]=(unsigned char) t1_value_1;
        m_beacon_info[2]=(unsigned char) t1_value_2;
        m_beacon_info[3]=(unsigned char) t2_value_1;
        m_beacon_info[4]=(unsigned char) t2_value_2;
        m_beacon_info[5]=(unsigned char) t3_value_1;
        m_beacon_info[6]=(unsigned char) t3_value_2;
        m_beacon_info[7]=(unsigned char) p1_value_1;
        m_beacon_info[8]=(unsigned char) p1_value_2;
        m_beacon_info[9]=(unsigned char) p2_value_1;
        m_beacon_info[10]=(unsigned char) p2_value_2;
    
        memset(&init, 0, sizeof(init));
        //Manufacturer data
        ble_advdata_manuf_data_t                  manuf_data; //Variable to hold manufacturer specific data
     
        manuf_data.company_identifier             =  0x0487; //Centricas company ID
        manuf_data.data.p_data                    = m_beacon_info;
        
        manuf_data.data.size                      = 11;
        
        init.advdata.p_manuf_specific_data = &manuf_data;
    
        init.advdata.name_type            = BLE_ADVDATA_FULL_NAME;
        //init.advdata.short_name_len = 6; // Advertise only first 6 letters of name
        init.advdata.include_appearance   = true;
        init.advdata.flags                = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
        
        init.config.ble_adv_fast_enabled  = true;
        init.config.ble_adv_fast_interval = ADV_INTERVAL;
        init.config.ble_adv_fast_timeout  = APP_ADV_DURATION;
    
        init.evt_handler = on_adv_evt;
    
        err_code = ble_advertising_init(&m_advertising, &init);
        APP_ERROR_CHECK(err_code);   
    
        ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);
    }
    

    Thanks,

    Thomas

  • Hi Thomas

    Okay, thank you for explaining what you want to do. I urge you to check out the sd_ble_gap_adv_set_configure function on line 1887 in ble_gap.h at C:\nordicsemi\SDK\nRF5_SDK_16.0.0_98a08e2\components\softdevice\s140\headers\ where configuring an additional advertising set is described. In order to update advertising data while advertising, new advertising buffers must be provided, as you can't change the one you're using while advertising, which is likely what causes the error.

    So you'll have to alternate between what advertising buffer you're updating each time in order to keep up a continuous advertisement.

    Best regards,

    Simon

  • Ok I'll have a look.

    But the old way I did it was start an ad then stop and start another. I presume the : SVCALL(SD_BLE_GAP_ADV_SET_CONFIGURE, uint32_t, sd_ble_gap_adv_set_configure(uint8_t *p_adv_handle, ble_gap_adv_data_t const *p_adv_data, ble_gap_adv_params_t const *p_adv_params));

    Is used to update it rather than stop and start it again.

  • Also is there any example code where this is used?

Related