Get Current Time
응답
18. 6. 5 오전 8:04

Hello everyone, 
Is it possible to get the current time? I found xTaskGetTickCount() acquire the system time. Do I need to use NTP to acquire current time? I want to read the time when sensors publish data to MQTT server.

Thank you.

Kind regards 

Rachel

0 (0 투표)
RE: Get Current Time
응답
18. 6. 5 오후 1:50 as a reply to Rachel Wu.
Hello Rachel,

unfortunately, the XDK's clock is not representing real time, since it can not actively track the time when it is turned off.

Hence, SNTP must be used to get an accurate timestamp. For this, I have provided a code-snippet in this file on github.

For further information on how to use the resulting value efficiently, I recommend to take a look at the BoschXdkCloudConnectivity's SNTP implementation. There, the file SntpTime.c implements SNTP functionality. While that implementation uses a raw UDP message instead of the SNTP API provided by Serval, the resulting timestamp is the same.

Please tell me if this was helpful, and do not hesitate to ask further questions.

Kind regards,
Alex
0 (0 투표)
RE: Get Current Time
응답
18. 6. 6 오전 8:53 as a reply to Alexander Sawtschuk.

Hello Alex,

I am interested to set the time to XDK too.

For testing, how can I just print out the time stamp to the console?

Thanks,

Eddie

 

0 (0 투표)
RE: Get Current Time
응답
18. 6. 6 오후 1:01 as a reply to Eddie Kwan.
Hello Eddie,

printing the timestamp received by the NTP server is exactly the use case implemented in the code snippet I provided on github

Additionally, if your use case currently only consists of printing the timestamp (i.e. your testing project does not do anything else), then you have to connect to WiFi first and set up ServalPAL. I have created another snippet here that covers the gist of it. Of course, for further options during WiFi setup, please take a look at the corresponding guide in the XDK Learning Section

Furthermore, you can print the system time using the interface Serval_Clock.h as follows:

 
 uint64_t time; 
Clock_getTimeMillis(&time); 
printf("time: %llu\n\r", time);  


Keep in mind that the SNTP implementation returns the time in seconds, and as mentioned in my previous post, for advanced usage of the clock time and the time returned by the NTP server please take a look at SntpTime.c in BoschXdkCloudConnectivity .

Please tell me if this was helpful, and do not hesitate to ask further questions.

Kind regards,
Alex
0 (0 투표)
RE: Get Current Time
응답
18. 6. 7 오전 11:37 as a reply to Alexander Sawtschuk.

Hello Alex,

I have tried your code. It can get time at first. And then It didn't change anymore.

XDK will send sensor data to mqtt every 1s, but the timestamp didn't change.

