No reconnection to the cloud after sleep

I’ve got a core monitoring my solar heating system. At night, no sun, so I put the core into sleep (not deep sleep). This seems to work, a good reduction in supply current, and 5 hours later, it awakes and the current goes back to normal. The core is connected to my Wifi and I can ping it on 192.168.1.3. However, it is not connected to the cloud and is not seen as “alive” by “Spark Core Web Interface” which I use to interrogate it as I haven’t got round to writing some Javascript to custom poll its contents.
According to the documentation, after sleep, the core should reconnect and everything should connect back to the cloud. Mine doesn’t. What am I not doing, or doing wrong?
Any hints gratefully received. Thanks, GoToPCs, Edinburgh.

Hi @gotopcs,

Any chance you can post your code that is having this problem? We’ve also recently rolled out version 10 of the firmware to the build servers and build IDE, so if this is a bug it’s possible it’s been fixed recently. :slight_smile:

Thanks!
David

Hi @gotopcs

One other thing caught my eye here: you can ping it after sleep. Autonomous ping reply was removed in the TI CC3000 WiFi chip in the Deep Update patch, so that implies that you have not updated this core to the latest TI firmware for WiFi.

Maybe you should do that update and try again?

2 Likes

Thanks for your replies. Here is a snippet of the code I’m running. As you will see, I’ve shortened the sleep time enormously. When running the second “if” code, the LED never goes to red, but the core goes in and out of sleep (I’m monitoring the current consumption). When running the second “if” code, the core seems to be asleep all the time, shows green on the LED (for awake!) and can’t be interrogated.
My original code sent the core to sleep for 5 hours, then back to a 1-sec flashing loop for the other 19 hours. But it wouldn’t allow interrogation from the cloud at all. You are probably right I need to “Deep Update”. Where do I find info on this please?

void loop()
{
    if ((Time.hour() > 14) and (Time.hour() < 19))  // GMT !
        {
            RGB.color(16, 60, 16);
            RGB.brightness(32);
            solarDelay(240);       // awake for 4 minutes
            PumpOffTime = PumpOffTime + 240;
            RGB.color(60, 16, 16);
            RGB.brightness(12);
            Spark.sleep(120);      // sleep for 2 minutes
        }
    if ((Time.hour() > 18) or (Time.hour() < 6))  // GMT !
        {
            RGB.color(16, 60, 16);
            RGB.brightness(32);
            solarDelay(120);                  // awake for 2 minutes
            PumpOffTime = PumpOffTime + 120;
            RGB.color(60, 16, 16);
            RGB.brightness(12);
            Spark.sleep(120);                 // sleep for 2 minutes
        }
}

int solarDelay(int seconds)
    // double flashes the blue LED and delays total of 1 second
{
    do
    {
        digitalWrite(led2, HIGH);
        delay(20);               // Wait for 20ms
        digitalWrite(led2, LOW); 
        delay(130);              // Wait for 130ms
        digitalWrite(led2, HIGH);
        delay(20);               // Wait for 20ms
        digitalWrite(led2, LOW); 
        delay(828);              // Wait for 828ms 
        seconds = seconds - 1;
    }    
    while (seconds > 0);    
}

Yes, you’ve guessed it, I’m a newbie to both core and C.

Earlier today I’ve been reading results from the core without problems, but only after a reset to gain communication. At this time of day (4pm) it is running the >14, <19 loop. I’m monitoring current consumption. The core is awake for 2 minutes and asleep for 2 minutes (as you’d expect). When it is awake, I try to communicate with it via the “Spark Core Web Interface” which sees the core (I think) and enumerates the functions and variables pertaining thereto. However, the “Online” button does not come up, and trying to read any register or function just loops forever. Very weird. Any ideas?

You might want to see if your access token has expired.

http://docs.spark.io/api/#authentication-list-all-your-tokens

I seem to have a frightening number of access tokens! Expiry dates range from 24th Nov to 23rd Dec.
BTW, when core is awake, it is pingable and my IP scanner finds it. When asleep, neither of these work (unsurprisingly). So it is connecting to my LAN OK, just not to the cloud.

I can get the core to go to sleep when I call it from the Spark Core Web Interface by issuing a digitalwrite(S5) command which the code below sends the core to sleep for 5 minutes, then it wakes up and reconnects so communication is re-established. But obviously I can’t be at the keyboard 24/7 to send these commands!

void setup()
{
//Setup the Solar application here
pinMode(led2, OUTPUT);
//Register the Solar functions
Spark.function(“digitalread”, solarDigitalRead);
Spark.function(“digitalwrite”, solarDigitalWrite);
}

void loop()
{
… do various stuff
}

int solarDigitalWrite(String command)
{
bool value = 0;
//convert ascii to integer
int pinNumber = command.charAt(1) - ‘0’;
//Sanity check to see if the pin numbers are within limits
if (pinNumber< 0 || pinNumber >9) return -1;

if(command.startsWith("S"))
{
    // white LED while asleep, then back to whatever
    RGB.color(120, 120, 120);
    RGB.brightness(64);
    Spark.sleep(pinNumber * 60);
    sleepDelay(pinNumber * 70);
    return 123;
}

}

int sleepDelay(int seconds)
// double flashes the blue LED and delays total of 1 second
{
do
{
digitalWrite(led2, HIGH);
delay(200); // Wait for 200ms
digitalWrite(led2, LOW);
delay(200); // Wait for 200ms
digitalWrite(led2, HIGH);
delay(200); // Wait for 200ms
digitalWrite(led2, LOW);
delay(398); // Wait for 398ms
seconds = seconds - 1;
}
while (seconds > 0);
}

If, however, I use the code below on a timed basis, say once every 10 minutes, the core goes to sleep for the correct time, the re-awakes, but communication is NOT re-established - no flashing green etc, it just continues round its loop and the only way to regain contact with it from the Cloud is to press the reset button. Any ideas??? I’m guessing the function call from the Web Interface reconnects because it is supposed to return a value and the core firmware remembers that, but in the timed case (below) this is not true.

this is in the loop…

if ((Time.hour() > 14) and (Time.hour() < 19))  // GMT !
// YELLOW phase
{
    RGB.color(150, 70, 0);
    RGB.brightness(64);
    MinNow = millis();
    if (MinNow-minuteNow>600000UL) 
    {
        minuteNow = MinNow;
        Spark.sleep(12);      // sleep for 12 seconds
        sleepDelay(20);       // delay 20 seconds
    }    
}

I agree with you: The docs seem to indicate that all should re-connect after you awake from sleep(). But someone else has reported that their TCP/UDP sockets need to be re-established. And that seems to make sense, perhaps, so we try to out-guess the docs: Have you tried calling Spark.connect() after you wake up? And waiting until Spark.connected() returns true? None of this is documented as being necessary but…

Assuming you are still having this issue the docs don’t mention that Spark.connect() is called after waking up so I would suggest you try, as @psb777 suggested, calling Spark.connect() and then doing something like

while(Spark.connected() == 0);

(or something with a timeout) once you wake up

Well, I didn’t think I’d create such a storm of controversy over what I thought was a simple comment. I’d no idea I was in the wrong place, so sorry for that. The general opinion seems to be that the core re-boots after sleep thus losing all volatile storage. OK. How do I work round that? I’ve searched this forum for someone with the same problem, but not found a definitive answer. So, I’ve tried a workaround using WiFi.off() and WiFi.on(). Part of the (trial only) code follows below. I think I’m nearly there, but at the end of the code, when the LED goes yellow (connected, whooppee!), thereafter the code goes back into the main polling loop and will not communicate with “Spark Core Web Interface” or publish data as commanded. I’ve timed the various LED colours and no timeouts are occurring. solarDelay(1) delays 0.1 seconds. The switching of WiFi off then on is accomplished by using “Spark Core Web Interface” sending the parameter “S0” via the digitalwrite command. The code is set into Testmode first by sending T1 via the same command button (not relevant to this discussion, I don’t think).
Code snippet:

 int DigitalWrite(String command)
{
    bool value = 0;
    //convert ascii to integer
    int pinNumber = command.charAt(1) - '0';
    int pubnumber = EEpointer + 5;
    //Sanity check to see if the pin numbers are within limits
    if (pinNumber< 0 || pinNumber >9) return -1;

    if (command.startsWith("T"))  // 1 for testing (no sleep), 0 for normal operation
    {
            // cyan LED while in test mode, then back to whatever
            RGB.color(20, 255, 20);
            RGB.brightness(64);
            TestMode = pinNumber;
            return TestMode;
    }


    if (command.startsWith("S"))
    {
            int loopout = 60;
            // red LED while WiFi off, then back to whatever
            RGB.color(120, 0, 0);
            RGB.brightness(120);
            WiFi.off();                 // reduce power
            solarDelay(600);        // delay 1 minute
            RGB.color(0, 120, 0);
            RGB.brightness(120);
            WiFi.on();                  // wifi back on
            solarDelay(20);        // delay 2 secs
            // connect to local wireless network
            do 
            {
                    WiFi.connect();
                    if (loopout > 0)
                    {
                            solarDelay(10);           // delay 1 second, max 1 minute
                            if (WiFi.ready() == true)
                            {
                                    break;
                            }  
                            loopout = loopout - 1;
                    }
            }
            while  (WiFi.ready() == false);                // wait until IP address acquired
            RGB.color(0, 0, 120);
            RGB.brightness(120);
            solarDelay(20);        // delay 2 secs
            if (Spark.connected() == false) 
            {
                    Spark.connect();
            }
            solarDelay(100);        // delay 10 secs
            if (Spark.connected() == true) 
            {
            RGB.color(120, 120, 0);
            RGB.brightness(120);
            }
            solarDelay(20);        // delay 2 secs
            
            sprintf(publishString,"Connected after %u seconds",loopout);
            Spark.publish("Data1",publishString);
    }
}

First off let me clear this up because I wasn’t clear: the forums aren’t the wrong place for a bug report; the GitHub issue page is just a better one. In you case you also need some code help so posting here is perfectly acceptable.

Just to confirm: the core’s RGB does indeed turn yellow (indicating that it is connected to the cloud) but the Spark.publish() 2 or 3 lines later don’t work?

Spot on! Yellow appears, then it goes back to Cyan for looping. The publish does not work and no comms are possible thereafter.
Don

Interesting problem. Where in your code do you release control over the RGB LED? If it goes back to cyan then (I’m fairly sure) you would need to have done a RGB.control(false); Do you do that? and if so where?

Harrison,
Ah no! I don’t release control of the LED. It does not go to breathing Cyan, I simply tell it to go to RGB.color(20, 255, 20); as in the “T” routine above the “S” routine.
Don

Interesting. If you release control of the LED (perhaps using another “X” character routine) what happens?

I added a subroutine to release control of the LED (which worked). Rebooted after flashing. As soon as the system was running, I sent a T1 command to put it into Test mode. Data now being published correctly, LED is solid cyan. I sent an X command - LED changed to breathing cyan as expected. Sent an S command to switch the WiFi off, then on. LED changed immediately to breathing white, and stayed that way. No comms possible until reboot of firmware which I did several minutes later.

When you send the S command does it briefly turn yellow (indicating the Spark.connect( ) succeeded) or does that not happen?

@gotopcs Trying to follow your thread - so I may not completely understand what you are doing.

From what I can gather you are using the Spark Cloud to send commands to your core using Spark.function().

So it appears you can get the core up and connected with the Cloud as it responds to commands. However when you turn off the WiFi using your S command the core drops WiFi as you expect, but your calls to WiFi.on();, WiFi.connect(); and Spark.connect(); appear to not work correctly? If you release control of the LED before you startup the WiFi you should see Blue (WiFi.on), flashing Green (WiFi.connect) and then flashing Cyan to breathing Cyan (Spark.connect).

Rather than manage the WiFi connection directly, you could just call Spark.connect(); instead of WiFi.on(); and WiFi.connect(); as they are called as part of Spark.connect();

It’s hard to troubleshoot when you have control of the RGB. To get the status just release the RGB with RGB.control(false); It may be easier to understand what’s going on.

Yes it does go yellow for a couple of seconds.
I will try the Cloud.connect() and post feedback!
Thanks for your advice chaps, I’d be totally at a loss without this help.
Don