Can the Spark Core trigger the Reset Pin?

I have a spark core and I’m using it now to push sensor data to Xivley which works fine as long as there are no CC3000 issues that pop up that kills the connection or freezes the Spark Core.

I have read that sometimes the code in the main loop still runs when this CC3000 Errors happen and sometimes it just freezes the loop.

If I could get the Spark Core to reset every 5 - 10 mins automatically then I would have a working solution. Every time I reset the Spark Core it successfully connects to my Wifi network and the Spark Cloud, so if I can automate the the reset to happen ever 10 mins that means I would never have more than a 10 min gap between data transmissions to Xivley which would be fine for what I’m doing right now. This would give me a working solution until they figure out a fix for the current issues.

So all you guys out there smarter than me I’m asking you if there is a way to program the Spark Core to reset it self (Cycle OFF and then back ON) at any predetermined time frame like ever 5 or 10 mins?

Or does this automated function need to happen by another circuit that controls the power that feeds the Spark Core?

@RWB this is an excellent question that I’ve been meaning to find the answer to… Most microcontrollers have a software reset command that can be called. A little digging and I found the one the Core has, and created this example:

uint32_t lastReset = 0; // last known reset time
bool s = true;

void setup()
{
  lastReset = millis(); // We just powered up
  pinMode(D7, OUTPUT);
}

void loop() {
  // Run some test code so we know the core is running!
  digitalWrite(D7,s);
  s = !s; // toggle the state
  delay(100); // makes it blinky
  
  // Is it time to reset?
  if( tenMinutesElapsed() ) {
    // Software Reset
    NVIC_SystemReset();
  }
} // End main loop (currently runs every 5-6 ms)

uint8_t tenMinutesElapsed() {
  if( (millis()-lastReset) > (10*60*1000) ) {
    lastReset = millis();
    return 1; // 10 minutes has elapsed
  } else {
    return 0; // nope, not yet be patient!
  }
}

Note this does reset the STM32, and should technically be the same as pressing the reset button as far as the CC3000 is concerned.

If your code locks up in the main loop, this won’t reset it.

There should be a watchdog timer running in the STM32 already to check for code that blocks for over 10-15 seconds. The Cloud Handshake code might be interrupting and performing this Soft Reset already (I’m not sure), but there should be a hardware peripheral watchdog timer that basically does the same thing after a certain time of code not executing.

If you want to really want to PRESS the reset button every 10 minutes no matter what, you’ll need some external hardware/software to do this. An ATTiny4 would be perfect… super small, internal osc. and can be programmed to output LOW for 100ms every 10 minutes pretty easily. Lot’s of ways to do this. Again, you should not need this external hardware if the STM32 has a watchdog timer enabled.

Awesome, I am grateful for your feedback. I do not have the technical knowledge currently to understand this nearly as well as you do, so your help is greatly appreciated.

I'm willing to test this code out and post the results good or bad. I'll try to figure out if the main loop is stalling when the CC3000 freezes up or not.

I just need to know how I should integrate your code above with my current sketch so it should work correctly.

I just had to rest my Spark Core 2 times in the last 3 hours due to it freezing up from the Cyan Flash the first time, and then the green flash the second time.

I've been sending data to Xivley for about 2 days now just testing how everything is working now with my Cell phone being my WiFi Hotspot.

Here is my current code:

define FEED_ID "1234" //note: fake id here..
define XIVELY_API_KEY "1234" //note: fake key here

TCPClient client;

int reading = 0;
int ledD = D7;

int count = 0;
int total_temp = 0;
int temp_calc = 0;
unsigned long LastUpTime = 0;
unsigned long LastCloudCheck = 0;
char whichApp[64] = "READ TEMPERATURE with XIVELY";

// This routine runs only once upon reset
void setup()
{
//Register our Spark function here
Spark.variable("whichapp", &whichApp, STRING);
Spark.variable("reading", &reading, INT);
Spark.function("degres", tempCalculation);
Spark.function("volt", analogReading);
pinMode(A7, INPUT);
pinMode(ledD, OUTPUT);
ledStatus(5, 100); //Blink
}

void loop()
{
reading = analogRead(A7);
temp_calc = (reading*3.3/4095)*100 - 50;

   if (millis()-LastUpTime>1000)
   {
      if (count <= 5) {
          total_temp += temp_calc; 
          count++;
      }
      else {          
              xivelyTemp(total_temp/count); //Send the average of the last 5 readings
              count = 0;
              total_temp = 0;
      }
      LastUpTime = millis();
   }
   if (millis()-LastCloudCheck > 1000*60*5) { //check every 5 min to see if the connection still exists
       if(!Spark.connected()) Spark.connect();
       LastCloudCheck = millis();
   }

}