void sensorStreamDATA(sensorEvent event)
{
	getMAC();
	memset(sensorStreamBuffer.data, 0x00, SENSOR_DATA_BUF_SIZE);
	sensorStreamBuffer.length = NUMBER_UINT32_ZERO;
 	sensorStreamBuffer.length += sprintf((char *)sensorStreamBuffer.data + sensorStreamBuffer.length,
 			"{\n\"Device\": \"%s\",\n",
			"XDK110");

 	sensorStreamBuffer.length += sprintf((char *)sensorStreamBuffer.data + sensorStreamBuffer.length,
 			"\"MAC Address\":\"%s\",\n",
			MACAddress);
	switch(event)
	{
	case ENV:
		_envData = ReadEnvironmentSensor();
		doSNTP();
		sensorStreamBuffer.length += sprintf(sensorStreamBuffer.data + sensorStreamBuffer.length,
				"\"Sensor\": \"%s\",\n",
				"Environment Sensor");
		sensorStreamBuffer.length += sprintf(sensorStreamBuffer.data + sensorStreamBuffer.length, 
"\"Timestamp\": %ld,\n",  time_check);
		sensorStreamBuffer.length += sprintf(sensorStreamBuffer.data + sensorStreamBuffer.length,
				"\"humidity (%%rh)\" : %ld\n}",
				_envData.humidity);
		printf("1\n");
		break;
}

Thank you at first.

Rachel

0 (0 투표)
RE: Get Current Time
응답
18. 6. 7 오후 1:30 as a reply to Rachel Wu.
Hello Rachel,

the code snippet's function doSNTP() is not meant to be used more than once. If you want to retrieve the time multiple times from the NTP server, you have to use only Sntp_getTime() of the Serval_Sntp.h interface.

But what I would actually recommend is to use the interface Serval_Clock.h in addition. This is also done in the file SntpTime.c of the BoschXdkCloudConnectivity example.

The gist of it is as follows:

The Clock interface returns the number of seconds since the XDK booted, and the SNTP implementation returns the number of seconds since 01.01.1970 00:00:00. As such, you can take the offset between the current time and the XDK's clock value, and add that offset on the XDK's clock everytime you need the timestamp.

Calculating the offset can be done as follows. For this, modify the function onTimeReceive() provided by the code-snippet as follows:

 
#include "Serval_Clock.h" // add this to the includes
static uint32 time_offset = 0;

static void onTimeReceive(Ip_Address_T* sourceIp, Ip_Port_T sourcePort, uint32_t timestamp) {
	  uint32_t clock_timestamp;
    Clock_getTime(&clock_timestamp);
    time_offset = timestamp - clock_timestamp;
}


And now, every time you need a timestamp, you call the following function:

 
static uint32_t getCurrentTime(void) {
	uint32_t clock_timestamp;
	Clock_getTime(&clock_timestamp);
	return clock_timestamp + time_offset;
}


Keep in mind, those are the seconds, and not the milliseconds. For milliseconds, you can use the function Clock_getTimeMillis() as shown in my previous answer (the timestamp returned by the SNTP implementation is always only the seconds).

Please tell me if this was helpful, and do not hesitate to ask further questions.

Kind regards,
Alex
0 (0 투표)
RE: Get Current Time
응답
18. 6. 14 오전 11:07 as a reply to Alexander Sawtschuk.

Hi Alex,

It can work now.

Thank you very much

Kind Regards

Rachel

0 (0 투표)
RE: Get Current Time
응답
18. 6. 14 오후 3:45 as a reply to Rachel Wu.
Hello Rachel,

I am glad to hear that it is working now.

Please feel free to ask if you have any further questions or concerns.

Kind regards,
Alex
0 (0 투표)
RE: Get Current Time
응답
18. 10. 8 오후 3:36 as a reply to Alexander Sawtschuk.

Hello Alexander, 

 

using your script from https://github.com/appropos-de/xdk-snippets/blob/master/snippets/sntpUsingServal.c

 

i get the follwoing error. 

 INFO | XDK DEVICE 1: asserted at Filename 3rd-party/FreeRTOS/Source/queue.c , line no  1392 
 INFO | XDK DEVICE 1: Error in ServalPAL package.
 INFO | XDK DEVICE 1:     Package ID: 30    Module ID: 8    Severity code: 2    Error code: 1

 

Do you have an idea why?

 

kind regards

sven

0 (0 투표)
RE: Get Current Time
응답
18. 10. 9 오후 2:32 as a reply to Sven Kabitzki.
Hello Sven,

Unfortunately, I am currently not able to find the source of the error. In that regard, I would need more information about your use case.

Could you please provide an outline about how you integrated the provided SNTP source code. Did you use it as provided or did you add the implementation for Serval PAL and Wi-Fi to it too?

Kind regards,
Franjo
0 (0 투표)
RE: Get Current Time
응답
18. 10. 10 오전 7:02 as a reply to Franjo Stjepandic.

Hello Franjo, 

 

thought i would get notified if a new response to my post is posted. 

lucky me, i checked by hand ;-) 

So my simple script looks like:

/* module includes ********************************************************** */

/* own header files */
#include "XdkAppInfo.h"
#undef BCDS_MODULE_ID  /* Module ID define before including Basics package*/
#define BCDS_MODULE_ID XDK_APP_MODULE_ID_APP_CONTROLLER

/* own header files */
#include "AppController.h"

/* system header files */
#include <stdio.h>

/* additional interface header files */
#include "BCDS_CmdProcessor.h"
#include "BCDS_WlanConnect.h"
#include "FreeRTOS.h"
#include "task.h"

/* constant definitions ***************************************************** */

/* local variables ********************************************************** */

static CmdProcessor_T * AppCmdProcessor;/**< Handle to store the main Command processor handle to be used by run-time event driven threads */

static xTaskHandle AppControllerHandle = NULL;/**< OS thread handle for Application controller to be used by run-time blocking threads */

/* global variables ********************************************************* */

/* inline functions ********************************************************* */

/* local functions ********************************************************** */
#include "BCDS_NetworkConfig.h"
#include "Serval_Sntp.h"

