Spark Core in car blinks red and restarts frequently

I’m using a Spark Core to monitor an engine in a car.

Obviously for such an application the Core cannot always be connected to the cloud. Instead, the measurements are collected, accumulated and saved in the Flash. The accumulated result is published as an event to the Spark cloud every minute whether or not there is a connection. So as soon as the car goes back to a parking spot with WiFi the results get uploaded.

I’m using the SEMI_AUTOMATIC system mode to make sure my code runs at boot.

When the car drives out of WiFi range, the LED starts blinking green as expected.

However, once every minute or so the LED blinks red multiple times (10 times, then off for a second, then 10 times, then some more). The core then restarts. What could cause this?

Has anyone else been successful with an application where the cloud connection is by design not present all the time? How do you set up the Core so it doesn’t panic and restart every once because it can’t connect to the cloud?

I will eventually look at deep sleep and WiFi off to avoid running down the car battery when the engine’s off, but for now I’m focused on getting the Core to work with the engine on.

Thanks for your insight.

1 Like

I would not even try to publish when there is no connection.
Calling Spark.publish() could well cause your red blink. Why not check for Spark.connected() and only publish if possible?

I would also purposefully connect and disconnect to WiFi and cloud and not just have it permanently try to connect, since the recurring connection attempts do suck up some of your precious processing time, which could be put to better use monitoring your engine.

3 Likes

Thanks for the advice about Spark.connected(). When I looked at the docs for Spark.publish, it seemed that calling the method when the cloud is disconnected was allowed and should simply return false.

Calling Spark.publish() when the device is not connected to the cloud will not result in an event being published. This is indicated by the return success code of false.

If the device restarts when calling publish when the cloud is disconnected, it sounds like a firmware bug.

This would cause unexpected restarts in a lot of user’s programs whenever their internet connection was down if the program doesn’t check if the device is online before doing publish.

What do you think?

Regarding disconnecting from WiFi, that’s what I want to look at as a 2nd step when my program works with the WiFi on all the time.

So far that was no issue for me, since I’m used to defensive programming :wink:
But sure, if this is stated you should be able to rely on it.
If you could test my suspission and if it turns out to solve your problem, you could either file an issue for that, or report back on this thread and I’ll tick that in for you.

1 Like

IMO Spark.publish() should fail-safe in all cases. The device could get disconnected from the cloud between < whatever check is made> and the call to Spark.publish() due to events beyond any local control.

3 Likes

@AndyW, my thoughts exactly.

@ScruffR, I added the Spark.connected() check and now the program doesn’t restart anymore.

I’ll write a small program to duplicate the issue I was having and post the results back here.

Actually looking at firmware/src/spark_utilities.cpp the various SparkClass::publish return void so the documentation comment that Spark::publish() returns false is wrong. I could submit a PR to the firmware repository to at least make Spark::publish() return the value from spark_protocol.send_event.

Is the master branch (Spark Core only) of the firmware repository still being updated or is all work being done on develop (Core and Photon), i.e. is a PR for master still appropriate?

I ran a few tests. The Spark Core restarts with red blinking lights when calling Spark.publish() before the first successful connection to the cloud. It is OK to call Spark.publish() after the connection drops as long as it was connected once before.

I think the firmware should protect the user against this corner case by checking if the initial connection was done before trying to publish.

Here are the details:

Code variant 1: Call publish before cloud connection is complete

SYSTEM_MODE(SEMI_AUTOMATIC);

void setup() {
  Serial.begin(115200);
  delay(2000);
  Serial.println("Program starting");
  Spark.connect();
  Serial.println("Cloud connect done");
}

void loop() {
    Serial.println("connected=" + String(Spark.connected()));
    Serial.println("Publishing");
    Spark.publish("event");
    Serial.println("Publish done");
    delay(1000);
}

Output variant 1

2015-06-03 15:29:55 -0400 Program starting
2015-06-03 15:29:57 -0400 Cloud connect done
2015-06-03 15:29:57 -0400 connected=0
2015-06-03 15:29:57 -0400 Publishing
2015-06-03 15:30:10 -0400 Program starting
2015-06-03 15:30:12 -0400 Cloud connect done
2015-06-03 15:30:12 -0400 connected=0
2015-06-03 15:30:12 -0400 Publishing
2015-06-03 15:30:25 -0400 Program starting

Results variant 1

