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

Update timer speed once connected

I have a custom Characteristic in my GATT that is sending data in Notify mode every 30ms.

In my firmware I use timer to do this with something like this :


#define RTC1_TICK_DURATION		31
	
#define TIMER_ONE_DURATION   		33 // 30ms																/**<(deflt:1000)[ms] sending/measurement cycle duration for 1s cycled characteristics*/
#define TIMER_ONE_TICKS_NB 		(TIMER_ONE_DURATION * 1000 / RTC1_TICK_DURATION)


err_code = app_timer_start(m_TimerOne_id, (uint32_t)TIMER_ONE_TICKS_NB, NULL);


Everything is working great but sometimes, randomly, my app using BLE or my laptop using Web BLE (so two different device with two different source code with the same behavior) are unable to retrieve value for this Characteristic. They are able to connect to my device but no Characteristic value is send.

I tried to change the interval from 30ms to 90ms and so far I am not able to reproduce this issue so it lead me to think that the speed can be the source of the issue.

How would you deal with that ? Is it possible to notify at a low pace, then one second after a connection is made, increase the speed ? Or better, when someone subscribe to the Notifying Characteristic increase speed, when it disconnect decrease speed ?

Thanks !

Parents
  • Hi

    First, I want to say that development without the possibility to debug is very hard, and ill advised, and you should avoid this in the future.

    Next, what you should look at are return values from the ble_service_on_value_change() function, to see how are you updating your firmware? By using a debugger or bootloader? If you do have a debugger you could use the RTT logger, to read these return values. If not you should test this on a development kit first, before implementing it into your product.

    I don't think this is a race condition per say, but maybe an interrupt from some process with a higher priority. Again, debugging is the correct way of finding out what is happening, as me guessing what the issue is, is really inefficient.

    Best regards,

    Simon

  • According to this post I have the same behaviour.

    The error appears when my m_conn_handle = 0xFFFF

    But I don't think this is the real error. The real error is that sometimes, even if I call nrf_drv_saadc_sample(), it never trigger the saadc_callback() function.

    Could it be because I uninit the saadc every time I do a disconnection to enter in low power ?

    Every time I disconnect I do :

    void saadc_uninit(void)
    {
        ret_code_t err_code;
        nrf_drv_saadc_abort();
    
    
        nrf_saadc_disable();
        while(NRF_SAADC->STATUS == (SAADC_STATUS_STATUS_Busy << SAADC_STATUS_STATUS_Pos))
          {}
    
        err_code = nrf_drv_saadc_channel_uninit(0);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_saadc_channel_uninit(1);
        APP_ERROR_CHECK(err_code);
    
        nrf_drv_saadc_uninit();
        NRF_SAADC->INTENCLR = (SAADC_INTENCLR_END_Clear << SAADC_INTENCLR_END_Pos);
        NVIC_ClearPendingIRQ(SAADC_IRQn);
    
    }

    It seems more likely to be something to do with the saadc driver for me instead of the connection handler.

    Can this be related to this or this ?

    Because most of the times I can predict when an error will occurs just by checking my debug from my previous disconnection. If during a disconnection, I see a debug log from saadc_callback() showing while i'm in the DEVICE_GOtoLowpower case (or after), my next connection will not get data. I hope I make myself clear.

    Here are the log :

    case DEVICE_GOtoLowpower :
            send_log("Start DEVICE_GOtoLowpower");
            stop_TimerOne();
            stop_TimerTwo();
            send_log("Timers stopped");
            accel_deep_sleep();
            disable_spi();
            send_log("before saadc_uninit");
            //saadc_uninit();
            send_log("after saadc_uninit");
            GPIO_lowpower();
            u8_device_state=DEVICE_DISCONNECTED;
            send_log("End DEVICE_GOtoLowpower");

    <info> app: Start DEVICE_GOtoLowpower
    <info> app: Timers stopped
    <info> app: before saadc_uninit
    <info> app: after saadc_uninit
    <info> app: End DEVICE_GOtoLowpower
    <info> app: LOG FROM saadc_callback here

Reply
  • According to this post I have the same behaviour.

    The error appears when my m_conn_handle = 0xFFFF

    But I don't think this is the real error. The real error is that sometimes, even if I call nrf_drv_saadc_sample(), it never trigger the saadc_callback() function.

    Could it be because I uninit the saadc every time I do a disconnection to enter in low power ?

    Every time I disconnect I do :

    void saadc_uninit(void)
    {
        ret_code_t err_code;
        nrf_drv_saadc_abort();
    
    
        nrf_saadc_disable();
        while(NRF_SAADC->STATUS == (SAADC_STATUS_STATUS_Busy << SAADC_STATUS_STATUS_Pos))
          {}
    
        err_code = nrf_drv_saadc_channel_uninit(0);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_saadc_channel_uninit(1);
        APP_ERROR_CHECK(err_code);
    
        nrf_drv_saadc_uninit();
        NRF_SAADC->INTENCLR = (SAADC_INTENCLR_END_Clear << SAADC_INTENCLR_END_Pos);
        NVIC_ClearPendingIRQ(SAADC_IRQn);
    
    }

    It seems more likely to be something to do with the saadc driver for me instead of the connection handler.

    Can this be related to this or this ?

    Because most of the times I can predict when an error will occurs just by checking my debug from my previous disconnection. If during a disconnection, I see a debug log from saadc_callback() showing while i'm in the DEVICE_GOtoLowpower case (or after), my next connection will not get data. I hope I make myself clear.

    Here are the log :

    case DEVICE_GOtoLowpower :
            send_log("Start DEVICE_GOtoLowpower");
            stop_TimerOne();
            stop_TimerTwo();
            send_log("Timers stopped");
            accel_deep_sleep();
            disable_spi();
            send_log("before saadc_uninit");
            //saadc_uninit();
            send_log("after saadc_uninit");
            GPIO_lowpower();
            u8_device_state=DEVICE_DISCONNECTED;
            send_log("End DEVICE_GOtoLowpower");

    <info> app: Start DEVICE_GOtoLowpower
    <info> app: Timers stopped
    <info> app: before saadc_uninit
    <info> app: after saadc_uninit
    <info> app: End DEVICE_GOtoLowpower
    <info> app: LOG FROM saadc_callback here

Children
No Data
Related