// Customize depending on your desired NTP server
#define SNTP_DEFAULT_PORT				UINT16_C(123)
#define SNTP_DEFAULT_ADDR				"0.de.pool.ntp.org"
static WlanConnect_SSID_T 		WLAN_SSID 	=	"WLAN_SSID";
static WlanConnect_PassPhrase_T WLAN_PW 	= 	"WLAN_PW";
#define SECONDS(x) ((portTickType) (x * 1000) / portTICK_RATE_MS)

static void onTimeReceive(Ip_Address_T* sourceIp, Ip_Port_T sourcePort, uint32_t timestamp) {
	BCDS_UNUSED(sourceIp);
	BCDS_UNUSED(sourcePort);
	printf("Timestamp: %lu\n\r", timestamp);
}

static void onSent(Msg_T *msg_ptr, retcode_t status) {
	BCDS_UNUSED(msg_ptr);
	printf("sent status: %d\n\r", status);
}

void doSNTP(void) {
	Retcode_T retcode = RETCODE_FAILURE;
	printf("Sntp_intialize\r\n");

    retcode = Sntp_initialize();

    printf("Sntp_start\r\n");
    retcode = Sntp_start(Ip_convertIntToPort(123), onTimeReceive);

    printf("NetworkConfig_GetIpAddress\r\n");
    Ip_Address_T destAddr;
    retcode = NetworkConfig_GetIpAddress((uint8_t *) SNTP_DEFAULT_ADDR, &destAddr);

    printf("Sntp_getTime\r\n");
    retcode = Sntp_getTime(&destAddr, Ip_convertIntToPort(SNTP_DEFAULT_PORT), onSent);
}
/**
 * @brief Responsible for controlling application control flow.
 * Any application logic which is blocking in nature or fixed time dependent
 * can be placed here.
 *
 * @param[in] pvParameters
 * FreeRTOS task handle. Could be used if more than one thread is using this function block.
 */
static void AppControllerFire(void* pvParameters)
{
    BCDS_UNUSED(pvParameters);
    Retcode_T retcode = RETCODE_OK;

    if (RETCODE_OK == retcode)
	{
		retcode = WlanConnect_Init();
	}
    /* code to implement application control flow */
	printf("*****************************************************************\n\r");
	printf("seting up wlan \n\r");

	retcode = WlanConnect_WPA(WLAN_SSID, WLAN_PW ,0);

	if (RETCODE_OK == retcode)
	{
		printf("Erfolgreich mit WLAN verbunden\n\r");
	}
	else
	{
		printf("Fehler bei der Verbindung zum WLAN\n\r");
	}

	retcode = NetworkConfig_SetIpDhcp(0);

	if (RETCODE_OK == retcode)
	{
		printf("IP via DHCP erfolgreich\n\r");
	}
	else
	{
		printf("IP via DHCP FEHLER\n\r");
	}
	;
	doSNTP();
    /* A function that implements a task must not exit or attempt to return to
     its caller function as there is nothing to return to. */
    while (1)
    {
    	printf("T\r\n");
		vTaskDelay(SECONDS(5));
    }
}

/**
 * @brief To enable the necessary modules for the application
 *
 * @param [in] param1
 * A generic pointer to any context data structure which will be passed to the function when it is invoked by the command processor.
 *
 * @param [in] param2
 * A generic 32 bit value  which will be passed to the function when it is invoked by the command processor..
 */
static void AppControllerEnable(void * param1, uint32_t param2)
{
    BCDS_UNUSED(param1);
    BCDS_UNUSED(param2);
    Retcode_T retcode = RETCODE_OK;

    /* @todo - Enable necessary modules for the application and check their return values */
    if (RETCODE_OK == retcode)
    {
        if (pdPASS != xTaskCreate(AppControllerFire, (const char * const ) "AppController", TASK_STACK_SIZE_APP_CONTROLLER, NULL, TASK_PRIO_APP_CONTROLLER, &AppControllerHandle))
        {
            retcode = RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_OUT_OF_RESOURCES);
        }
    }
    if (RETCODE_OK != retcode)
    {
        printf("AppControllerEnable : Failed \r\n");
        Retcode_RaiseError(retcode);
        assert(0); /* To provide LED indication for the user */
    }
}

/**
 * @brief To setup the necessary modules for the application
 *
 * @param [in] param1
 * A generic pointer to any context data structure which will be passed to the function when it is invoked by the command processor.
 *
 * @param [in] param2
 * A generic 32 bit value  which will be passed to the function when it is invoked by the command processor..
 */
