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

UART + non-connectable advertisement

I am trying to broadcast a non-connectable advertisement (such as a beacon) while I am connected to a device that I am transferring data via TX. I am working with a nRF52840 on Segger Embedded Studio v3.4 with the nRF5_SDK_15 as the base for my code manipulation. More specifically I'm going off the ble_app_uart example for pca10040 s132. I don't care about receiving data through RX from the device I am connected to. By the way, I have tried using the Time Slot API where I try to initiate the advertising of the beacon when the device connects through UART. It is my understanding from projects such as the nRF51-multi-role-protocol-conn-observer-advertiser example on github but this is for nrf51 devices. I have tried to mimick this project as well as articles showing how the time slot api can be used to implement non-connectable advertising during a connection as a peripheral. I have also tried doing this without the Time Slot API but to no avail. My thinking is that the buffer transferring data out of the device can only handle 31 bytes of data per interval, but both the advertising and uart protocols take up 31 bytes so its not possible to do at the same time. There must be a way to switch between the two protocols (uart and advertisement) when the radio interrupt occurs. Please help.

  • I found what you are referring to and I am able to pass in data properly. What I am having trouble with is being able to call uart_event_handle constantly because the use case is having the bluetooth device emit UART signals in a regular interval with the temp and weight information. I am able to trigger the uart_event_handle by creating a variable of type app_uart_evt_t and passing it into that function. I do this in the main loop, but there is not enough of a delay between each call to this function. My thoughts were to either sleep the thread for a certain period of time which I have had zero success, and I am also trying to create an app_timer to repeatedly call this function in a certain interval but not successfully able to do so. Was wondering if you could help me create this timer or if you could think of a better way. Here is my main loop so far:

    for (;;)
        {   
            if(connected == 1) {
                  
                  
                 // create timer
                  ret_code_t err_code;
                  err_code = app_timer_init();
                  APP_ERROR_CHECK(err_code);
                  
                  // variables to pass into app_timer_create
                  app_timer_id_t * timer_id = APP_TIMER_DEF(10);
                  app_timer_mode_t * timer_mode = APP_TIMER_MODE_REPEATED;
                  app_timer_timeout_handler_t * timer_timeout_handler;
                  
                  // variable to pass into uart_event_handle
                  app_uart_evt_t * p_event;
                  // triggers data to be sent over UART
                  uart_event_handle(p_event);
    
                  // 
                  err_code = app_timer_create(timer_id,timer_mode, timer_timeout_handler);
                  APP_ERROR_CHECK(err_code);
            }
            
            idle_state_handle();
        }

    But I'm getting a compiler error with the timer_id as I have no idea what to pass in. I also don't think I'm setting the timer_mode variable properly, and I don't know how I can set the timer_timeout_handler to call the part_event_handle function. I've also attached my source code.
  • Hello,

    Sorry for the late reply. I have been out of office this week.

    First, I recommend that you do the app_timer_init() outside your main-loop, because in this case you will run app_timer_init() all the time, as long as you are connected, so it will stop and start all the time, and you will create timers just as often, and your app_timer_create() will return NRF_ERROR_INVALID_STATE from the second time it is called.

    So move everything that you have inside if(connected == 1){} to before the for(;;)

    What you actually don't do is to start the timer, using app_timer_start. This is also something you should do outside your main-loop. If not, you will just start it over and over.

    I suspect that the if(connected) part is something you want in your timeout handler. You should initialize your timer in your main() application, before the for (;;) loop, and you can start your timer in the BLE_GAP_EVT_CONNECTED event in ble_evt_handler().

    I recommend that you look at the ble_app_hrs example, as this sets up different timers. You can see in the main() function, that it calls timers_init(), application_timers_start().

    The m_heart_rate_timer_id is quite similar to what you are trying to achieve. As you can see, the timer_id is defined near the top of main.c, APP_TIMER_DEF(m_heart_rate_timer_id);

    If I were to tell you how to do it, it would be a copy paste of the main file from the ble_app_hrs example.

    Best regards,

    Edvin

Related