Spark.sleep() getting stuck

I am experimenting with Spark.sleep(). I am trying to turn WiFi off for 10 seconds. When I run this line the Core led keeps breathing like normal, but then after a few seconds just keeps breathing green and never connects back to the cloud. It doesn’t matter how low I set the time parameter to. What could be the issue here?

@mnetwork, what SYSTEM_MODE are you running in? We would need to see your code to understand how you are using Spark.sleep() :smile:

When you verified your code did it give you any warnings or errors? Also like said above please show your code^

I am using AUTOMATIC. in my loop I have pretty much this:

void loop() {
    if (sleepFlag == 1) {
        sleepFlag = 0;
        //Spark.sleep(10);
    }
}

I did not have any errors or warnings. The code is very simple at this point. I was really just testing this part of the Sleep() function for saving on battery life.

@mnetwork, what do you have in your setup()?

Just four lines setting variables.

As much as I’m sure you think that’s a helpful answer it’s not very helpful ( I mean this in the nicest way possible). Is there a reason we can’t just see your code? If there are proprietary bits feel free to just psuedo code them or remove private URLs (replace them with example.com or something).

Additional questions: How are you compiling your code? Are you using the WebIDE? Have you done a http://support.spark.io/hc/en-us/articles/203108844-Perform-a-Full-Firmware-Upgrade which is very helpful to make sure everything’s up to the latest version? I can tell you that right now I have a core sitting next to me that wakes up every hour, downloads ~40kb of data, uploads a status report, and then goes back to sleep and it’s been doing that for weeks so what you want to do is very much possible and the error you are getting is most likely the result of your code. Again, not trying to be mean, just trying to full relay the facts.

2 Likes

Here you go. The reason I didn’t put the rest of the code in is because when I take it out nothing changes.

const int servoPin = A0;
const int servoPosPin = A1;

int servoPos = 0;
int servoMoveFlag = 0;
int reqServoPos = 0;

Servo myservo;

void setup() {
    Spark.variable("servopos", &servoPos, INT);
    Spark.function("moveservo", moveServoToPos);
    pinMode(servoPosPin, INPUT);
    servoPos = analogRead(servoPosPin);
}

void loop() {
    if (servoMoveFlag == 1) {
        myservo.attach(servoPin);
        myservo.write(reqServoPos);
        delay(800);
        myservo.detach();
        servoMoveFlag = 0;
        readPosition();
        //Spark.sleep(D0,FALLING,10);
        Spark.sleep(10);
    }
    
    readPosition();
}

int moveServoToPos(String servoMovePos) {
    reqServoPos = servoMovePos.toInt();
    servoMoveFlag = 1;
    return 1;
}

void readPosition() {
    servoPos = analogRead(servoPosPin);
    delay(1000);
}

You could try to add this to your loop()

  ...
  if (!Spark.connected() && WiFi.ready())
    Spark.connect();
  ...

Since waking the WiFi alone, does not reconnect to the cloud, you need to do this yourself once the network connection got reestablished.

I thought this only needs to be called if you do a disconnect and not sleep.

How could the Core stay connected to the cloud without the WiFi network providing the connection?

My understanding was that sleep puts WiFi to sleep, but keeps executing code for the duration passed in the argument and after that duration has passed it wakes from that sleep and connects to the cloud. The only thing I can find in the documentation is that you have to do a connect if you manually do a disconnect (not sleep).

I do agree that it is not explicitly mentioned in the docs - at least not where I looked.

But for me it seemed obvious - or it was a fluky guess - and it worked on my Core when I tried your code with it :wink:

Another suggestion might be to use WiFi.off() instead of Spark.sleep(). This would give you better control of when exactly you want to reconnect explicitly by just calling Spark.connect().

1 Like

Well adding your snippet to the top of the loop does work. I was sure it would. Do you find on your Core that you HAVE to add this to use sleep?

I tried updating with spark-cli as you asked. Didn’t change anything. It seems that when the Core goes to sleep it changes to a breathing white light. Once it comes out of sleep it turns into a flashing green light. Adding the code mentioned above it comes out of sleep and goes right into its regular state. Is this expected behavior? Why is this not mentioned in the docs?

Yes, to get the Core to reconnect after sending the WiFi to sleep, I have to.

No, I don’t to use Spark.sleep() in any of the other sleep modes, since waking from them causes the Core to act as if it was just powered up.
I guess you’ve seen that yourself when using the commented line of your code

  ... 
  //Spark.sleep(D0,FALLING,10);
  ...

Well, I was using deep sleep with a wake interrupt in my last thread. I’m just getting a lot of code sorted as I am planning for a big project. We’ll see if @harrisonhjones answers about how sleep is supposed to function.

I do recall that thread, and you did mention SLEEP_MODE_DEEP in the initial post, but Spark.sleep(D0,FALLING,10); is not actually putting the Core into deep sleep.

But well, no point nit picking here.
Let’s see if @harrisonhjones will put me right on my misconceptions as @peekay123 did on the CHANGE matter.

@ScruffR, mine freund :smirk: You are correct that Spark.slee(D0, FALLING, 10) does not put the Core in deep sleep but it does, however, put it in STOP mode which is also low power. Nonetheless, a RESET event is required to stop the IDWG watchdog timer so STOP mode can be properly invoked. You can wake from STOP mode via an RTC event or an external interrupt.

I believe there is some confusing use of Spark.sleep() versus WiFi.off(). Truth be told, Spark.sleep(time) does NOT put the processor to sleep. Instead, it simply calls WiFi.off() with a timer value! So to be explicit, it is better to use WiFi.off() instead and control the time yourself.

The code snippet is just good form IMO. Knowing the cc3000 has been disabled, it only makes sense to make sure the cloud connection is re-established without assuming the Core firmware will do that (and it may but I’m not sure). :smiley:

2 Likes

Thanks Paul (@peekay123 - thanks for calling me Freund :blush:), this was exactly my understanding too.
The reference to (propper) sleep() and consequently waking up with the explicit need to go through all the normal boot-up/reconnect procedure, was mainly meant as a way to establish that it’s not too far fetched that Spark.connect() might be needed after (“wimpy” WiFi only) sleep() - even when not needed after propper sleep().

And about WiFi.off():
This was exactly my thinking a few posts up.
Mainly for flexibility, but also for clarity - as you mentioned.

2 Likes

Interseting, so sleeping with a wakeup pin is not the same (power consumption) as deep sleep? Do we know how it compares to deep sleep? I would imagine it is a good amount less than regular sleep.