Thing.handle() hangs when there's no wifi

I use my main loop to both handle wifi connection (using thing.handle()) and handle physical peripherals namely button presses.
If there’s no wifi (my router occasionally stops working…) I can no longer detect button presses because I suspect the thing.handle() doesn’t return.

Is this a known problem? Am I doing something wrong?

Thanks!

Hi @jonspieg, this is more or less the expected behabiour. The thing.handle() is trying to connect to the Wifi every time it is called. If the router is not connected, the device will take some time trying to connect to your access point. If it cannot connect, the library adds 5s delay (to avoid reconnecting too fast), and will exit the handle function. So, the handle function is returning, but it takes too much time to be able to recognize buttons changes. When the device is correctly connected, the handle function should be able to return quite fast, allowing a normal loop behaviour.

In this case I think that you can use processor interruptions, so when you press a button, your code is called… It should work, let me know!

Hi Alvaro,
I think it is common issue for a real device in IoT. Sometimes ethernet or wifi connections are not available. In this case the device must continue reading buttons or doing any kind of control in the main loop without delays. When the internet connection is available again the device has to resume reporting to the cloud. This is a desirable behavior, and it is common in industrial control. Using interrupts is an option but not always possible, so I think a non blocking handle function could help to solve this issue. In my scenario I am reporting the level of 3 fuel tanks to the thinger.io cloud and locally to a HMI connected using MODBUS RTU, but sometimes the user disconnects the ethernet cable and the system has to continue working locally without the cloud connection.
Please let me know how can I improve the handle() function because when the ethernet cable of my arduino mega + ethernet shield is not connected the main loop is not executed adequately.

Hi @Alejandro_Mera, in this case, If you are using a Mega + Ethernet Shield, I think you should take a look to this class:

I have not tested it, but for your use case, I would change the connect_nectwork function to something like this:

 virtual bool connect_network(){
       if(connected_) return true;
        // random mac
        byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
        THINGER_DEBUG("NETWORK", "Initializing Ethernet...");
        if(Ethernet.begin(mac)==0){
            return false;
        }
        THINGER_DEBUG_VALUE("NETWORK", "Got IP Address: ", Ethernet.localIP());
        connected_ = true;
        return connected_;
}

This way we are removing any delay while trying to connect. Not sure if the Ethernet.begin call will take too much time to complete to make the device not responsive to buttons presses. But, as you say, the best way to handle this is with interruptions.

Let me know if it works, maybe we can optimize this in a different way.

The thing.handle(); line is also blocking for 5sec when the device is not set up on the console…
IMHO that really should not be.
If Thinger is acessible, but does not (yet) recognize the device, thing.handle(); should resume without delay.