static void AppControllerSetup(void * param1, uint32_t param2)
{
    BCDS_UNUSED(param1);
    BCDS_UNUSED(param2);
    Retcode_T retcode = RETCODE_OK;

    /* @todo - Setup the necessary modules required for the application */

    retcode = CmdProcessor_Enqueue(AppCmdProcessor, AppControllerEnable, NULL, UINT32_C(0));
    if (RETCODE_OK != retcode)
    {
        printf("AppControllerSetup : Failed \r\n");
        Retcode_RaiseError(retcode);
        assert(0); /* To provide LED indication for the user */
    }
}

/* global functions ********************************************************* */

/** Refer interface header for description */
void AppController_Init(void * cmdProcessorHandle, uint32_t param2)
{
    BCDS_UNUSED(param2);

    Retcode_T retcode = RETCODE_OK;

    if (cmdProcessorHandle == NULL)
    {
        printf("AppController_Init : Command processor handle is NULL \r\n");
        retcode = RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_NULL_POINTER);
    }
    else
    {
        AppCmdProcessor = (CmdProcessor_T *) cmdProcessorHandle;
        retcode = CmdProcessor_Enqueue(AppCmdProcessor, AppControllerSetup, NULL, UINT32_C(0));
    }

    if (RETCODE_OK != retcode)
    {
        Retcode_RaiseError(retcode);
        assert(0); /* To provide LED indication for the user */
    }
}

/**@} */
/** ************************************************************************* */

The outcome looks like: 

INFO | XDK DEVICE 1: *****************************************************************
 INFO | XDK DEVICE 1: seting up wlan 
 INFO | XDK DEVICE 1: Erfolgreich mit WLAN verbunden
 INFO | XDK DEVICE 1: IP via DHCP erfolgreich
 INFO | XDK DEVICE 1: Sntp_intialize
 INFO | XDK DEVICE 1: Sntp_start
 INFO | XDK DEVICE 1: asserted at Filename 3rd-party/FreeRTOS/Source/queue.c , line no  1392 
 INFO | XDK DEVICE 1: Error in ServalPAL package.
 INFO | XDK DEVICE 1: 	Package ID: 30	Module ID: 8	Severity code: 2	Error code: 1

 

 

0 (0 투표)
RE: Get Current Time
응답
18. 10. 10 오후 2:24 as a reply to Sven Kabitzki.
Hello Sven,

thank you for providing your source code, this helped to find a solution.

Since this is a ServalPal error, it is necessary to add #include "BCDS_ServalPal.h" and #include "BCDS_ServalPalWifi.h" to your include section of your source code.

Also, a ServalPal setup is required.
The knowledgebase offers a great HTTP guide, which includes the mentioned ServalPal setup within a full code example.
To access this guide, a free registration as knowledge base user is required. Follow up this step by a click on the top menu the button KNOWLEDGE BASE . On the left menu, choose Protocols and HTTP .

Another issue within your code is the direct UML address within #define SNTP_DEFAULT_ADDR "0.de.pool.ntp.org" .
At this point, the XDK expects an IPv4 address.
#define SNTP_DEFAULT_ADDR "5.9.59.78" worked well in my scenario and directed to the 0.de.pool.ntp.org address.

Another major issue is a missing delay within your code, after the function doSNTP .

To solve this, I suggest you to separate Sntp_initialize and Sntp_start from NetworkConfig_GetIpAddress and Sntp_getTime , which require a delay after calling.
Due to your while loop's content, I assume you want to print the timestamp periodically. If you put a delay of a few seconds and NetworkConfig_GetIpAddress and Sntp_getTime inside the while loop, it will constantly print the timestamp to your console.

Please let me know if this was helpful and feel free to ask if you have further questions.

Kind regards,
Franjo
0 (0 투표)
RE: Get Current Time
응답
18. 10. 15 오전 11:13 as a reply to Franjo Stjepandic.

Hello Franjo,

thanks for your response. 

i tried and took your suggestions in account and its works now. 

Guess i need to dive deeper into the serval package as its function is not clear to me right now;-) 

BTW. now it works with the hostname too. 

Funny you mentioned the http example as i experience some problems there too :-) 

i will have a look, if your suggestions here, help me there ;-) 

kind regards

sven

0 (0 투표)
RE: Get Current Time
응답
18. 10. 15 오후 3:08 as a reply to Sven Kabitzki.
Hello Sven,

thank you for providing the positive feedback.
I am glad my earlier post helped you to make it work.

If the problem with the http example still contains, I am sure we will find a solution for this, too.

Please feel free to ask if you have any kind of further questions.

Kind regards,
Franjo
0 (0 투표)