void xivelyTemp(int temperature) {

ledStatus(5, 100);
//Serial.println("Connecting to server...");
if (client.connect("api.xively.com", 8081))
{
// Connection succesful, update datastreams
client.print("{");
client.print(" "method" : "put",");
client.print(" "resource" : "/feeds/");
client.print(FEED_ID);
client.print("",");
client.print(" "params" : {},");
client.print(" "headers" : {"X-ApiKey":"");
client.print(XIVELY_API_KEY);
client.print(""},");
client.print(" "body" :");
client.print(" {");
client.print(" "version" : "1.0.0",");
client.print(" "datastreams" : [");
client.print(" {");
client.print(" "id" : "bedroom_temp",");
client.print(" "current_value" : "");
client.print(temperature-8); //adjustment for some weird reason..
client.print(""");
client.print(" }");
client.print(" ]");
client.print(" },");
client.print(" "token" : "0x123abc"");
client.print("}");
client.println();

    ledStatus(3, 1000);        
} 
else 
{
    // Connection failed
    //Serial.println("connection failed");
    ledStatus(3, 2000);
}
if (client.available()) 
{
    // Read response
    //char c = client.read();
    //Serial.print(c);
}
if (!client.connected()) 
{
    //Serial.println();
    //Serial.println("disconnecting.");
    client.stop();
}
client.flush();
client.stop();

}

void ledStatus(int x, int t)
{
for (int j = 0; j <= x-1; j++)
{
digitalWrite(ledD, HIGH);
delay(t);
digitalWrite(ledD, LOW);
delay(t);
}
}

int tempCalculation(String command) {
int tempCalc = (reading*3.3/4095)*100 - 50;
return tempCalc;
}

int analogReading(String command) {
return reading;
}

Can you do me a favor and provide a link to your code at http://www.pastebin.com ?

http://pastebin.com/h6zSkURU

Ok @RWB give this a try :wink: http://pastebin.com/raw.php?i=js9pjzZU

Thanks BDub, I’m running it now under a new Xivley Feed so we can monitor the up time and see if the core locks up for more than 10 mins and does not reset automatically.

1 Like

Tried the code and it does reset the Spark Core ever 10 mins but if I drop the data connection on my wifi network the CC3000 freezes up and the main loop stops running and therefore the 10 min system reset does not get to run to fix the problem.

So the Spark Core is just not able to hold a reliable connection to a WiFi network as of now.

The only solution for me right now is to toggle the power feeding the Spark Core OFF and ON externally if I want to know that the Spark Core will for sure reset ever 5 or 10 mins.

Hope the fix comes soon!

Thanks for the code BDub!

No problem! Spark Team is working on a CC3000 driver that is non-blocking, so perhaps this will allow the user code to still be processed in absence of Wifi data.

I have been implementing a similar solution to this problem but with a 555 timer instead which triggers the reset every 2 hours. Ugly solution but necessary until Spark comes together and becomes a more reliable product then what it is currently.

1 Like

can you post a picture OF THAT 555 TIMER SETUP?

Here you go

lol, how about a real life pic of how you have it setup? It helps a beginner like me LOL

Do you have it bread boarded up or is it pre made board where you just place your own resistors to change the timing?

@sjunnesson that’s a 4.7Meg ohm resistor, not a 47Meg ohm right?

Here’s another version that I just simulated to exactly 600 seconds. The 840k should probably be a 1 meg ohm potentiometer so you can dial it in just right.

Hey BDub, is there a way to get one of the output pins on the Spark Core to only go low and trigger the reset pin only if the main loop fails?

I saw somebody mention something like this in another thread but they were not sure if they set a pin high in the setup if it would go low if the main loop stopped or failed.

So bascially can use use a output pin that is set high in the setup and connect the pin to the reset pin so when it goes low it will cause the Spark Core to restart which would cause a new wifi connection to happen.

Would something like this work?

Hi RWB, Thanks to your recent post I figured another work around for my temporary solution.

I tried to mimic using a similar method you just asked about, however from my brief experience, it doesn’t allow any changes from any of the pins current state, therefore changing them wont cause the reset (my understanding), I had to use outside hardware.

My temporary solution resets the Spark only if the program stops running from being disconnected to the cloud. :slight_smile: My CFOD Killer using an ATTiny85. https://community.spark.io/t/cyan-flash-of-death-killer/2713

it is actually a 47 Mega ohm resistor. I need about 2 hours between each reset so my calculation at this site with R1=47M R2=20k and C=220uF gave me ~7,168 seconds which is close to 2 hours. Could of course switch it for a lower value and have a more frequent reset.

No that won't work, you have to assume your outputs will lock up high or low. You need a pulse detector.

You wanna get crazy eh? Ok here you go... 10 SECOND WATCHDOG by BDub

Pulse D2 at the prescribed rate to keep RST high. ~10 seconds after pulses stop, RST pulses low for 250ms. RST will continue to pulse low every 10 seconds if pulses do not return. Input is AC coupled, so pulses can stop high or low without a problem. R7 can be omitted as there is a 10k pull up on the Spark Core.

If you are looking for something to do, go ahead and build it! If you just want to get it done easily, kindly ask @Sparky for his ATTiny85 code :wink:

1 Like

HA! Yea I’ve spent enough time playing with the Spark Core already!

@Sparky looks to have a nice and neat one chip solution for now so lets explore that solution and hope it solves all our problems while we get the real fix working!

Fun Fun Fun!

You know, you might think this is a band-aid solution to reliability with the Spark Core… but the reality is, even if we didn’t have CFOD issues right now… an external watchdog is a good design practice for bulletproof systems :wink:

2 Likes