Issues with RETURN_ON_ERROR

Hello,

I am using an april board and an imp card for an application that requires high power efficiency. For this reason I am using the instruction server.sleep() when the imp is idle. The thing is that everything worked fine until I tried to change the default settings of server.setsendtimeoutpolicy() to RETURN_ON_ERROR so the imp keeps executing my code even when it is unable to connect to a WiFi network. For some reason that I cant figure out, whenever the imp goes to sleep, it never wakes again. I am not using the server.connect() instruction because I read in the documentation that the imp tries connecting on its own when waking from a deep sleep.

Do you know anything about this issue?

Thank you for your attention!

The imp is likely waking fine, but because when in RETURN_ON_ERROR mode the imp will NEVER start a connection as a side-effect of (eg) a server.log or agent.send, you must use server.connect().

The imp, even in SUSPEND_ON_ERROR mode, does not connect when waking from deep sleep. In that mode, though, the first attempt to communicate with the server will force a connection.

So… use server.connect() when you want to be connected and you should be fine.

I tried using server.connect() but the imp is not waking up. The first three lines of my code are the following:
server.setsendtimeoutpolicy(RETURN_ON_ERROR, WAIT_TIL_SENT, 30.0); server.onunexpecteddisconnect(DisconnectionHandler); server.connect(DisconnectionHandler,30.0);

where DisconnectionHandler only updates a flag’s value.

Is there anything else I might be doing wrong?

Thanks!

What’s your disconnectionhandler? It needs to take a parameter otherwise the callback will instead throw an error.

This is the disconnectionhandler:
function DisconnectionHandler(reason){ if (reason!=SERVER_CONNECTED){ nv.disconnectedFlag = true; } else { nv.disconnectedFlag = false; } server.log("Disconnected FLAG = "+nv.disconnectedFlag); }

That looks ok but without seeing your whole code I don’t know what might be happening. Note that the connection happens in the background, so the rest of your code is running during the connection attempt. If this sleeps then it’ll never connect.

Ok, so now I know that the connection happens in the background. My inmediate thought was to add a delay (imp.sleep(20)) for 20 seconds to check wether my code was being executed so fast that the imp didn’t have time to connect. My new first four lines of code are:
server.setsendtimeoutpolicy(RETURN_ON_ERROR, WAIT_TIL_SENT, 30.0); server.onunexpecteddisconnect(DisconnectionHandler); server.connect(DisconnectionHandler,30.0); imp.sleep(20);
My device is still not connecting back or showing any lights after the first disconnection.
The way I send it to sleep is:
imp.onidle(function(){ server.log("-------The imp is shutting down"); server.sleepfor((nv.interval) * 60); })
I seem to be running out of ideas to solve this problem. Any comments will be greatly appreciated.

server.connect() attempts a connection and the function you pass to it is called once regardless of whether the connection is successful or not. It’s a one-shot process. If you want it to connect again, you need to make sure that your DisconnectionHandler calls server.connect() again, directly or indirectly.

I use different handlers for server.onunexpecteddisconnect() and server.connect(), as they have slightly different purposes. Just so my state machine understands what state wifi is in at startup I also call my “ConnectionHandler” directly. This tells me if the squirrel code is running with or without a wifi connection. KEY_UNKNOWN_REASON is an arbitrary value that’s distinct from the enumerated values that the server.connect() handler is called with.
server.setsendtimeoutpolicy(RETURN_ON_ERROR, WAIT_TIL_SENT, 30); server.onunexpecteddisconnect(_onDisconnect.bindenv(this)); _onConnect(server.isconnected()?SERVER_CONNECTED:KEY_UNKNOWN_REASON);
My connection handler is roughly like this…
`
function _onConnect(reason) {
_update(reason); // update wifi stats

    if (reason==SERVER_CONNECTED) {            
        if (_connectCallback!=null)
            _connectCallback(_state.ssid,_state.bssid);
        _state.retries=0;
    }
    else {
        // connect has failed, take action
        _state.retries++;
        server.connect(_onConnect.bindenv(this), _config.timeout);
    }
}

`

@bfc-sensors I’m not sure that a busy-wait in the foreground is the best thing to do here, ie I’m not sure how that will affect the connection process. It should be fine (on another thread), but I’ve never tried it myself.

If you want to absolutely stop any other foreground code executing after those 4 lines for debug purposes, just use “return” at line 4. This stops your code execution and the only thing that’ll happen on the device after that point are callbacks you’ve already registered.

Rest assured though, this is not an imp problem. Many customers do exactly what you’re doing without issues, so it’s got to be something incorrect in your implementation, we just have to find out what.