Can I Turn the CC3000 OFF? [solved]

You guys deserve a TON of credit for the thankless work that you do!!! And these little cores are so incredibly complex, resolving all the issues and implementing new features seems an insurmountable task to me, so I bow to the entire spark team, elites included!

1 Like

Yahoo! I found a bug in delay() where it does NOT call SPARK_WAN_Loop() when the SPARK_WLAN_SLEEP flag is set by Spark.sleep()! So in the @brianr test code:

char LED = D7;

void setup() {
pinMode(LED, OUTPUT);
digitalWrite(LED, HIGH);    //LED on initially
}

void loop() {    
//Do something
    delay(25000);           //delay for 25 seconds

//Start sleep cycle    
digitalWrite(LED, LOW);     //LED off to indicate sleep
Spark.sleep(30);            //sleep for 30 seconds
delay(30000);               //delay for 30 seconds
digitalWrite(LED, HIGH);    //LED back on
//End sleep cycle
}

if the delay(30000) is removed after the Spark.sleep() call so that loop() ends and the firmware background task picks up on the sleep flag then the CC3000 goes in standby. Leaving the delay will prevent the CC3000 from going into standby and the sleep time expires at the same time as the delay. This happens at the end of loop() but the sleep has expired so essentially nothing happens and the CC3000 stays ON.

To prove this, simply add SPARK_WLAN_Loop() after the Spark.sleep(30) call and the CC3000 will go into standby as expected!

Now, using a INA219 current/voltage sensor to measure the current on the 5V (USB) side of a Core with nothing else connected to it (eg. sensors), here are my current measurements:

CC3000 ON, connected to cloud and breathing cyan: 138ma

CC3000 in standby using Spark.sleep(), breathing white: 32ma

Replacing Spark.sleep(30) with Spark.sleep(SLEEP_MODE_DEEP,30) will cause the Core to essentially shut down for 30sec after which it will reboot and start over again. The results shocked me somewhat because they are different than what I reported before:

CC3000/Core in deep sleep mode: 1ma or less!!

My previous measurements were made with a DHT22 and an INA219 sensor connected to a Core. My assumptions were that both consumed less than 2ma which is glaringly wrong! So with proper power management OUTSIDE the Core, low power modes are very conceivable. :slight_smile:

5 Likes

@peekay123 - Thatā€™s great news about the deep sleep, bug find, and workaround! Iā€™m giving you a big old wi-five from south of the border! Also, applause all around! :clap: :clap: :clap:

1 Like

@peekay123 Iā€™m sure @brianr is gonna be happy to hear this news :smile:

And 1ma in deep sleep is really pretty good considering it consumes about 140,000 times more power during normal WiFi operations. This makes it perfect for remote data loggers that have access to WiFi.

Even if the location you wanted to gather data from didnā€™t have WiFi near it you could use a XBee Pro 900 HP to transmit the sensor data back to a Spark Core that did have WiFi access up to .75 miles away based on my in XBee range testing. Either way the Spark Core can let you get your data onto the web.

Now on to getting the FRAM & Sharp Memory LCDā€™s up and running.

Keep up the good work @peekay123 your making a lot of stuff work with the Spark Core that wouldnā€™t otherwise.

Iā€™m personally anxious to get my hands on a Flutter. We met the creator at Maker Faire, and heā€™s working as fast as he can to get them into production!

1 Like

I saw that Kickstarter awhile back. They must have been working on this for awhile now.

Iā€™d like to test one against XBEE 900 Pro HP in the city and field and see how they compare. They make the XBEEs with Arduino Processors on board with the Encryption also for about $50 each.

The more options the better.

@peekay123, it does indeed seem like the core goes to sleep if I comment out the 30 second delay - excellent find! That delay was in there because code continues to run while the core is sleeping, when what I really want it to do is sleep on low power and do nothing. I will say that this exact core worked with v0.2.1 as expected, but as long as we all know that the sleep has to be at the end of the loop, then I guess it can be made to behave as desired? Iā€™d say moving the 30 second delay in this example to the beginning of the code might work, but really a ā€œwhileā€ loop to wait for cloud status to connect is probably a much better idea. Even when sleep worked mid-code, checking for connection status is always smarter than delaying for x seconds. Iā€™ll try some stuff and post back results. Maybe Iā€™ll try to wrap up sleep options in a function; sleep(non-blocking, intSec), sleep(blocking, intSec), deep sleep(intSec). That ought to keep me busy for a while!

Deep sleep didnā€™t seem to lose itā€™s potency when v0.2.2 came around, and is very handy, but I need to retain variable values, so a hard restart doesnā€™t work. Would love it if key-values were implemented natively, but I fear thatā€™s a very long way off, if at all.

