Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs

Problem with nrf5_calendar example

Dear,

I have integrated the nrf5_calendar example with "usbd_ble_uart" . Everything works correctly, but I have detected two possible errors (or I am doing something wrong):

ERROR 1: problem with the configured year. I can solve this by changing 1900 to 2000, but I don't know if it will affect another time.

ERROR 2: The function "nrf_cal_get_time_string" adds +1 to the configured month value (I have tried with different configurations and it always happens).

Notes:

SDK: nRF5_SDK_17.1.0_ddde560

EVB: nRF52833 DK

Any ideas?

Thank you very much for your help.

Raquel.

  • ERROR 1: problem with the configured year. I can solve this by changing 1900 to 2000, but I don't know if it will affect another time.

    I don't think you should do that. The reason is that the external time library expects to get the "year" parameter given as years after 1900. Please look up the "struct tm" in time.h.

    What sort of problem did you see? (your screenshot shows 1900 as being used), by the way.)

    ERROR 2: The function "nrf_cal_get_time_string" adds +1 to the configured month value (I have tried with different configurations and it always happens).

    This is also something that is decided by the external library. Please have a look at the struct (from time.h) :

    struct tm {
        int tm_sec;   /* seconds after the minute, 0 to 60
                         (0 - 60 allows for the occasional leap second) */
        int tm_min;   /* minutes after the hour, 0 to 59 */
        int tm_hour;  /* hours since midnight, 0 to 23 */
        int tm_mday;  /* day of the month, 1 to 31 */
        int tm_mon;   /* months since January, 0 to 11 */
        int tm_year;  /* years since 1900 */
        int tm_wday;  /* days since Sunday, 0 to 6 */
        int tm_yday;  /* days since January 1, 0 to 365 */
        int tm_isdst; /* Daylight Savings Time flag */
        union {       /* ABI-required extra fields, in a variety of types */
            struct {
                int __extra_1, __extra_2;
            };
            struct {
                long __extra_1_long, __extra_2_long;
            };
            struct {
                char *__extra_1_cptr, *__extra_2_cptr;
            };
            struct {
                void *__extra_1_vptr, *__extra_2_vptr;
            };
        };
    };
    

    Best regards,

    Edvin

  • Hi Edvin,

    Thank you for your answer.
    I have not been very clear with the problems I am having. I will try to explain better below:


    I send the year,month,day,second,minute and hour values via USB (I use TeraTerm) and via Bluetooth (with the nRF Toolbax mobile app). In both cases I capture and store the data correctly (see following image):

    When I apply the values to time_struct using nrf_cal_set_time(...) it also seems to work correctly (see following image):

    However, when I try to query the configured values by calling the function "nrf_cal_get_time_string(false)" the values are not the correct ones (See following image):
    Note: I also tried with nrf_cal_get_time_string(true).

    The value of "month" is not correct.

    I attach below the code where I capture and process this data:

    static void cdc_acm_user_ev_handler(app_usbd_class_inst_t const *p_inst,
        app_usbd_cdc_acm_user_event_t event) 
    {
     [...]
     case APP_USBD_CDC_ACM_USER_EVT_RX_DONE: {
        ret_code_t ret;
        static uint8_t index = 0;
        index++;
        
          if((startAccsample == true)){
              memcpy(arrayUsb, "\r\nSTOP DATALOGGER\r\n", sizeof(arrayUsb));
              writeToUsb();
              app_timer_stop(acc_timer_id);
              startAccsample = false;
          }
    
        do {
    
          if ((m_cdc_data_array[index - 1] == '\n') ||(m_cdc_data_array[index - 1] == '\r')) 
          {
            if (index > 1) {
                  memcpy(usb_rx_data, m_cdc_data_array, sizeof(m_cdc_data_array));
            }
    
             eventUsbDetected = eventUsbRx();
             EvaluateUsbOption(eventUsbDetected);
    
            index = 0;
             memcpy(usb_rx_data,0,sizeof(usb_rx_data));
             memcpy(m_cdc_data_array,0,sizeof(m_cdc_data_array));
          }
     [...]
     
     }
     
     }

    void currentTime() {
    
      char *time_string;
      uint16_t length;
    
      time_string = nrf_cal_get_time_string(false);
      length = strlen(time_string);
    
      #if (CONFIG_USB == 0)
      uint32_t err_code = ble_nus_data_send(&m_nus, time_string, &length, m_conn_handle);
      APP_ERROR_CHECK(err_code);
      #else
      sprintf(time_string,"%s\r\n",time_string);
      memcpy(arrayUsb, time_string, sizeof(arrayUsb));
      writeToUsb();
      #endif
    }

    void configTimeRx(void){
    
    
      #if(CONFIG_USB == 0)
      hour = atol(ble_rx_data);       // 1 - 24
      minute = atol(ble_rx_data + 3); // 0 - 59
      second = atol(ble_rx_data + 6); // 0 - 59
      day = atol(ble_rx_data + 9);    // 1 - 31
      month = atol(ble_rx_data + 12); // 0 - 11
      year = atol(ble_rx_data + 15);  // 1900
      #else
      hour = atol(usb_rx_data);       // 1 - 24
      minute = atol(usb_rx_data + 3); // 0 - 59
      second = atol(usb_rx_data + 6); // 0 - 59
      day = atol(usb_rx_data + 9);    // 1 - 31
      month = atol(usb_rx_data + 12); // 0 - 11
      year = atol(usb_rx_data + 15);  // 1900
      #endif
    
      nrf_cal_set_time(year, month, day, hour, minute, second);
    
    
      SEGGER_RTT_printf(0, "\r\nTime set: ");
      SEGGER_RTT_printf(0, "\r\n%s", nrf_cal_get_time_string(false));
      SEGGER_RTT_printf(0, "\r\n\n");
    
      currentTime(); //tx time
    
      memset(ble_rx_data, 0, 26);
    
      update_time = false;
      data_rx_time = false;
    }

    --------------------------------------------------------------

    I have observed that I am not working with the same version of the library that you propose. Please note the definition of my "struct tm":

    I am working with "SEGGER Embedded Studio for ARM 5.50d".

    time.h

    ------------------------------------

    On the other hand:


    The first capture I attached in ERROR 1 was made with time_struct.tm_year = year - 1900;
    But the second capture was made with time_struct.tm_year = year - 2000;
    However, this problem was solved by removing the following part in the nrf_cal_set_time(...) function (I read this proposal from some NORDIC colleague).

    -----------------------------

    This is the example of nrf5_calendar I am working with:

    nrf5-calendar-example-master.zip

    Thank you for your help,

    Raquel.

  • Please note that this is not an official example from Nordic. It was a project used in a demo at some point, and uploaded to the Nordic Playground for convenience, in case anyone needed something similar. 

    The confusion regarding the month is just because you believe that the months go from 1 to 12, but they go from 0 to 11. As it says "months since january". Try inserting a date in december, and you should see that it is not possible to use month number 12.

    I do agree that it is a bit confusing, but when you enter the month 10 over UART, it is not october, it is november. If this confuses you, you need to either adjust how the time is printed (add 1 to the month) or change the way that the month is input (add one). 

  • So the month setting has to be taking into account January = 0 and December = 11, however, the function nrf_cal_get_time_string(false) does return the correct value (January = 1, December = 12).
    My tests make me think that this is the case. Can you confirm this?

    TEST:

    I want to set mm/dd/yyyy = 12/12/2022 and hh:mm:ss = 23:59:55. Taking into account that month = 0 means January and month = 11 means December, I configure by USB the following:

    [INFO]: 11/12/2022, 23:59:55

    After 5 seconds the day, month and year must be changed.  You can see that January is shown as 01 (and not as 00):

    Thank you.

Related