Using Spark.Disconnect() & being able to flash over-the-air?

So my spark is running a basic temperature and light sensor application. The local network is almost always ON but the internet connection on that network is pretty unreliable so you could imagine my delight when I found Spark.disconnect() function.

But I want to change the firmware on it over the air. Is there any workaround that my core can be disconnected from the Spark Cloud for most of the time but connect back to the Cloud every once in a while and check for new code to be flashed over the air?

Also if use Spark.connect() and there happens to be no internet at that time, will my core hang up??

Ok, this is funā€¦ will disconnect you from the Cloud on start up, and then if you need to reflash your code just press the Mode button to reconnect to the Cloud first. It also ignores the Mode button for the first 3 seconds after start up, so you have enough time to get your Core into Smart Config if you need it.

uint32_t startTime = 0;
void setup() {
    startTime = millis(); // capture the time that our app starts
    Spark.disconnect();
}

void loop() {
    if(ModeBtnPressed()) {
        RGB.control(true);
        for(uint8_t x=0; x<2; x++) { // Ready the Hyperdrive!
            RGB.color(255,0,0); //red
            delay(100);
            RGB.color(255,100,0); //orange
            delay(100);
            RGB.color(255,255,0); //yellow
            delay(100);
            RGB.color(0,255,0); //green
            delay(100);
            RGB.color(0,255,255); //cyan
            delay(100);
            RGB.color(0,0,255); //blue
            delay(100);
            RGB.color(255,0,255); //magenta
            delay(100);
            RGB.color(255,255,255); //white
            delay(100);
        }
        RGB.control(false);
        Spark.connect(); // Engage Hyperdrive!
    }
}

bool ModeBtnPressed() {
    if(millis() - startTime > 3000) { // wait at least 3s for smart config
        if(BUTTON_GetDebouncedTime(BUTTON1) >= 100) {
            BUTTON_ResetDebouncedState(BUTTON1);
            return 1;
        }
    }
    return 0;
}
5 Likes

Thatā€™s a nice workaround, also Hyperdrive! New library? :slight_smile:

Thanks. Yeah it seemed fitting for connecting to the Information Super Highway :wink:

1 Like

@BDub Thanks a lot for this! I'm Looking forward to the weekend now.

I had an alternate idea in the meantime. Where I would listen for particular TCP/IP or UDP packets that tells the Spark to Connect or Disconnect from the cloud, but it probably isn't a general solution I suppose.

And I hate doing this to you guys but I have more doubts =[

  1. if(millis() - startTime > 3000) { // wait at least 3s for smart config
  • Will I still be able to send it to Smart Config Mode, when I hold the Mode button for 3 seconds?
  • Will I still be able to wipe all Wifi data when I hold the Mode button for 10 seconds?
  1. The following is more of a general doubt:
if(BUTTON_GetDebouncedTime(BUTTON1) >= 100) {
            BUTTON_ResetDebouncedState(BUTTON1);
            return 1;
        }
  • Can I apply the above to analog and digital pins as well !?
  • Is there any documentation for the functions you've used? I could not find any on http://docs.spark.io/

Thanks so much already :smile:

Yes, you have to press RESET first, then MODE right away.

No, not unless you change the timing to if(millis() - startTime > 10000) Another way to do it would be to comment out this line BUTTON_ResetDebouncedState(BUTTON1); so that the background code can still see the button being held for 10 seconds. Actually I like this latter idea a lot. The only problem is the interrupt code that monitors the button only resets debounce time when you press the button again. If it reset the debounce time when you let go, we could use the mode button very easily in our code without interfering with the SmartConfig stuff. I'll experiment with this and see if it works, then if so submit a pull request.

Not at this time, but you can certainly roll your own debounce routine on any input. Exposing the MODE function on any input pin is an item on the backlog though, so in the future you should be able to do this :smile:

Not for the Mode button stuff. They are pretty self explanatory though, one just holds the current number of milliseconds that it has been pressed for. The other resets that time.

2 Likes

Pull request submitted :slight_smile:

Once this is approved, hereā€™s a nice way to toggle the connect on and off:

#include "application.h"

bool ModeBtnPressed();
bool WE_SO_CONNECTED = false;
bool MODE_PRESSED = false;

void setup() {
  Spark.disconnect(); // Disconnect from the Cloud on startup
}

void loop() {
  if(ModeBtnPressed()) {
    if(WE_SO_CONNECTED == false) {
      RGB.control(true);
      for(uint8_t x=0; x<2; x++) { // Ready the Hyperdrive!
        RGB.color(255,0,0); //red
        delay(50);
        RGB.color(255,100,0); //orange
        delay(50);
        RGB.color(255,255,0); //yellow
        delay(50);
        RGB.color(0,255,0); //green
        delay(50);
        RGB.color(0,255,255); //cyan
        delay(50);
        RGB.color(0,0,255); //blue
        delay(50);
        RGB.color(255,0,255); //magenta
        delay(50);
        RGB.color(255,255,255); //white
        delay(50);
      }
      RGB.control(false);
      Spark.connect(); // Engage Hyperdrive!
      WE_SO_CONNECTED = true;
    }
    else {
      Spark.disconnect(); // Power down the Hyperdrive...
      WE_SO_CONNECTED = false;
    }
  }
}

bool ModeBtnPressed() {
  if(BUTTON_GetDebouncedTime(BUTTON1) > 100) {
    // Detect mode pressed only once
    if(!MODE_PRESSED) { 
      MODE_PRESSED = true;
      return 1;
    }
    // wait until button is released before indicating it's pressed again
    return 0;
  }
  else {
    MODE_PRESSED = false;
    return 0;
  }
}
2 Likes

@BDub Iā€™m guessing this means I will now be able to toggle Spark Connect & Disconnect using the Mode button and still be able to enter Smart Config (3 second Mode Button Press) and clear Wifi Data (10 second Mode Button Press). If so, then that is cool!

You guys are awesome! :slight_smile:

1 Like

Yes it works very well!

1 Like

@BDub Iā€™m trying to wrap my head around this Cloud OFF feature you created.

If I use this feature and turn off the could connection will it eliminate the lockups we have been having with the Spark Core when it looses a wifi connection or the data drops out?

The CC3000 does not power down does it? The power consumption stays the same right?

We could extend this button to an external button if we wanted to right?

I just want my script to run like on a Arduino Micro regardless of the CC3000ā€™s cloud connection status.

Let me know whats up @BDub

Check out these posts:

Correct, Spark.disconnect() does not power down the CC3000. It just closes the socket to the cloud and doesn't try to communicated with the Cloud anymore.

@RWB If your application has nothing to do with the Spark Cloud and you want your device to stay stable during loss of internet connectivity or loss of connectivity with the Spark Cloud then spark.diconnect is the what you need.

But there are some disadvantages of using spark.disconnect like not being able to flash your core over the air and not being able to use Spark functions and variables, and a few more.

To overcome some of these issues, @BDub 's been nice enough to provide a solution for toggling ON/OFF the Spark connection to the Cloud using the mode button.

Ideally I want the CC3000 to just not affect the main loop when its not available. I want it to be as easy to use as possible so no switch to turn it on or off would be ideal since spark.disconnect doesnā€™t provide any power savings might as well leave it on and make it not affect my main loops performance.

1 Like

For the sake of closure ā€“ so folks donā€™t suffer through the workarounds:

The SYSTEM_MODE toggle now solves this problem.

http://docs.spark.io/firmware/#eeprom-semi-automatic-mode

1 Like

I donā€™t think what you mentioned fits the description of this thread though?