Ok, the 60 second delay may have been something I really missed, early on. Aside from downloading the initial program, I don’t need my spark to be connected to the cloud. In fact, unless the power resets (and the ‘clock’ gets out of sync) I don’t see any reason to connect to the cloud except at initialization. Why would a 60 second delay cause the core to lose its connection? Why should I care? If there’s a good reason, I want to understand it. If the only reason is that the core likes to stay connected to the mothership, there should be a way to disable that, right?
I’ve gone back to the drawing board to try and implement your recommended controls and get rid of the stopping delays. This all very helpful and I’m learning a ton by trying to make this code my own. Thanks for all your help!
As a side question: What difference does it make if I declare stuff before the setup() function as opposed to inside the setup function? If there’s no difference, is there a best practice? Should I be declaring all my variables and stuff within the setup() function? Is it a matter of personal preference/readability?
Here’s what I have now
UDP UDP;
int houron = 8;
int houroff = 11;
char string[ 17 ] = { "" };
int hour, minute, second;
int led = D0;
unsigned int localPort = 123;
unsigned int timeZone = -6; //tz offset
const char timeServer[] = "pool.ntp.org";
const int NTP_PACKET_SIZE= 48;
byte packetBuffer[NTP_PACKET_SIZE];
int ntpsent = 0; //number of ntp requests sent
int ntplistened = 0; //number of times we've listened for an ntp response
int synced = 0;
unsigned int offset = 0;
unsigned long secsSince1900 = 0;
void setup()
{
UDP.begin(localPort);
RGB.control(true);
pinMode(led, OUTPUT);digitalWrite(led, LOW); //set it to be off initially
}
void loop()
{
if (!synced) {
RGB.color(255, 0, 0); //red indicates not sync'd
if (!ntpsent || ntplistened >= 3000) {sendNTPpacket(timeServer);} //send request if not yet req'd or if no response in 3000 loops
receiveTimeTick(); //try to read a response
}
if (synced) {
RGB.color(0, 255, 0); //green indicates sync'd
const unsigned long seventyYears = 2208988800UL;
unsigned long epoch = secsSince1900 - seventyYears;
epoch += ((millis() - offset) / 1000.0);
hour = (epoch % 86400L) / 3600;minute = (epoch % 3600) / 60;second = (epoch % 60); //calculate h, m, & s
if (second <= (houron - 1)) {digitalWrite(led, LOW);} //if before 8am, turn off LED
if (second >= houron && second <= (houroff - 1)) {digitalWrite(led, HIGH);} //if between 8:00am and 10:59am, turn on LED
if (second >= houroff) {digitalWrite(led, LOW);} //if after 11am, turn of LED
delay(1000); //in no hurry here since we're waiting for time to pass, but don't stop too long
}
}
unsigned long sendNTPpacket(const char *address)
{
memset(packetBuffer, 0, NTP_PACKET_SIZE);
packetBuffer[0] = 0b11100011;packetBuffer[1] = 0;packetBuffer[2] = 6;
packetBuffer[3] = 0xEC;packetBuffer[12] = 49;packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;packetBuffer[15] = 52;UDP.beginPacket(address, 123);
UDP.write(packetBuffer, NTP_PACKET_SIZE);UDP.endPacket();
ntpsent += 1;ntplistened = 0;
}
void receiveTimeTick() {
ntplistened += 1;
if ( UDP.parsePacket() ) {
UDP.read(packetBuffer, NTP_PACKET_SIZE);
unsigned long highWord = (packetBuffer[40] << 8) + packetBuffer[41];
unsigned long lowWord = (packetBuffer[42] << 8) + packetBuffer[43];
secsSince1900 = highWord << 16 | lowWord;
secsSince1900 += timeZone*60*60;
offset = millis();
synced = 1;
}
while ( UDP.parsePacket() ) {UDP.read(packetBuffer, NTP_PACKET_SIZE);}
//delay(1000); //do i need a delay here just to make sure all 3000 loops don't happen too quickly?
}