Over the air flash no matter what

Is there a way to ensure flashing over the air by keeping connected to the spark cloud. I’ve been working with TCP “get requests” from the spark to some ASP code and ultimately to my SQL Server but I can’t always flash over the air. I keep getting “the request seems to take longer than usual. Please be patient…Error: core not found. please check that it is online”, but the spark is breathing cyan.

How can I be able to flash over the air no matter what?

Jay,

You’ve got a few options. If your code is taking up a lot of the CPU time then sometimes it’s hard to hit the “flash window”. There are plans in the pipeline to improve the flashing process (ie, instead of hitting a “flash window” the core will go online and check to see if the firmware to be flashed is different than the current firmware) but in the mean time you again, have several options:

If you are located physically close to the core I would suggest using a pin on the core to put the core into “ok, he wants to flash, stop doing anything except for maintaining the cloud connection”. You could also put a delay in the beginning of the code (in setup) to do the same thing.

Another option would be to emulate the future functionality of the OTA flash. Use TCP connect to grab a small text file on a server you control and update that text file whenever you want to flash. The TCPclient would grab the file, realize it’s different, and then go into “wait for OTA firmware” mode.

4 Likes

Happy to hear about this change as i have struggled with the same issue

Actually I managed this issue messaging Cores via tcp to enter into an idle state and connect to the cloud, as I am working in semiautomatic mode for most of the time.

1 Like

can you share a simple example?

1 Like

I always like to see examples too.

@Herner & @jaysettle

Why, sure. Pseudocode should help, as I am not in office, but you get the idea.
My app is a finite state machine, or, better, an infinite one (have a lot of them).
Bear in mind that you can (and should) extend this example testing for some sort of time lapse (you don’t want to stay with cloud online waiting forever), so, if the time spent on the cloud exceeds, say, 60 seconds, you force a reboot (how rude !) and all starts over again.

SYSTEM_MODE(SEMI_AUTOMATIC);

enum appstates { normal, waitupdate };
TCPclient cli;
uint32_t appstate;

setup()
{
change_state(normal);    
cli.connect(ip, port);
}

loop()
{
    char * data;

    switch (appstate) {
    case normal:             // do your routine job
    data = get_readings_from_adc();
    send_readings_to_tcp(data);
    break;
    
    case waitupdate: // cloud up, cli socket down, only delay(5) in the loop.
    delay(5);
    break;
    }
}

void send_readings_to_tcp(char * outdata)
{
    cli.write(outdata, strlen(outdata));

// server side tells something. Time to close socket and connect to cloud
    if (cli.available()) {
    cli.flush();
    cli.stop();
    Spark.connect();
    change_state(waitupdate);
    }
}

void change_state (uint32_t newstate)
{
    appstate = newstate;
}

char * get_readings_from_adc(void)
{
// get ADC data
}

So every other loop, you alternate between your routine job and connecting to the spark cloud by changing appstate? How long have you been running this and how are your results with flashing?

Do you not need to call Spark.process();?

Thanks btw.

Hi, @jaysettle

No… if you look deeper at the code, you see that the waitupdate state is triggered by the socket connection IF it receives something. What I do is:

A - transmit adc readings to the server
B - test if server sent a message to core. If NO, state remains normal. If YES, socket is flushed and closed, cloud is connected and state switches to waitupdate.

P.S.: Spark.process() is called implicitly at every round of main loop() if working in semiautomatic mode and cloud is online, IIRC, and in this case it is semiautomatic, is online, and doing almost nothing, waiting for an update.

Claudio

1 Like

Ok yes I see that, but when you say “test if server sent a message to core”, are you testing to see if the spark cloud server has sent a message to core, or testing to see if your server has sent a message to core?

I thought your “if (cli.available()) {}” statement was testing to see if your tcp data made a connection/destination from the core to your server. I see that you’re sending adc readings over tcp but I didn’t expect to see your server send back information to the core. Sorry I’ll keep asking questions until I understand exactly how to do this.

Thanks for your time.

cli stands for declaration of TCPClient object.

ur welcome.

Like I said posts ago, I’m not using cloud at all (only for firmware updates), so the tcp client does a connection to my server. It’s a normal client socket that core uses for sending data, but obviously the server can use it too to send messages to the core.

Claudio