Core unstable. Constant wifi reconnect [SOLVED]

So I have a simple program on my core where I have a function that I pass a string that turns a relay on and off. Everything is working except for the small problem of the core only being stable for about 10 seconds before it stops responding. It will then go from breathing cyan to flashing cyan and reconnect after 20 seconds. It has this same behavior if i use the Tinker app as well and manually toggle the relays.

I’m using the python SparkCloudAPI with a simple python script to cycle each of the 8 relays on for 0.5 sec and then off. I can usually get 2-6 relays to cycle before the core stops responding, but its random. I’ve just recently start playing with the core and I’ve been trying to read up on this problem. I’m not sure where to go from here. I’ve factory reset the core 3 or 4 times and it doesn’t make any difference. Do I need to flash and older version of firmware? I can’t imagine its a memory problem, but who knows. At this point my core is unusable, if anyone has any insight on how I might be able to get my core reasonably stable I would be extremely grateful.

@carter, can you share your code so we can take a look? The flashing cyan happens when you lose the cloud connection and that typically happens because the user code does not return control to the “background” task in a timely fashion (10 seconds - sound familiar :wink: ).

int switchLED(String command)
{
    Serial.println(command);
    int cIndex = command.indexOf(',');
    if (command.substring(0, cIndex) == "on"){
        Serial.println("com is on");
        Serial.println(command.substring(cIndex+1));
        if (command.substring(cIndex+1) == "v1"){
            digitalWrite(D0, LOW);
            return 1;
        }
        else if (command.substring(cIndex+1) == "v2"){
            digitalWrite(D1, LOW);
            return 1;
        }
        else if (command.substring(cIndex+1) == "v3"){
            digitalWrite(D2, LOW);
            return 1;
        }
        else if (command.substring(cIndex+1) == "v4"){
            digitalWrite(D3, LOW);
            return 1;
        }
        else if (command.substring(cIndex+1) == "v5"){
            digitalWrite(D4, LOW);
            return 1;
        }
        else if (command.substring(cIndex+1) == "v6"){
            digitalWrite(D5, LOW);
            return 1;
        }
        else if (command.substring(cIndex+1) == "v7"){
            digitalWrite(D6, LOW);
            return 1;
        }
        else if (command.substring(cIndex+1) == "v8"){
            digitalWrite(D7, LOW);
            return 1;
        }
        else {
            return -1;
        }
    }
    else if (command.substring(0, cIndex) == "off"){
        Serial.println("com is off");
        Serial.println(command.substring(cIndex+1));
        if (command.substring(cIndex+1) == "v1"){
            digitalWrite(D0, HIGH);
            return 1;
        }
        else if (command.substring(cIndex+1) == "v2"){
            digitalWrite(D1, HIGH);
            return 1;
        }
        else if (command.substring(cIndex+1) == "v3"){
            digitalWrite(D2, HIGH);
            return 1;
        }
        else if (command.substring(cIndex+1) == "v4"){
            digitalWrite(D3, HIGH);
            return 1;
        }
        else if (command.substring(cIndex+1) == "v5"){
            digitalWrite(D4, HIGH);
            return 1;
        }
        else if (command.substring(cIndex+1) == "v6"){
            digitalWrite(D5, HIGH);
            return 1;
        }
        else if (command.substring(cIndex+1) == "v7"){
            digitalWrite(D6, HIGH);
            return 1;
        }
        else if (command.substring(cIndex+1) == "v8"){
            digitalWrite(D7, HIGH);
            return 1;
        }
        else {
            return -1;
        }
    }
    else {
        return -1;
    }
}
// setting things up
void setup() 
{
    Serial.begin(9600);

    pinMode(D0, OUTPUT);
    pinMode(D1, OUTPUT);
    pinMode(D2, OUTPUT);
    pinMode(D3, OUTPUT);
    pinMode(D4, OUTPUT);
    pinMode(D5, OUTPUT);
    pinMode(D6, OUTPUT);
    pinMode(D7, OUTPUT);
    
    digitalWrite(D0, HIGH);
    digitalWrite(D1, HIGH);
    digitalWrite(D2, HIGH);
    digitalWrite(D3, HIGH);
    digitalWrite(D4, HIGH);
    digitalWrite(D5, HIGH);
    digitalWrite(D6, HIGH);
    digitalWrite(D7, HIGH);
    
    // initalize a function we can access via the Spark Cloud
    Spark.function("switchLED", switchLED);
}

