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.

Parents Reply
  • The reason for why there isn't any tutorial for setting up sensors is because different sensors have different protocols. Some use UART, some use I2C, some use SPI, some are analogue (Like your weight sensor), some are something else (Like your Temp sensor. Not standardized). 

    The weight sensor uses changes the resistance depending on the weight, so you have to give it some voltage, and measure the voltage drop over the sensor. See the Saadc example on how to do this.

    The temp sensor uses a custom protocol. It is called 1-wire-bus. See the datasheet section 1-wire bus system. I don't know what protocol it is, but it looks like a modified SPI or UART, using only one wire (in and output). You will have to experiment a bit with this one, or maybe you can find some tutorials (not from Nordic) on how to use this.

    Best regards,

    Edvin

Children
  • So I figured out how to read the sensors using the Saadc example. Now the task that I'm faced with is to relay this data through UART ble_peripheral to my iPhone/Android device. I am using the UART tutorial on ble_peripheral but I'm having a difficult time trying to find out where I pass these values to be sent over UART.

  • look for ble_nus_data_send();

    It is used in the uart_event_handle() in main.c in that example.

    You can use this function to send your data to the phone.

    BR,

    Edvin

  • 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