@brainr, Iā€™m glad I was able to shed some light on the sleep modes. I agree that it would be nice to have key variables persist through resets. There are several ways of doing this. One is using the external flash on the Spark, another is using FRAM. @kennethlimcp will soon be going to productions on his FRAM/SD shield and @timb is working on shield as well. FRAM is fast, persistent and ideal for both data logging and variable storage. Finally, the ability to store to cloud is good but is subject to connectivity and reliability constraints. My money is on FRAM :smile:

With this findings in this thread, Iā€™ve decided to put a Core on a 3.7v 600mAh batteries and try out the various power modes to see how long they run. It may take a few days to try out all the different power mode options, but Iā€™ll post my findings in a separate thread.

2 Likes

Can someone post some example could as to how to get the thing to sleep properly? I have some pretty simple code that doesnā€™t seem to wake back up. It also doesnā€™t flash green as the docs say. Hereā€™s a snippet:

void setup() {
    delay(5000);
}

void loop() {
    httpGetRequest(srvIP, srvHost, srvPort, srvPath);

    Spark.sleep(10);
}```

The `httpGetRequest()` function is pretty self-explanatory, so I omitted it and it's variables for brevity.  I get the same (lack of) results if I use `SPARK_WLAN_Loop()` after the sleep or not.  I give myself a 5-second delay in `setup()` so I have a little window to reset and flash the Core from the web IDE.  Also, the TCPClient doesn't seem to work if I don't have an initial delay before attempting to use it.  1 and 2 seconds didn't work, but 5 seconds did!

Deep sleep mode seems to work as intended, though!

@wgbartley, Can you send me a gist with your code (I donā€™t know where to find httpGetRequest!) so I can test locally? I have a hunch and I need to test it :smile:

@peekay123 - Here you go!

Just try not to change the char srvPath[] = "/logger/?l=uptime-test"; to uptime1, uptime2, uptime3, or uptime4.

1 Like

@wgbartley, there are some flaws in your logic and itā€™s not your fault :open_mouth: The issue lies with the concept of ā€œsleepā€ and how Spark.sleep() actually works. The way it is presently designed, Spark.sleep() does not actually put the processor to sleep, only the CC3000 wifi module. And it does so in the ā€œbackgroundā€ so your user code is not ā€œawareā€ of the effect of the Spark.sleep() call unless it tests for it.

So, in your case, you call httpGetRequest() AND Spark.sleep(60) for EVERY iteration of loop and since Spark.sleep() is a non-blocking call, it puts the CC3000 in standby for every loop()! So, your httpGetRequest() will never connect and your CC3000 will never wake :wink:

So, the first part of the solution is better documentation. The second is more or less straight forward. It involves testing for the wifi/cloud status BEFORE calling httpGetRequest() and Spark.sleep() so neither is called while the wifi is in standby mode, like this:

void loop() {
    if (WiFi.status() == WIFI_ON) {
//    if (Spark.connected()) {
        delay(5000);
        httpGetRequest(srvIP, srvHost, srvPort, srvPath);
        Spark.sleep(60);
    }
}

Notice that before calling httpGetRequest() and Spark.sleep(), I test to see if the wifi is back ON again. That way, the CC3000 standby mode is allowed to occur and after one minute, it will automatically wake and wifi will be ON again. At that point, the entire cycle starts again. The choice of WiFi.status() vs Spark.connected() is entirely based on the type of connectivity required (eg. Spark.publish() requires cloud connection, not just wifi).

The weird part, however as you might have noticed, is the delay(5000) following the IF statement. It seems that WiFi.status() will return WIFI_ON before the actual ā€œconnectionā€ is complete. Without the delay, the httpRequest() fails most of the time, whereas WITH the delay, it fails some of the time. I have more investigation to do on this :smile:

Thanks, @peekay123! That makes total sense, but the docs could definitely use that little tip.

The delay() in the setup also mitigates the same issue when not putting anything to sleep. Without the delay in setup, httpGetRequest at the top of the loop fails 100% of the time for me.

@wgbartley, I had the same results with the delay. We need to figure out why it is needed. Perhaps @zachary can give some guidance.

I came to this thread by Google. For the sake of closure ā€“ so folks donā€™t suffer through the workarounds:

I believe the SYSTEM_MODE toggle now solves this problem.


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

2 Likes

Can this please be added to the documentation?

EDIT: These too (Photon only):

This was changed in the WiFi class over a year ago. The current documentation for WiFi accurately reflects the tested and available API functions.

[Are you sure this is the right place to post compared to simply continuing the original cc3000 thread?]
@moors7: the posts have been moved accordingly. This topic however was closed, and therefore unable to be continued. I'll unlock it for a duration of 12 hours after the last reply. Any comment after that, please PM me, and we'll work something out

1 Like