[Submission] Real Time Clock Library for Spark

Blinking red means that your firmware has done a panic, or major error. The pattern of flashes tells you what error it is. It should be SOS (… — …) followed by a number of flashes, and then SOS again. If the number of flashes is 8, then you are running out of RAM, which is the most common kind of panic. There are other kinds of panic’s too.

I hope you have the most recent version of SparkTime since I reduced the amount of RAM used this week. UDP and TCP both use a good bit of RAM and folks have found it hard to use both at the same time, even without any other libraries. This is an area where the Spark team recognizes that there is a problem but we need to figure out how to reduce the RAM requirements of all the great features we have now.

If you can post your code, we can likely figure it out!

Yes the number of flashes are 8.

Concerning the version of SparkTime that I use the latest version, the one that is today in your github. Today was the first time I used your library.

My actual code is

#include "SparkTime.h"


UDP UDPClient;
SparkTime rtc;

int lamp = D0;


void setup() {

pinMode(lamp,OUTPUT);
digitalWrite(lamp,LOW);


rtc.setUseEuroDSTRule(true);

}

void loop() {

unsigned long currentTime = rtc.now();


if (rtc.hour(currentTime)==5) {  //all of the 5am hour
    digitalWrite(lamp,HIGH);
} else if (rtc.hour(currentTime)==6 && rtc.minute(currentTime)<50) { // from 6:00 to 6:49:59
    digitalWrite(lamp,HIGH);
} else {
    digitalWrite(lamp,LOW);
}

}

The code compiles and upload effectively but then it starts with the red blinking.
Although when I upload your code from the SparkTimeExample.cpp it works fine.

Hi @schvic

You forgot the initialize the rtc and optionally set the timezone. Try this:

// This #include statement was automatically added by the Spark IDE.
#include "SparkTime.h"


UDP UDPClient;
SparkTime rtc;

int lamp = D0;


void setup() {
    
pinMode(lamp,OUTPUT);
digitalWrite(D0,LOW);

rtc.begin(&UDPClient, "pool.ntp.org");
rtc.setTimeZone(0); // gmt offset
rtc.setUseEuroDSTRule(true);

}

void loop() {

unsigned long currentTime = rtc.now();

if (rtc.hour(currentTime)==5) {  //all of the 5am hour
    digitalWrite(lamp,HIGH);
} else if (rtc.hour(currentTime)==6 && rtc.minute(currentTime)<50) { // from 6:00 to 6:49:59
    digitalWrite(lamp,HIGH);
} else {
    digitalWrite(lamp,LOW);
}

delay(100);

}

I set the gmt offset to 0 and added a small delay at the bottom of loop since the time changes only very second.

Perfect, it works perfectly.

Thank you very much @bko .

1 Like

Worked very well. Thank you @bko!

1 Like

Hye @bko,
I would like compile your NTP Client project with my project (https://github.com/captainigloo/sparkcore-local-http-server-rest-json), but it’s impossible to flash spark core.
What’s the problem ? Problem of ressouces ?

HI @CaptainIgloo

Yes, it could be resources. What error did you get?

Lot of folks have reported that having a TCP connection for say HTTP and a UDP connection for NTP required too much RAM. It is also possible you are out of flash.

If you build locally you can get a lot more data about flash and RAM usage, so when you have a project that is close to the limits, that is a better way to go. I looked at your project git and there is way too much code for me to quickly figure out what might be wrong, but I see a lot of stack allocated arrays and some malloc in the code, and I would urge you in general to look at your memory footprint and try to reduce it.

You should also make sure you have my latest version since around the first of April I moved some code around to make sure the constant strings ended up in flash and not RAM.

Finally the Spark team is working on using the internal RTC on the STM32 chip and setting it from the cloud. That work is largely done but will not come to the webIDE for a while. When that comes in, the need for NTP time will reduce.

No error message, no flash magenta, and display ready.

OK, so you are probably going to have to set up a local build environment to figure it out.

My library uses less than 200 bytes of RAM but UDP allocates a 1024 byte buffer and so does TCP, so that is more than half the available RAM right there. Looking your git, I would definitely say that RAM is going to be an issue.

Ok thank you.
I am not a specialist in development.
I’ll wait for the cloud function because I do not want to change the http server.

bko, I did a local compile of the “package” and it shows:

text data bss dec hex filename
98684 2996 13076 114756 1c044 core-firmware.elf

So there is plenty of room in flash but the STATIC memory allocation (2996+13076) is 0x3EC8. My experience tells me that at 0x4000, the Spark starts having memory issues. So my guess is that there is a DYNAMIC memory allocation problem that pushes the RAM over the edge. Normally, however, I see a panic when that happens but Captainlgloo says he sees nothing! I will flash the code to a core to see if I get anything different. NOTE: I am using the latest (as of a few minutes ago) master.

1 Like

If I add the NTP client in my project http server, I see nothing in web compilation (no error, no led magenta, and web IDE return “Ready”), but I did not try the local compilation

When I looked at code on github, there were a lot of #define <<some buffer size>> 512 and I pretty much stopped looking after that.

@bko, thanks, I reduced all bufer to 256 bytes. I will test later.

Hi,
I confirm dysfunction tcpserver with tcpclient. Whatever the project the two do not work together.

1 Like

For those who have been doing cool stuff with RTC,

the firmware-side code to update via the cloud is done!

Just give the :spark: team some time before the server-side code gets pushed as well :smiley:

2 Likes

Hey :spark: s, I was wondering if any progress has been made on the NTP/RTC stuff, it’s an interesting feature, and I’m sure a lot of people can’t wait to start using it :wink: Any updates?
Thanks in advance!

I’ve been trying to figure out how to keep the relay open for a specific amount of time, based on the current time. So if its 11am, I’d like to keep the relay open for 1 min 10sec. This is what I’ve been using, but it always stays open for 1 minute regardless.

Maybe there is a better way to do this?

unsigned long currentTime = rtc.now();

if (rtc.hour(currentTime)==11 && rtc.minute(currentTime)==00 && rtc.second(currentTime)>00) {
    digitalWrite(RELAY1,HIGH);
} else if (rtc.hour(currentTime)==11 && rtc.minute(currentTime)==01 && rtc.second(currentTime)==10) { 
    digitalWrite(RELAY1,LOW);
} else {
    digitalWrite(RELAY1,LOW);
}

Try this:

unsigned long currentTime = rtc.now();

if (rtc.hour(currentTime)==11 && rtc.minute(currentTime)==00 && rtc.second(currentTime)>00) {
    digitalWrite(RELAY1,HIGH);
} else if (rtc.hour(currentTime)==11 && rtc.minute(currentTime)==01 && rtc.second(currentTime)<=09) {
    digitalWrite(RELAY1,HIGH); 
} else if (rtc.hour(currentTime)==11 && rtc.minute(currentTime)==01 && rtc.second(currentTime)==10) { 
    digitalWrite(RELAY1,LOW);
} else {
    digitalWrite(RELAY1,LOW);
}

or another way:

unsigned long currentTime = rtc.now();
static unsigned long stopTime = 0;

if (rtc.hour(currentTime)==11 && rtc.minute(currentTime)==00 && rtc.second(currentTime)==00) {
    digitalWrite(RELAY1,HIGH);
    stopTime = currentTime + (60+10);  //one minute and ten seconds
}

if (currentTime >= stopTime) {
    digitalWrite(RELAY1,LOW);
}

Both worked perfect, I like the ladder a bit better. Is it possible to do days of the week as well?