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,

Parents
  • Hello,

     

    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

     Does k get incremented every time this handler is called? You can try to print it while you get the data, to see why only the last device is stored, and not all of them.

    Is your k variable volatile? Maybe it starts on 0 every time it is called?

  • Hello,

    Thanks for you reply. Yes I am able to store data and later in the timer handler, prints the data on console. But the thing is I have not changed anything. Sometimes the data prints, sometimes do not. I do not know what is causing this issue. I was not getting data at first, but when I uploaded the program again, I got the data. Then after letting it run for 1 hour, it stopped the data. Now it is not showing the data. I am not sure if need to post another question for this. I am using nrf52840 dongle. Maybe this was the reason I was not getting the data and I thought that I have done something wrong in my code.

  • 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,

  • if you have access to the UART output then I suggest that you use the NRF_LOG module with UART as backend, instead of app_uart_put. The reason for this is that NRF_LOG will give you information when the APP_ERROR_CHECK() detects something strange. Maybe the error handler fires in your application, causing the application to restart, and hence your counter goes back, and you lose all your previously stored data. 

    So, enable logging in sdk_config.h with UART as backend, and define DEBUG in your preprocessor defines, and monitor the uart log output.

  • OK I will do as you said. I will enable the logging using uart. And I will get back to you in a day.

  • Hi Edvin,

    Well, i have tried many things and have completed most of my work. But still I am not able to store advertisement data. I am sure that the problem is with storing part, because when I store only one device, it works as expected, but when I store multiple devices in one array as I mentioned above, the application crashes.This storing part is the main part of my application, and I am no C expert, so could not figured out how to store the devices data into one array for specific time to be able to send it and reinitialize the array and repeat the process.

    Can you suggest something. 

    Regards,

    PK SHER

  • Does the log say anything on where the application crashes? You can try to add "DEBUG" to your preprocessor defines if it only says "Fatal error". Then it should give you a line number.

    Looking at your snippet from a couple of posts ago:

    static void ble_evt_handler(ble_evt_t const *p_ble_evt, void *p_context) {
      ble_gap_evt_t const *p_gap_evt = &p_ble_evt->evt.gap_evt;
      uint8_t uuid[30];
      uint8_array_t adv_data;
    
      switch (p_ble_evt->header.evt_id) {
      case BLE_GAP_EVT_ADV_REPORT: {
        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++;
            }
          }
        }
        nrf_gpio_pin_clear(LED2);
      }
      default:
        break;
      }
    }
    

    What type is your deviceLength variable?

    Try to set it as a "volatile uint32_t" or whatever uintx_t you use. Just make it volatile. You can declare it at the top of that .c file that you use it in.

    Also, what type of variable is the "devices" variable? Is it an array? what type? How do you declare it? If it is an array, how long is it?

Reply
  • Does the log say anything on where the application crashes? You can try to add "DEBUG" to your preprocessor defines if it only says "Fatal error". Then it should give you a line number.

    Looking at your snippet from a couple of posts ago:

    static void ble_evt_handler(ble_evt_t const *p_ble_evt, void *p_context) {
      ble_gap_evt_t const *p_gap_evt = &p_ble_evt->evt.gap_evt;
      uint8_t uuid[30];
      uint8_array_t adv_data;
    
      switch (p_ble_evt->header.evt_id) {
      case BLE_GAP_EVT_ADV_REPORT: {
        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++;
            }
          }
        }
        nrf_gpio_pin_clear(LED2);
      }
      default:
        break;
      }
    }
    

    What type is your deviceLength variable?

    Try to set it as a "volatile uint32_t" or whatever uintx_t you use. Just make it volatile. You can declare it at the top of that .c file that you use it in.

    Also, what type of variable is the "devices" variable? Is it an array? what type? How do you declare it? If it is an array, how long is it?

Children
Related