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

    I believe the ble_app_pwr_profiling example uses the sd_ble_gap_adv_set_configure function in order to set up two different advertising buffers, however, we don't have an example for updating advertising data regularly like you want to.

    Best regards,

    Simon

  • Hi Simon,

    I have looked through the ble_app_pwr_profiling example. I have gotten it to work with my advertising that updates once per second from data coming in via UART.

    However, whilst this works. Using the nordic semi conductor app (NRF connect). The device comes up with the live data and a connection is available.

    The way my code works at the moment is as follows:

    • init the advert via button press (connectable)
    • Wait for UART string data (received once per second)
    • Update the advert (Run advertising_mod function see below)
    • Loop

    Then when press connect nothing is populated within the services menu also, I am chucking the data out to a RTT viewer. When I press connect I stop my live advertising Via a boolean that is set from the ble_evt_handler connected state. Then I can see the services. But, when I disconnect I get fatal error.

    This runs from BLE_GATTS_EVT_TIMEOUT APP 

    Advertising Mod: Note m_beacon is just for storing my data values inside of.

    static void advertising_mod(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)
    {
        uint32_t      err_code;
        ble_advdata_t advdata;
        uint8_t       flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;
        
        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
    
        ble_advdata_manuf_data_t manuf_specific_data;
        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;
       
        manuf_specific_data.company_identifier = COMPANY_IDENTIFIER;
        manuf_specific_data.data.p_data = (uint8_t *) m_beacon_info;
        manuf_specific_data.data.size   = APP_BEACON_INFO_LENGTH;
    
        // Build and set advertising data.
        memset(&advdata, 0, sizeof(advdata));
    
        advdata.name_type             = BLE_ADVDATA_NO_NAME;
        advdata.flags                 = flags;
        advdata.p_manuf_specific_data = &manuf_specific_data;
    
        // Initialize advertising parameters (used when starting advertising).
        memset(&m_adv_params, 0, sizeof(m_adv_params));
    
        m_adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
        //m_adv_params.properties.type = BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED;
        m_adv_params.p_peer_addr     = NULL;    // Undirected advertisement.
        m_adv_params.filter_policy   = BLE_GAP_ADV_FP_ANY;
        m_adv_params.interval        = CONNECTABLE_ADV_INTERVAL;
        m_adv_params.duration        = APP_ADV_DURATION;       // 30 Second adverts
        m_adv_params.primary_phy     = BLE_GAP_PHY_1MBPS;
    
        err_code = ble_advdata_encode(&advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_data.len);
        APP_ERROR_CHECK(err_code);
    
        err_code = sd_ble_gap_adv_stop(m_adv_handle);
        APP_ERROR_CHECK(err_code);
    
        err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &m_adv_params);
        APP_ERROR_CHECK(err_code);
    
        err_code = sd_ble_gap_adv_start(m_adv_handle, APP_BLE_CONN_CFG_TAG);
        APP_ERROR_CHECK(err_code);
    }

    The error comes from err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle,
    BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);

    But, I am not sure why.

    Thanks,

    Thomas

  • Hi Thomas

    Thomas said:
    Then when press connect nothing is populated within the services menu also, I am chucking the data out to a RTT viewer. When I press connect I stop my live advertising Via a boolean that is set from the ble_evt_handler connected state. Then I can see the services.

    I'm not entirely sure what you mean here. Do you have to press connect twice for the device to connect to your central properly? The fact that it stops advertising when you connect makes sense, as it is connecting and won't be able to advertise during that process, as the nRF52 series only has one radio.

    As for the disconnect you are seeing, BLE_GATTS_EVT_TIMEOUT means that a peer failed to respond to an ATT request in time, and that makes the central disconnect from your peripheral. So somewhere your peripheral is ignoring an ATT request from the central which causes this disconnect. You can see ble_gatts_evt_timeout_t for more information on this disconnect reason.

    Best regards,

    Simon

  • Hi Simon,

    Sorry the confusion let me clarify.

    I can advertise whilst no connection is active and have changing adverts that works fine.

    Then from the main NRF connect screen when I see the list of devices I have the option to connect to the device as you would expect. From there I can see the services with the device. 

    However, when I then disconnect from this my advert does not come back and I get the aforementioned fatal error.

    I want my advertising to restart on a disconnect. I am not sure why this is not the case.

    In my main code I have the following:

     while (true)
        {
            if(GATT_CONNECTED == false)
            {
              // Get next gyte from FIFO
              while (app_uart_get(&c) != NRF_SUCCESS);
              string[pos] = c;
    
              // Assume that all strings end with \n. If end, print and start over.
              if (string[pos] == '\n')
              {
                  string[pos+1] = '\0';
                  NRF_LOG_INFO("Received string: \"%s\"", string);
                  sscanf( string, "%*d , %d , %*d , %d ", &T1_data_1,&T2_data_1);
                  NRF_LOG_INFO("T1 is:\"%d\"", T1_data_1);
                  NRF_LOG_INFO("T2 is:\"%d\"", T2_data_1);
                  pos = 0;
                  counter++;
                  idle_state_handle();
                  data_changed = true;
                  //converted_number =  toBinary(T1_data_1);
                  if(data_changed==true)
                  {
                    advertising_mod(counter,T1_data_1,T2_data_1,00,00,70,80,70,80);//Only have two temperature sensors
                    data_changed = false;
                  }
              }
              else
              {
                  pos++;
                
              }
           }
           else// GATT_CONNECTED = true
           {
               idle_state_handle();
           }
        }

    GATT_CONNECTED is a boolean I have created. I set this to true in the ble_evt_handler within the case BLE_GAP_EVT_CONNECTED case. And I also set it to false on the disconnected case.

    I am not sure why the advert itself does not restart. Note I am using a modified ble_app_pwr_profiling example.

  • Hi Thomas

    Seeing as you're using the ble_app_pwr_profiling example, how are you handling the BLE_GAP_EVT_DISCONNECTED in your ble_evt_handler? By default, the ble_app_pwr_profiling example is handling it by going to system OFF mode upon a disconnection, which might be why your device doesn't start advertising upon a disconnect. Try handling the disconnect event like the ble_app_uart example does, as that example does start advertising automatically upon a disconnect.

    Best regards,

    Simon

Related