Wifi.ready not working

Spark stuck on slowly breathing blue led after wifi.on
I cant get the spark to go into :
if (WiFi.ready()) {
}

Did they changed something in the last firmware update? do you have any suggestions?

Are you using Manual mode?

There’s a recent addition of feature to allow control of connection to the cloud. More information here: http://docs.spark.io/firmware/#advanced-system-modes

1 Like

you say “blue” is it light or a darker blue - (blue or cyan)? flashing blue is listening mode, where the core is ready to accept wifi config. breathing cyan is connected to the cloud.

more details under LEDs in the docs.

He meant dark blue, I’m also working on that project, and thats a piece of code that stopped working suddenly it used to work before, and we do manage to connect to the network before calling WiFi.off.

Little more info : we need to save battery so we start the core by waiting in Wifi.Off state untill the user clicks a button, then we do WiFi.On and wait for WiFi.ready() before we try to establish a TCP connection, but it doesn’t seem to get to WiFi.ready anymore,
also @kennethlimcp, I don’t get why we need to bother with manual mode, we need a TCP connection not to connect to the cloud.

The system modes govern both when wifi is enabled and when the cloud is enabled. Using system mode MANUAL will give you full control over the wifi connection and the cloud connection, with both disconnected initially. Wifi will be initially off until you request that it comes on, if you're using automatic mode, it will come on initially and then you turn if off.

But I don't think this has anything to do with the problem you're seeing.

Wifi.ready() waits for WLAN_DHCP to be set - so this will hang until the spark recieves a DHCP assigned address. If not done already, please call Wifi.connect() after Wifi.on() to be sure a connection to the network is established (IP address etc..)

2 Likes

thanks mdma, I’ll try this as soon as I can, if this works its the second time that firmware updates broke my code and forced me to make changes in a previously working code, it should be a blessing that firmware updates arrive at this pace but it turns out to be very disturbing, at least while using the web ide.

anyway, thanks a lot! the community is always very helpful!

I’ve been trying to use WiFi.ready() like so while (!WiFi.ready()) in Setup() to make sure that I have a valid localIP assigned before trying to do a TCPClient.connect() to a server of mine. It was not working and I’ve validated that it actually does not have a valid IP via WiFi.localIP() - it comes back zero. Then I traced the code in core-firmware and it appears that the code does no in fact wait for there to be a valid IP address before WiFi.ready() returns true. Can someone please confirm this who works for Spark?

1 Like

HI @jhodapp . Good question!

WiFi ready() is flagged as true when the wifi connection is established - that is when the device has connected to the access point with the credentials and password. The IP address is obtained via DHCP which takes some time afterwards. This is done asynchronously and the address updated as part of the background loop.

To wait for the IP to be assigned, check WiFI.localIP() while calling SPARK_WLAN_Loop(), like this:

while (WiFi.ready() && WiFi.localIP()[0]==0) {
   SPARK_WLAN_Loop();
}

But be careful with code like this - routers can go offline, and wifi connections dropped for various reasons, so best to program defensively and handle the case when you don’t get a local IP.

Alternatively, if you use AUTOMATIC mode, the IP is set before setup() is called.

2 Likes

Thanks for the reply!

I do have to comment and say that the documentation on this function call is highly misleading. It outright says:

This function will return true once the Core is connected to the network and has been assigned an IP address, which means that it's ready to open TCP sockets and send UDP datagrams. Otherwise it will return false.

As I already stated previously, I've found this to not be true and confirmed it by studying the code. I think this documentation needs updating or the code needs improving.

1 Like

That’s a good point. It seems that there the docs state the correct intent, while the code implements something else - namely fetching the IP asynchornously.

We could change WiFi.ready() to do what the docs say - what to people think?

It might need a timeout and error return value since there are some folks that want to not block forever waiting if it fails for some reason.

As I envisage it, WiFi.ready() would continue to be a status report - not blocking. The change in behaviour would be that it only returns true once the IP has been established, rather than the current behaviour where it returns true as soon as the wifi connection is established, but before the IP has been assigned via DHCP.

(Actually behind the scenes the IP has been already assigned, but it's not copied to the address used by WiFi.localIP() until the next iteration of the background loop. I'm guessing this is a workaround for some cc3000 issues.)

This sounds perfect to me. Let me know if you need someone to test this out after you get it coded up. Thanks!

Hi @mdma

That sounds good but the example has to indicate that you cannot just hard while loop on “not ready” without calling SPARK_WLAN_Loop() or equivalent in the loop.

Since this is a common case, I’ve wondered why we don’t have a method that waits for wifi to be in a given state that also runs the background loop.

if (WiFi.waitUntil(CONNECTED, 10000)) {
   // wifi now connected and with an IP
}
else {
   // wifi didn't connect within 10 secs
}

The waitUntil() method would run the background loop as necessary, so user code can focus on what state they are trying to get into rather than how to get there.

The same could be applied to Spark also to wait for cloud connect/disconnect.

Yes absolutely, both of these would be welcome additions and I think very common use cases for many developers. It’s much better than having to call the internal SPARK_WLAN_Loop() function.