Spark function and a loop


#1

Hi,

I am new to Spark and am experienced with Arduino and so I am not a total newbie. However, I have a question about Spark functions that I do not fully comprehend and was hoping to get expert views.

I have been playing with with the blink code and triggering it via the REST commands. I wrote the following two functions for test purposes.

int blink(String args2){
    Serial.println("Entering blink loop");
    while(1)
     digitalWrite(led2, LOW); 
     delay(1000);               // Wait for 1 second in off mode
     digitalWrite(led2, HIGH);
     delay(1000); 
    }
    Serial.println("Exit blink loop");
    return 10;
}

int blinkoff(String args1){
    Serial.println("Entering blinkoff");
    digitalWrite(led2, LOW);
    Serial.println("Exiting blinkoff");
    return 20;
}

I was trying to understand how the Spark REST protocol handles loops. I find a couple of interesting elements of this code.

  1. The API times out in the Blink function because it never reaches the “return 10.” (This is obvious because the loop prevents it from reaching the return.) Is this a problem? It seems problematic that the browser just sits and waits forever.
  2. If I close the window in 1 and then run “blinkoff,” I see the LED turn off briefly and then resume blinking. It appears that the Spark remains in the blink loop in perpetuity and that the blinkoff routine has no effect long-term effect.

Here are my questions:

  1. Should perpetual loops ever be used in Spark functions?
  2. Is there any way to return a JSON value inside of a loop in the API? (Using return will kick you out of the function and hence the loop.)
  3. Once a loop is running in a Spark function is there any way to stop it remotely via the REST API?

Thank you for any assistance and sorry if these are newbie-ish. I am trying to get my head around Spark and how I will use it.


#2

I think the best approach is to treat Spark.function()'s like you would an interrupt handler: do the minimum work that you can in the handler itself and post flags that you check back in the main loop.

So in particular, I would not do while(1) {...} in a Spark.function() or interrupt handler but neither would I routinely do the Serial.println() which can take a long time (several milliseconds at say 9600 baud) other that for debugging.

Your second function, minus the debugging Serial.println()'s is more in keeping with best practices.

Just like on Arduino, the return value of loop() is ignored (it is declared void), so in order to return a JSON, use a Spark.variable() with a string. You can use a Spark.function() to trigger an update to the JSON variable or you can use Spark.publish() to let the web side know that the variable was updated, depending on how you compute the values. You can also use Spark.publish() directly to send a JSON to the web side and I have a tutorial showing you how to do that here in the forum.


#3

Brian, thank you so much! Your explanation makes total sense. It is particularly timely because I just finished exploring Arduino interrupts and so my knowledge is fresh. For anyone else interested in this topic, here is the updated code that works perfectly and better follows best practices as described by Brian.

int led2 = D7;
boolean blinknow = false;

void setup() {
  pinMode(led2, OUTPUT);
  digitalWrite(led2,LOW);
  Spark.function("blinkon", blink);
  Spark.function("blinkoff", blinkoff);
}

void loop() {
    if (blinknow){
        digitalWrite(led2, HIGH); 
        delay(1000);
        digitalWrite(led2, LOW);
        delay(1000);   
    }
}

int blink(String args2){
    blinknow = true;
    return 10;
}

int blinkoff(String args1){
    blinknow = false;
    return 20;
}

#4

Nicely done.

You could also do away with all of those “delays” and use a comparrison against the millis() function. My library, which is just posted, RGBEffect does that.

Here’s a gist of something similar to what you did using the library: https://gist.github.com/harrisonhjones/d315732f278cd523b1bf

You can grab the library files here: https://github.com/harrisonhjones/RGBEffect