The program restarts when calling Spark.publish() since the connection was initiated but the cloud handshake wasn’t finished. You get the same results if you don’t call Spark.connect() at all.

Code variant 2: Don’t call publish when there is no cloud connection

SYSTEM_MODE(SEMI_AUTOMATIC);

void setup() {
  Serial.begin(115200);
  delay(2000);
  Serial.println("Program starting");
  Spark.connect();
  Serial.println("Cloud connect done");
}

void loop() {
    Serial.println("connected=" + String(Spark.connected()));
    if(Spark.connected()) {
        Serial.println("Publishing");
        Spark.publish("event");
        Serial.println("Publish done");
    } else {
        Serial.println("Not publishing");
    }
    delay(1000);
}

Output variant 2

2015-06-03 15:41:02 -0400 Program starting
2015-06-03 15:41:04 -0400 Cloud connect done
2015-06-03 15:41:04 -0400 connected=0
2015-06-03 15:41:04 -0400 Not publishing
2015-06-03 15:41:06 -0400 connected=1
2015-06-03 15:41:06 -0400 Publishing
2015-06-03 15:41:06 -0400 Publish done
2015-06-03 15:41:07 -0400 connected=1
2015-06-03 15:41:07 -0400 Publishing
2015-06-03 15:41:07 -0400 Publish done
2015-06-03 15:41:08 -0400 connected=1
2015-06-03 15:41:08 -0400 Publishing
2015-06-03 15:41:08 -0400 Publish done
2015-06-03 15:41:09 -0400 connected=1
2015-06-03 15:41:09 -0400 Publishing
2015-06-03 15:41:09 -0400 Publish done
2015-06-03 15:41:10 -0400 connected=1
2015-06-03 15:41:10 -0400 Publishing
2015-06-03 15:41:10 -0400 Publish done

Results variant 2

The defensive programming approach suggested by @ScruffR to check for Spark.connected() avoids issues here.

Code variant 3: Wait for initial connection then always publish

SYSTEM_MODE(SEMI_AUTOMATIC);

void setup() {
  Serial.begin(115200);
  delay(2000);
  Serial.println("Program starting");
  Spark.connect();
  Serial.println("Cloud connect done");
  
  while(!Spark.connected()) {
      delay(1000);
  }
}

void loop() {
    Serial.println("connected=" + String(Spark.connected()));
    Serial.println("Publishing");
    Spark.publish("event");
    Serial.println("Publish done");
    delay(1000);
}

Output variant 3

2015-06-03 15:53:44 -0400 Program starting
2015-06-03 15:53:46 -0400 Cloud connect done
2015-06-03 15:53:48 -0400 connected=1
2015-06-03 15:53:48 -0400 Publishing
2015-06-03 15:53:48 -0400 Publish done
2015-06-03 15:53:49 -0400 connected=1
2015-06-03 15:53:49 -0400 Publishing
2015-06-03 15:53:49 -0400 Publish done
...
2015-06-03 15:53:57 -0400 connected=1
2015-06-03 15:53:57 -0400 Publishing
2015-06-03 15:53:57 -0400 Publish done
***************************************WiFi turned off here
2015-06-03 15:53:58 -0400 connected=0
2015-06-03 15:53:58 -0400 Publishing
2015-06-03 15:53:58 -0400 Publish done
2015-06-03 15:53:59 -0400 connected=0
2015-06-03 15:53:59 -0400 Publishing
2015-06-03 15:53:59 -0400 Publish done
...
2015-06-03 15:54:52 -0400 connected=0
2015-06-03 15:54:52 -0400 Publishing
2015-06-03 15:54:52 -0400 Publish done
2015-06-03 15:54:54 -0400 connected=0
2015-06-03 15:54:54 -0400 Publishing
2015-06-03 15:54:54 -0400 Publish done
***************************************WiFi turned on here
2015-06-03 15:54:56 -0400 connected=1
2015-06-03 15:54:56 -0400 Publishing
2015-06-03 15:54:56 -0400 Publish done
2015-06-03 15:54:57 -0400 connected=1
2015-06-03 15:54:57 -0400 Publishing
2015-06-03 15:54:57 -0400 Publish done

Results variant 3

Even though the WiFi connection drops, the program doesn’t restart.

1 Like

In 0.4.0 that’s what happens. We’re just waiting for all the fixes since 0.3.4 to be available on the core. Which is expected before the end of the month.

3 Likes

Thanks for the update @mdma. I’m eagerly waiting for the update and my Photons :smile: