Core wont connect in manual mode

I want to use my Core to monitor my fish tank and some other temperatures etc.

I do not want to use the automatic mode because the WiFi is rather unstable and drops connection every few minutes. This makes the core go offline and stop the code, turning off my led strip inside the fishtank, leaving the fish in the dark :frowning:

So I tried to use it in manual mode and only open connection to publish some temperature or status, such as it dimming the lights. However, it does not connect to WiFi or even turn on the ledstrip, it is just dead. It seems like it continues to reboot, first the RGB led is white for a second, then it flashes green for a bit and then it just dies and restarts after 10 seconds.

Here is the code I am using at the moment:

// This #include statement was automatically added by the Spark IDE.
#include "SparkButton/SparkButton.h"

SYSTEM_MODE(MANUAL);

int awake = 1;
int asleep = 0;
SparkButton b = SparkButton();

void setup() {
    Spark.connect();
    b.begin();
    RGB.control(true);
    pinMode(A0,OUTPUT);
    Spark.syncTime();
    Time.zone(+1);
    Spark.publish("Status","back online at " + Time.timeStr());

}

void loop() {
    
    if (Time.weekday() > 1 && Time.weekday() < 7)
    {
    
        if ((Time.hour() >= 10 || b.allButtonsOff() == 0)  && awake == 0 && Time.hour() < 23)
        {
            if (!Spark.connected()) Spark.connect();
            if (Spark.connected()) 
            {
                Spark.process();
                Spark.publish("Status","awakening at " + Time.timeStr());
            }
            
            awake = 1;
            asleep = 0;
            RGB.color(10,0,0);
            for (int i = 0; i < 200; i++)
            {
                analogWrite(A0,i);
                myDelay(7060);
                if (i == 200)
                {
                    if (!Spark.connected()) Spark.connect();
                    if (Spark.connected()) 
                    {
                        Spark.process();
                        Spark.publish("Status","awake at " + Time.timeStr());
                    }
                }
            }
        }
    }
    
    else
    {
        if (Time.hour() >= 10 && awake == 0 && Time.hour() < 23)
        {
            if (!Spark.connected()) Spark.connect();
            if (Spark.connected()) 
            {
                Spark.process();
                Spark.publish("Status","awakening at " + Time.timeStr());
            }
            awake = 1;
            asleep = 0;
            RGB.color(10,0,0);
            for (int i = 0; i < 200; i++)
            {
                analogWrite(A0,i);
                myDelay(7060);
                if (i == 200)
                {
                    if (!Spark.connected()) Spark.connect();
                    if (Spark.connected()) 
                    {
                        Spark.process();
                        Spark.publish("Status","awake at " + Time.timeStr());
                    }
                }
            }
        }
    }
    
    if (awake == 1)
    {
        analogWrite(A0,200);
        myDelay(60000);
        RGB.color(10,10,10);
        if (!Spark.connected()) Spark.connect();
        if (Spark.connected()) 
        {
            Spark.process();
            Spark.publish("Awake","awake at " + Time.timeStr());
        }
    }
    
    if (Time.hour() >= 23 && asleep == 0)
    {
        asleep = 1;
        awake = 0;
        RGB.color(0,0,10);
        if (!Spark.connected()) Spark.connect();
        if (Spark.connected()) 
        {
            Spark.process();
            Spark.publish("Status","sleepy at " + Time.timeStr());
        }
        
        for (int i = 200; i > -1; i--)
        {
            analogWrite(A0,i);
            myDelay(7060);
            if (i == 0)
            {
                if (!Spark.connected()) Spark.connect();
                if (Spark.connected()) 
                {
                    Spark.process();
                    Spark.publish("Status","asleep at " + Time.timeStr());
                }
            }
        }
        Spark.syncTime();
    }
    
    if (asleep == 1)
    {
        analogWrite(A0,0);
        RGB.color(0,0,0);
        if (!Spark.connected()) Spark.connect();
        if (Spark.connected()) 
        {
            Spark.process();
            Spark.publish("Asleep","Asleep at " + Time.timeStr());
        }
        myDelay(60000);
    }

}

void myDelay(unsigned long duration)
{
    unsigned long start = millis();
    while (millis() - start <= duration)
    {
        Spark.process();
    }
}

any help would be greatly appreciated :smile:

We also tried the manual mode. We had the same problem.
But the semi automatic mode works for us and is much more stable.

You can simply switch of the Cloud by Wifi.off() (if you want)
and simply turn them on by Spark.connect();
You can check the state very easily using:
Spark.connected()
and Wifi.ready();

Using this setup our “Connect to the cloud if needed” works.

We had also problems using Spark.process(). There seams to be a substantial difference between this and using the loop(). So our working solution doesn’t use Spark.process();

Thanks for the reply! I will try that in a bit :smile:

@TheHawk1337 Check your router. I had two cores yesterday exhibit the same behavior as you described -

At first I thought it was the core, then I noticed another doing the same thing, so I rebooted my network hardware - router and modem. This cleared up the issue. I remember issues with lease times and some other settings - but rebooting the hardware cleared the problem, so I was happy it was not the cores.

1 Like

@TheHawk1337, just a note on Spark.syncTime(). You should wait for the time to actually sync before continuing:

while(Time.year()==1970)
{
Spark.syncTime();  
Spark.process();
delay(100);
}

:smile:

1 Like

I don’t see any code handling the disconnect. So your code would be blocking on the Spark.connect() in setup(). This is really no different than running in the default automatic mode.

I’ve been working on a similar situation. I don’t want to program to block on no connection. So I’m starting a timer triggered interrupt immediately before Spark.connect(). The interrupt calls Spark.disconnect(). This way if the timer expires, the interrupt triggers and breaks the blocking connect. Then I check the state of Spark.connected() on every loop. If connected, I turn off the interrupt and try reconnecting if disconnected.

@peekay123 What happens with Spark.syncTime() if Spark.connected() == false? Does it block or fail gracefully?

<-wishlist> It would be nice if all spark functions were clearly documented as blocking or non-blocking for no cloud connection. <-/wishlist>

@matt_ri, not sure! So, it is good practice to check Spark.connected() before call syncTime(). :smile:

So after a little tinkering, I managed to fix it. I encountered a hard error apparently (I had RGB,control(true) so somehow the panic SOS wouldn’t show). During tinkering I also encountered breathing blue, breathing green and flashing green to infinity. I used below code which kindof works:

SYSTEM_MODE(SEMI_AUTOMATIC);

bool synced = false;

void setup() {

}

void loop() {
    
    if (synced == false)
    {
        if(!Spark.connected())
        {
            connect();
        }
        
        if(Spark.connected())
        {
            synced = true;
            Spark.publish("Synced!");
            Spark.syncTime();
            Time.zone(+1);
        }

    }

}

void connect()
{
    WiFi.on();
    WiFi.connect();
    while(!WiFi.ready())
    {
        
    }
    Spark.connect();
}

However, I tried to turn off the WiFi module to save power (no particular reason why :wink: ) and if the WiFi gets killed immediately after the publish it wont publish, so a big delay has to be added ( >1 sec) which is a bit ugly to do in my opion :worried: .

I am thinking to use Spark.subscribe() and subscribe to myself to check if the event published after which the core turns off WiFi again. But I will look into that later.

Thanks! :smile:

@TheHawk1337 If you figure out how to manage a cloud connection when you directly manage the WiFi and turn it off when not needed let me know. I would be interested in what you learn.

I am currently trying to use IFTTT to call a function after something is published, but IFTTT claims ‘spark of its api is offline’, not so sure about that :wink: