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

Nordic Calendar example (https://github.com/NordicPlayground/nrf5-calendar-example) related issue

I wanted to implement a time sync feature on nRF-52840 DK. I took a reference from this example, but there were certain things unclear to me.

Can somebody explain to me what is calibrated and uncalibrated time here? and what exactly are we doing here in this example?

Parents
  • In this example, a calendar is periodically synced with an outside time-stamp. It does not cover how you obtain the outside time-stamp, just how you can use it to update the calendar. 

    As the calendar uses the RTC as it's base clock, it will experience a fair amount of drift, +/- 10-20ppm at best, and will need to be periodically calibrated/synced. 

    I believe the uncalibrated time is the current time of the calendar, and the calibrated time is the provided synchronization time-stamp.

  • I flashed this example on an nRF52840 DK and I got this output on serial

     when I use the get function(option g) to get the time, I get this as the output where the calibrated and the uncalibrated time is the same.

     next, when I use the run continuous-time updates (option r), I get a time difference of 4 seconds every time and I just don't get it that why is there such a big difference.

    Later I set time to current time and then tried to run continuous-time updates (option r) and still there is a time difference of 4 seconds.

    can you please explain this behavior?

  • Hi Manikandan

    I am happy I could be of help Slight smile

    The purpose of this function is to provide a callback function to the library that will be called at a regular interval, which is useful if for instance you want to log the time regularly in your code, or if you want to display the time somewhere at regular intervals. 

    If you want to schedule some activity at a certain time in the future you can also use this callback to check the current time once in a while, and perform some activity once you reach a certain point in time. 

    As an example, if you create a void(void) function in your code and forward it to this function with the interval set to 60, your function will be called once every minute:

    void do_something(void)
    {
        // This code will run once every minute
    }
    
    .
    .
    
    nrf_cal_set_callback(do_something, 60);

     

    manikandan said:

    and also how can i print something like this int count =CAL_RTC->COUNTER / 32.768;

    printf("%d",count);;is this correct.I want to see the values myselfs before sending it over ble

    In order to divide the value by 32.768 you would have to convert the COUNTER value to float first, like this for instance:

    int count_ms = (int)((float)CAL_RTC->COUNTER / 32.768f);

    It is also possible to rewrite the formula and perform it all in integers:

    int count_ms = (CAL_RTC->COUNTER * 250 + 125) / 8192;

    Please note I haven't tested any of these code snippets, so take them with a grain of salt ;) 

    manikandan said:
    and also what happens when overflow occurs and how can i rectify that

    When an overflow occurs the RTC COUNTER value will be reset back to 0, and since the code is not set up to handle this it will lead to incorrect time updates. 

    To avoid this simply call the nrf_cal_set_callback(..) function with an interval lower than 512 seconds.

    Then the  RTC IRQ handler will be called before the overflow happens, and you should not have any issues. 

    Best regards
    Torbjørn 

  • hello, thanks for your help  i can be able to get milliseconds and run a 24 hours clock successfully now i want to do time sync up that day you told if we are developing our own app it is possible to get a timestamp in the app and send it over a proprietary service to the nRF52 device every time i connect.

    1)indeed we are developing our own app can you elaborate on how can i get that timestamp in program and set that time in nrf_cal_set_time(..) ??

    2)where do i get my timestamp in ble_app_uart program?? in nus_data_handler(..) function uh??

    thanks and regards

    Manikandan V

  • Hi Manikandan

    1) Not sure which mobile platform you are targeting, but on Android there is a LocalTime library for getting time and date information, and I am sure something similar exists for iOS. 

    The important thing is that you get an integer timestamp that can be passed over the BLE link. 

    2) That is correct. By default the ble_app_uart example uses the nus_data_handler(..) function to process incoming data from the app. 

    Best regards
    Torbjørn

  • hello  i am using android and developed an customised app and doing something like this is

    for (uint32_t i = 0; i < p_evt->params.rx_data.length; i++)
    {
    str[i]=p_evt->params.rx_data.p_data[i];

    strcpy(buf,str);

    uint8_t j=0;
    char *pch = strtok (buf,"- :");
    while (pch != NULL)
    {

    array[j]=pch;
    j=j+1;
    pch = strtok (NULL, "- :");
    }
    year=atoi(array[0]);
    month=atoi(array[1]);
    day=atoi(array[2]);
    hour=atoi(array[3]);
    minute=atoi(array[4]);
    second=atoi(array[5]);
    ....

    }

    note: i am sending the current time from app everytime i connect with bluetooth and getting the exact values in year,hour,...,seconds variable.

    but if  i call nrf_cal_set_time(..) in main to starts from 1970  but not with the time i sent

    my main looks like this

    int main();

    {

    //all init

    nrf_cal_set_time(year, month, day, hour, minute, second); 

    while(1)
    {

    length=sprintf(cal_string,"%s", nrf_cal_get_time_string(true)); 

    ble_nus_data_send(&m_nus,cal_string,&length,m_conn_handle);
    }

    }

    where should i call nrf_cal_set_time(..) in my program to make it run one time and start sending date and time from the time i sent.

    Thanks and regards

    Manikandan V

  • Hi 

    My initial thought is that you seem to be over complicating things a little. 

    Can't you just code year/month/day/hour/minute/second each into a separate byte without converting to and from ascii representation?

    Then you only need 6 bytes in total to represent a date and time update, and you can easily copy each byte from the rx_data.p_data buffer into the 6 variables (just remember to subtract 1970 from the year before sending it, and add it back here, since a single byte can't store numbers > 255). 

    Best regards
    Torbjørn

Reply
  • Hi 

    My initial thought is that you seem to be over complicating things a little. 

    Can't you just code year/month/day/hour/minute/second each into a separate byte without converting to and from ascii representation?

    Then you only need 6 bytes in total to represent a date and time update, and you can easily copy each byte from the rx_data.p_data buffer into the 6 variables (just remember to subtract 1970 from the year before sending it, and add it back here, since a single byte can't store numbers > 255). 

    Best regards
    Torbjørn

Children
Related