Automatically enter and exit listening mode

Would like to set up a photon to automatically start up in listening mode and remain there for five minutes before exiting this mode.

The idea is to give the opportunity to allow setting up a connection to an Access Point using SoftAP without the need to press the set up button (which in this case is not readily accessible).

I have tried the following without joy, ie it would NOT exit listening mode:

setup()
{
WiFi.listen(TRUE);
// Want to stop listening after 5 minutes
oneShot5minTimer.start();

}

// --------------------------------
// Called just once after 5 minutes
// --------------------------------
void OneShot5minTimerCallBack(void)
{

WiFi.listen(FALSE);

}

I admit to not having experimented further with this as yet, it is probably not working because the call is within a timer callback. If this is the issue, will shift it to the main loop and make the call when a flag is set.

Are there any other strategies, thoughts on how to achieve the aim?

1 Like

For one, I’d start the timer before entering Listening Mode and additionally if you use SYSTEM_THREAD(ENABLED) you can have your loop() run while in LM.

And as a final hint, using the STARTUP() macro makes sure that you are entering LM as early as possible.

1 Like

@ScruffR, guess what?

There is an API to do exactly what I want to do - WiFi.setListenTimeout(seconds):

https://docs.particle.io/reference/firmware/photon/#setlistentimeout-

Out of interest, I did try what you suggested and it worked, but my “wifi reconnect” strategy got in the way by kicking off a WiFi connection within loop() and hence a much shorter timeout. I was going to add logic to check to see if it was listening and if so, not to kick off my strategy.

Interesting thing is that by using the WiFi.setListenTimeout() API, my WiFi reconnnect strategy does not kick in (which is good), ie it remains listening for the set timeout.

Case closed!

2 Likes

:+1: Completely forgot about that :blush:

1 Like

Hi -

My apologies for reviving an old thread. Not sure which is less frowned upon, reviving old thread or starting new (but similar) one :see_no_evil:

I have a user case scenario where a device has been working for a while on site and for some reason, either client router is replaced, or WiFi credentials change. As I would not want clients opening up devices, I have come up with the code below to automatically put the device in listening mode:

//  Project:        Listen Mode 
//                  A project by FireFli (PTY) LTD

//  Date:           December 2019
//  Compiled by:    Friedl Basson - FireFli
//                  
//  Details:        The purpose of the code is to put device in listening mode IF:
//                  1.) Unable to connect to Particle Cloud 
//                  2.) Unable to connect to WiFi

//  Firmware:       V1.0.0

unsigned long old_time;
 
void setup()

{
    /////// Application SETUP Code goes here ///////

    old_time = millis();
    WiFi.setListenTimeout(20);          // Exit listen mode after 20s
}


void loop()

{
    /////// Application LOOP Code goes here ///////
    
// == ENTER lstening mode if current Wifi credentials are not valid or if Internet connection is not present == //
   
    if(millis() - old_time >= 20000) {   //Enter listen mode after 20s)
            if(!WiFi.ready()){
                WiFi.listen();
            }
      }

     //System.reset();
}

t seems to be working fine in both scenarios, just wanted to see whether this is actually correct or if there a better way of doing this?

Many thanks!!
Friedl.

The latest update to Discourse (the forum “engine” used here) will now close older topics after 2 months without engagement, so this question will be settled soon.
However, when opening a new thread it’s always good to refer/link to any previous thread that you already found touching on the respecitve topic. This way you can show that you did your “homework” and prevent you from getting the “have you done a search” response :wink:

About the actual point: Without SYSTEM_THREAD(ENABLED) and/or a non-AUTOMATIC SYSTEM_MODE() and/or actively disconnecting your code won’t be running in order to call WiFi.listen().

Also, when something works for you with this little effort the solution can’t be too far off.
But for a “boilerplate” solution this appears to not cater for edge cases and hence seems may not fit every use-cases.

1 Like

Hi @ScruffR

Thank you for the advice, I will be sure to keep it in mind :slight_smile:

I initially had SYSTEM_THREAD(ENABLED) but it seemed to have some ‘unwanted effects’ on the rest of the code I had in a previous project as this was added afterwards. I removed it and all worked as I wanted, al be it, unexpected :slight_smile:

I used Wifi.Ready and WiFi.Listen as I wanted the device to also enter Listen Mode when the connection was lost during normal operation running the code. Without this, I suspected the device would just flash GREEN attempting to connect to WiFi with the stored credentials correct?

Currently, once in listen mode, it seems to work as I wanted, in this case, remains in Listen Mode for 20s, exits Listen Mode and after 20s if unable to connect, enter Listen Mode again.

Thank you for the help, I will use SYSTEM_THREAD(ENABLED) again and do some thorough stress tests and try to recreate all scenarios. I also want to incorporate SoftAP to make it easier for clients to change credentials.

Just to be clear, nothing pertaining C++ is little effort for me :laughing:

1 Like

Hi -

Just an update on this as I needed to implement the same functionality again;

The code I previously mentioned failed to meet the requirement in one specific instance. When device is off at the same time the router is off (or new router or details), it would mot enter listening mode. I did some research on the forum and came up with the code below - first time working with interrupts.

SYSTEM_MODE(SEMI_AUTOMATIC);

boolean connectToCloud = true;

void setup() {
 
    attachInterrupt(A2, connect, FALLING);
    
    WiFi.setListenTimeout(20);
}

void loop() {
    
     if(connectToCloud) {
        if(Particle.connected() == false) {
             Particle.connect();
             connectToCloud = false;

        }
    }
}

 void connect() {
     connectToCloud = true;
     WiFi.listen();
    }

The initial code I used to come up with this was the reverse of what I needed. It kept the device in listen mode and only connected when button is pressed.

I ‘think’ I changed it appropriately to work the other way around. Currently it seems to work with one small undesired effect.

If the router is switched off (or new router, or new details) before the device is powered on, the device takes ±18-20 seconds to enter listen mode once A2 is set low. Is this to be expected? Is there a way I can change so it enters Listen mode as soon as the button is pressed?

I works fine once it has been connected to Wifi at least once.

Many thanks!
Friedl.