void loop() 
{

}

@peekay123 , the code is ugly but I was just trying to get something working first. I wasn’t sure how to post the code. Sorry for the copy and paste dump. The function seems to work great, the core just stops responding.

I edited the post for you. If you wrap your big block of code in ``` ... ```, it will format it so it's a little more readable.

@wgbartley , Thanks! I’ll remember that for future posts.

I don't know if it makes any difference but my core is the white one from the Kickstarter campaign. I tried the CC3000 firmware patch mentioned in the following post, but it seems to have made no difference.

Hi @carter

It could be a memory problem since every time you do command.substring() it creates a new String object and returns it. I am sure you will run out of memory eventually even if that is not the problem right now.

Maybe you could do your string parsing in a less memory intensive way? String.compareTo() or String.startsWith() do not create an entire new string, for instance.

I missed this part on my original pass! Can I ask how is your core powered? How do you drive the relays from the Core?

1 Like

@bko

I’ll definitely look at improving that. My core still behave the same way if I just use the tinker app though. Could this be related to using the cloud API to call the function?

@peekay123

Core is powered from USB port right now so I can use the serial port for debugging. I’m using one of those SainSmart 8 channel relay boards that is powered independently with a 2 amp 5v power supply.

Hi @carter

The tinker app should be very stable, so I agree that fixing your String issues is a lower priority.

Have you tried using 5 second intervals instead of 0.5 second intervals?

My feeling is that the cloud does not always respond in 0.5 seconds. I know that when I access the Spark api host from my house, it is over an 1/8 of second away so a round-trip takes around 1/4 of second. Sure the delays should be consistent and pipelined, if you will, but I think trying a longer interval might tell you something.

@carter, the documentation for that board sucks! From what I can see, the input is opto-coupled and driving the Spark data pin LOW will turn on a relay. However, driving it high will put about 3.3V on the control pin through two LEDs, a resistor then to Vcc which is 5V. @bko, do you see any potential level problems and would a level shifter/driver be warranted?

Current wise, again from what I gather, each pin needs to sink about 3ma so that should not cause any problems. It is the fact that after 6 relays, you see the problem occur that gets me.

@bko, from what I understand, cloud calls are limited to once per second at most!

I know Spark.publish() is limited but I am not sure about cloud functions and variables. In my servo tests, I know you cannot drag the slider too fast or it gets (temporarily) messed up. As I quoted above, @carter says he is trying to turn things on and off in 0.5 seconds.

I’m currently powering a 4-relay Sainsmart board and Spark over USB. The Sainsmart gets its 5V from the VIN pin on the Core. I do have to digitalWrite(i, LOW) to turn on a relay. It’s been running for a couple of weeks at least. I toggled my deck lights from the Maker Faire (as a demo) at least 2-3 dozen times.

As for cloud function timing, I was doing calls 0.5 seconds apart (or less) with some slight delays. In my browser, I could fire off two calls back-to-back and each one would go through after their appropriate round-trip delays. Standard browsers are typically limited to two concurrent connections per host.

@bko

I took my code back to a basic example where I only switch one relay and off. I’m not parsing any strings or anything. just basic turn on and off pin D7. I modified my test script with a 10 sec delay instead of 0.5. There is no difference at all still getting CFOD and then reconnect.

Do I have a bad unit? Could this have anything to do with my core being a v1.0? It doesn’t seem to matter what my code looks like.

@wgbartley

Out of curiosity, what version is your core?

Off the top of my head, I'm not sure. It's the white PCB, so it's not from the latest batch. Based on my naming convention (it's Epsilon), I'm thinking I received it around January-ish. I haven't done any patching to any Cores beyond my initial Kickstarter-backed Cores.

Just wanted to jump in here on limiting, core event publish’es are averaged to once per second, up to a burst of 4 at a time. The cloud will let you call functions and ask for variables as often as you like, but there you’re making a round-trip, so you’re just limited by your latency.

Hope that helps! :smile:

Thanks,
David

2 Likes