New feature: control your connection!

Hi @afromero,

from my understanding the connection to the button is just an example of what you can do in semiautomatic mode. You can use any other pin by adapting the code ( attachInterrupt(D0, connect, FALLING):wink: or do not use a button at all and call Spark.Connect() in some other place in your code.

1 Like

@michael1 - letā€™s take this discussion back over on the original discussion thread for the subscribe problem.

1 Like

Has anyone had a problem with SYSTEM_MODE(MANUAL) and OTA updates? If I set MANUAL and I try to do OTA uptade then core led is solid magenta and then resets it. In loop function I have this:

if(Spark.connected()){
        Spark.process();
        if(serverStatus == 1){
            serverStatus = 2;
            Serial.println("HELLO");
        }
        if(serverStatus == 0){
            serverStatus = 1;
        }
    }else{
        Spark.connect();
        serverStatus = 0;
    }

Do I missing something or it is a bug?

1 Like

Does anyone tried it or perhaps Spark employees can investigate it @zach ?

I can take a look at this the next day or two - from what I know of how this works, this could likely be a bug, since MANUAL mode is expecting user code to call Spark.process() but that is of course not possible during a OTA update.

Until a fix is available, can you use SEMI_AUTOMATIC mode?

Iā€™m trying to help debug this but my core will not even enter breathing cyan in Semi_auto or manual modeā€¦

Weird!!

1 Like

That's by design. With those two modes, the core starts of disconnected. (The change to semi-auto was quite recent.)

The semi-automatic mode will not attempt to connect the Core to the Cloud automatically.

http://docs.spark.io/firmware/#advanced-system-modes

So you need to put Spark.connect() in setup to get it to connect.

I wrote a code to connect like @markopraakli by my core keeps blinking green forever :open_mouth:

Update

Alright so letā€™s ignore my code. I got it working now (somehow). I just tested OTA in SEMI_AUTOMATIC and itā€™s flashing well now as we speak.

Will jump over to MANUAL next

Try dropping the Wifi calls - they shouldnā€™t be needed and could be interfering. (I agree this code should work as is, and that the extra calls to Wifi should have no effect if not needed.)

I uncommented this to let SPARK_WLAN_Loop() handle Spark.process() instead and was able to perform OTA flashing successfully.

Seems like some flags are not being set in Spark.process()? Just my wild guess. :wink:

I tried the following but it didnā€™t work as well:

SPARK_WLAN_Loop();
Spark.process();

@mdma, i have found the issue :smiley:

Due to that new IF condition (for the case of MANUAL, during an OTA update, Spark.process() is not executed just before OTA update.

See: https://github.com/spark/core-firmware/blob/c8fa2e0b79f9792f6dc9a6bd07697ca300cee9bc/src/spark_wiring.cpp#L666

I added a Spark.process() after the line and tada! OTA :smiley:

8 Likes

Nice! I am repeatedly clicking the ā€œlikeā€ button, sadly discourse will only give one like!

@zachary has been working in this area recently so he might be interested in looking at the fix.

I think thereā€™s more cleaning up than it looks thoughā€¦

But itā€™s probably due to my poor understanding of the entire firmware for OTA flashing.

The SPARK_FLASH_UPDATE flag gets set to 0 in the Spark.process() function though OTA is happening. I wonder whatā€™s the rationaleā€¦

I have used all three modes and found some minor issues that appear to have been resolved. I initially used the MANUAL mode and called ā€œSpark.process()ā€ every second or so in my main loop. However, when I tried to Spark.connect() I had the breathing cyan led but no connection. It was fine for working on a local network but to synchronise the time I had to download a Unix timestamp over the local TCP IP connection as I couldnā€™t use Spark.syncTime();

Next, I started using SEMI_AUTOMATIC mode and this was perfect for my code, allowing it to work on a local network and then calling Spark.connect() when required to download new firmware or to use Spark cloud functionality such as Spark.variable and Spark.syncTime. However, I had to call Spark.process() regularly in my main loop - this is not made clear in the documentation.

AUTOMATIC mode took care of everything but I prefer the above SEMI_AUTOMATIC to minimise any critical timing issues.

Overall I would say this functionality is a great step forward for those of us who want to dip in and out of the Cloud.

Thanks @kennethlimcp! Please submit a pull request to core-firmware. In order to avoid calling Spark.process() in MANUAL mode without the userā€™s consent, I think youā€™ll need to wrap the call to Spark.process() in if (SPARK_FLASH_UPDATE). See these two functions which set and reset it to indicate that OTA is in progress.

@zachary, just an update that iā€™m still working on this issue. I believe the issue is more than just Spark.process() not being called.

Iā€™m debugging and nothing it Spark.process() gets executed as the conditions defined are not met to qualify for the variables to be set.

Gonna dig further.

The last DEBUG message i read before the solid magenta occurs is:

0000154508:<DEBUG> void SPARK_WLAN_Loop() (373):
SPARK_CLOUD_SOCKETED=1
SPARK_CLOUD_CONNECTED=1
SPARK_FLASH_UPDATE=1
SPARK_LED_FADE=1

We might probably need to review the SYSTEM_MODE code as i tried to force the error using AUTOMATIC with the same condition as how MANUAL behaves and OTA flash still worked fine! :open_mouth:

Seems like I found a nice bug regarding MANUAL and OTA updates (glad to help you) :blush:
Do you guys have ETA to fix this?

so static ip with no cloud used to be this:

#include "spark_disable_cloud.h"

unsigned long pucSubnetMask[1] = {0x00ffffff};
unsigned long pucIP_Addr[1] = {0x2a00a8c0};
unsigned long pucIP_DefaultGWAddr[1] = {0xfe00a8c0};
unsigned long pucDNS[1] = {0x08080808};

netapp_dhcp(pucIP_Addr, pucSubnetMask, pucIP_DefaultGWAddr, pucDNS);   
wlan_stop();
delay(200);
wlan_start(0);

but is now this:

SYSTEM_MODE(MANUAL);

unsigned long pucSubnetMask[1] = {0x00ffffff};
unsigned long pucIP_Addr[1] = {0x2a00a8c0};
unsigned long pucIP_DefaultGWAddr[1] = {0xfe00a8c0};
unsigned long pucDNS[1] = {0x08080808};

WiFi.on();
WiFi.disconnect();
netapp_dhcp(pucIP_Addr, pucSubnetMask, pucIP_DefaultGWAddr, pucDNS);   
delay(200);
WiFi.connect();

Or static IP with cloud is:

SYSTEM_MODE(SEMI_AUTOMATIC);

unsigned long pucSubnetMask[1] = {0x00ffffff};
unsigned long pucIP_Addr[1] = {0x2a00a8c0};
unsigned long pucIP_DefaultGWAddr[1] = {0xfe00a8c0};
unsigned long pucDNS[1] = {0x08080808};

WiFi.on();
WiFi.disconnect();
netapp_dhcp(pucIP_Addr, pucSubnetMask, pucIP_DefaultGWAddr, pucDNS);   
delay(200);
WiFi.connect();
Spark.connect();

see also here

2 Likes

In the long run, imagine static IP support will be baked into the firmware as part of the wifi setup, since the call to netapp_dhcp() is persisted in the cc3000 eeprom. (This same fix also overlaps with enabling the 11-13 channels, since that is also persisted data and set as part of wifi setup.)

1 Like

Hello everybody !

Iā€™m actually trying to :

  • run my Spark on a local network (i.e. connecting it to a local Access Point, without connecting it to the Cloud because it will be used in a place where no connection to the internet is available)

  • provide the SSID of my local Access Point directly in the code

By reading all the topics on the subject from last March, Iā€™ve understood that the use of #include spark_disable_wlan.h, #include "spark_disable_cloud.h and #undef SPARK_WLAN_ENABLE have been more or less deprecated. So Iā€™m trying to do it with the WiFi and Spark classes,

Iā€™ve tried to do this by putting SYSTEM_MODE(SEMI_AUTOMATIC); at the top of my code, then this in the setup() function :

if (WiFi.hasCredentials()) {
WiFi.clearCredentials();
}
WiFi.setCredentials(MY_AP_SSID, MY_AP_PASSWORD, WPA2);
WiFi.on();
if (!WiFi.ready()) {
    WiFi.connect();
}
Udp.begin(8888);

but it doesnā€™t workā€¦ I canā€™t manage to get the LED breathing cyan, informing me that the connection has been successfull.

Can anybody explain me why my code doesnā€™t allow my Spark to connect to my local Access Point ?

Thanks !

(PS : Iā€™m compiling my code with the latest firmware and gcc by using the DFU mode)

What colors is your led showing now?

In my understanding SYSTEM_MODE(SEMI_AUTOMATIC) is all off the automatic mode stuff, except for the Spark.connect() call. After obtaining a working Wifi connection, your led should breath green, not cyan.
I can imagine that for setting the credentials manually, MANUAL mode would be more suitable, requiring you to setup the connection yourself. Have you tried that to see how that works out for you?

1 Like