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

Storing adv data

Hi. My application is scanning ble beacons for 1 sec every minute, and I want to store this data in an array to be sent every 10 min. I am getting the data in BLE_GAP_EVT_ADV_REPORT in p_ble_evt->header.evt_id, then I am printing to verify what I have received, and then I am storing the data using  the following

for (int i=0;i<p_gap_evt->params.adv_report.data.len;i++)
{
    devices[k++]=p_gap_evt->params.adv_report.data.p_data[i];
}

Then in repeated timer handler, I am sending the devices array that should contain all the beacons 30 byte data. At this time I have 5 beacons, so I declared array of size 200. In timer handler, I am doing this.

static void repeated_timer_handler(void * p_context)
{
    for (int i=0;i<sizeof(devices);i++)
    {
        app_uart_put(devices[i]);
    }
}

My main function looks like

int main(void)
{
    // Initialize.
    log_init();
    uart_init();
    power_management_init();
    ble_stack_init();
    scan_init();
    
    app_timer_init();
    
    create_timers();

    scan_start();

    app_timer_start(m_repeated_timer_id, APP_TIMER_TICKS(15000), NULL);

    // Enter main loop.
    for (;;)
    {
        idle_state_handle();
    }
}

But I am not getting anything on console, and if change my first snippet like this

for (int i=0;i<p_gap_evt->params.adv_report.data.len;i++)
{
    devices[i]=p_gap_evt->params.adv_report.data.p_data[i];
}

devices [k++] to devices[i], then in timer handler I get data in devices array but the last data that is stored, not all the data. I want to store the data for 10 scanning instances (1 sec scan every 1 min), then the timer handler will be executed every 10 min to send the data, and the process repeats.

Kindly suggest suitable way to achieve this.

I appreciate your suggestions.

Regards,

  • Yes I figured it after sending the reply. The leds are active low in the dongle. But still the problem is the same. It is not storing the advertised data with the above code that I had mentioned in my last reply. It can send me the data if I use "i" instead of "deviceLength++" like the following snippet but I cannot be able to store the data.

    Now I am looking for another way to store the data, maybe in the main loop or need to start and stop scanning explicitly. 

    for (int i = 0; i < p_gap_evt->params.adv_report.data.len; i++) {
        devices[i] = p_gap_evt->params.adv_report.data.p_data[i];
    }

  • Again, I really suggest that you develop your application on a DK where you have the possibility to debug. 

    What SDK version do you use?

  • Yes you are absolutely right, but I really cant do at this point, because if I order now, it would take some time to get, and I am going on a holiday. So, this project has to be completed on a dongle.

    I am using SDK 15.3 and softdevice s140.  I build my program using segger embedded studio and use nRF connect programmer for uploading. 

    I figured out (maybe I am wrong) that my program does not go into timer_handler, and spend all the time in scanning, and interval. my scan parameters are

    #define SCAN_INTERVAL 16000
    #define SCAN_WINDOW 1600 
    #define SCAN_DURATION 32000

    1 sec scan and 9 sec interval. But this scan duration is something I donot clearly understand. So I think I need to explicitly stop scan and do other stuff in timer_handler. Maybe the radio is on, so it is not going into timer_handler, or something like this. Can you suggest better way to scan for 1 sec every 10 sec, and at 15 sec, send the stored data via timer_handler. Or any approach to achieve this.

    I appreciate your effort to help me.

    Regards,

  • With the following parameters:

    #define SCAN_INTERVAL 16000
    #define SCAN_WINDOW 1600 
    #define SCAN_DURATION 32000

    You will scan for 1 second every 10 seconds, for 320 seconds (after that it times out and goes to sleep).

    I suggest, if you need to do this without a debugger, that you use your LEDs, and do one thing at a time.

    First, set up a timer and toggle a led (do not turn it on/off, and back off/on in the same timeout handler, but toggle it once every timeout, just to see that the timeout handler is repeatedly called. 

    Also, I suggest that you create your own error handler which only set a specific LED (e.g. the red one), so that you can check whether an error (custom_APP_ERROR_CHECK(err_code)) triggers. Alternatively alter the error handler (APP_ERROR_CHECK()) to do this.

    To toggle, you can use nrf_gpio_pin_toggle(uint32_t pin number) instead of nrf_gpio_pin_set() and nrf_gpio_pin_clear().

    When you have a stable timer, you can start checking that everything returns proper values:

        nrf_gpio_pin_set(LED2);    //Green LED
        if (p_gap_evt->params.adv_report.data.p_data[0] == 0x02) {
          if (p_gap_evt->params.adv_report.data.p_data[1] == 0x01) {
            if (p_gap_evt->params.adv_report.data.p_data[2] == 0x06) {
                for (int i = 0; i < p_gap_evt->params.adv_report.data.len; i++) 
                {
                    devices[deviceLength] = p_gap_evt->params.adv_report.data.p_data[i];
                    deviceLength++;
                }
                devices[deviceLength] = p_gap_evt->params.adv_report.rssi;
                deviceLength++;
                if (deviceLength < 4)
                {
                    nrf_gpio_pin_clear(LEDn) //red led (don't remember the number)
                }
                else
                {
                    nrf_gpio_pin_set(LEDn) //turn off the led to indicate that the parameter deviceLength is incremented properly
                }
            }
          }
        }

    e.g. like this to see whether deviceLength is actually increasing.

    I am not sure how you figure out that things are not working properly. Do you have some way of logging?

  • Hi, thanks for reply.

    I am using app_uart_put() to send to FTDI for showing the data on the terminal. Also, I am using LEDs.

    As you have said, I checked the timer by incremented a counter in timer_handler and printed the value of counter. I  have noticed it is not working correctly, the counter goes from 00 to 06, and then goes back to 00 then 01 and 02. After 02, the program does not go into timer_handler again. If I do not do anything in the timer_handler and just increment a counter. then it works properly. This is strange but true.

    Also, by changing the scan_interval, scan_window and scan_duration parameters. I observed the following.

    1: If scan_interval and scan_window are equal, scan does continuously.

    2: if scan_duration is less than scan_interval (for example: scan_interval 16000 and scan_duration 1000), scan does continuously.

    3: If we set values like scan_interval 16000, scan_window 1600, and scan_duration 1200, then it scans for 1 sec every 10 sec, but does not stop at 12 sec and keeps on doing this like forever. So what is the purpose of scan_duration if it does not stop.

    Now I think I need to explicitly start and stop scan, and need to use driver timer instead of app_timer. I followed this link as it is for app_timer, just changed timer_ticks value to 15000. Maybe I also need to change the data parser inside BLE_GAP_EVT_ADV_REPORT. I saw this data parser but I do not understand if it is OK for me.  https://devzone.nordicsemi.com/f/nordic-q-a/38656/adv-data-parser

     https://devzone.nordicsemi.com/nordic/short-range-guides/b/software-development-kit/posts/application-timer-tutorial

    Regards,

Related