When do Spark.functions run

Hi, quick question, if you have the loop function on your core whizzing round and round doing stuff and suddenly a Spark.function gets called say from a web page, does the loop function pause while the Spark.function is serviced a bit like an interrupt function call ?

At the end of loop() a bunch of other functions are called which maintain the connection to the cloud and handle things like Spark.Function(). Once that’s over loop() is called again. Make sense?

To extend Harrison’s answer a bit.

The default name of the function loop() is a bit misleading, since it not actually behaves like a loop at all - or rather only like a loop that always ever runs one iteration :wink:
But it is inside another bigger (“hidden”) endless loop that does things before and after and in between calls the function that’s called loop().

One of the things the outside loop does is to look if the cloud wants to trigger a call to a Spark.function or wants to know about the current content of a Spark.variable and branches or acts accordingly.

So in fact you can’t be sure how often loop() will do its job, since the outside loop needs “unpredictably” long to call loop() again.

And if you ask, why then is it called loop() at all - that’s what wiring compatibility requires.

Oh, ok, that’s useful to know, so it’s like the user stage of a cycle, then there’s the system stage and then back to the users turn :slight_smile:

Important to know if the user part is doing a lot and takes a long time to complete as the pending Spark.function/variable request would take a while until it’s serviced by the outer loop.

Exactly :+1:

And from your reaction I gather you also haven’t heard of the 10sec limit.
If you code prevents the “system stage” to do its job more than that the cloud connection will drop out. To avoid that, you’d have to explicitly call SPARK_WLAN_Loop() or Spark.process() during long running sections of your code.
If you only want to do long delays, the delay() function does call SPARK_WLAN_Loop() about once per second.

Ahh, that may explain a problem I’ve been experiencing, I’m using TCPClient in the loop to send a GET to a server, the servers reaction is to call a Spark.function. I’ve been experiencing a rapid flashing cyan LED sometimes, I assume then that it may be caused by the TCP request taking longer than 10 seconds to connect/complete, code below for reference.

TCPClient client;

#define server "someServer.com"
int dayLastSynced = 0;
int lastReq = 0;

void setup() {
  Serial.begin(9600);
  Spark.syncTime();
  Spark.function("rx_rules", receiveRules);
}

void printTime()
{
    Serial.print(Time.hour());
    Serial.print(":");
    Serial.print(Time.minute());
    Serial.print(":");
    Serial.print(Time.second());
    Serial.print(" ");
    Serial.print(Time.day());
    Serial.print("/");
    Serial.print(Time.month());
    Serial.print("/");
    Serial.println(Time.year());
}

void requestRules(int hour)
{
    bool connected = false;
    while (!connected) 
    {
	if(client.connect(server, 80))
	{
	    connected = true;
	    Serial.println("connected");
	    client.println(printf("GET /somePage.php?hour=%i HTTP/1.0", hour));
	    client.println("Host: " server);
	    client.println("Content-Length: 0");
	    client.println();
	    delay(2000);
	    client.stop();
	} 
	else 
	{
	    Serial.println("connection failed");
	    delay(200);
	}
    }
}

int receiveRules(String args)
{
    Serial.println(args);
}

void loop() {
    delay(10000);

    if(dayLastSynced != Time.day())
    {
	Serial.print("Synced time at :");
	printTime();
	Spark.syncTime();
	dayLastSynced = Time.day();
    }

    if(Time.hour() != lastReq)
    {
	Serial.print("Requested rules at :");
	printTime();
	requestRules(Time.hour());
	lastReq = Time.hour();
    }
}

Yes, this might well be.

So if you just add a SPARK_WLAN_Loop(); within your while() { } this might go away.

I guess this should do it, just under the else block :smile:

 /*
add this because the spark core needs to service the cloud connection every 10 seconds and if
 this loop function takes longer than ten seconds it will cause a cloud reconnect if SPARK_WLAN_Loop isn't called
*/
    if((millis() - wlanTime) > 8000)
    {
        SPARK_WLAN_Loop();
        wlanTime = millis();
    }