Weird Listening Characteristics

So I have an Argon on OS 1.5.2 and it keeps going into listening mode on boot up.

I’ve done the following to try and make sure it does not go into listening mode:

  • I’ve disabled the setup flag using the function below. This function is called in the setup() phase.
    dct_write_app_data(&flag, DCT_SETUP_DONE_OFFSET, 1);
  • In the setup() function I initialize my WiFi settings by calling the following init() function:
void WiFiNetworking::init() {
    String memberName = mClassname + "init";
    #if (PLATFORM_ID == PLATFORM_ARGON)
        SINGLE_THREADED_BLOCK() {
            WiFi.on(); // Need to be turn on when changing system mode
            if(WiFi.listening()) WiFi.listen(false);
            WiFi.connect(WIFI_CONNECT_SKIP_LISTEN);
        }
        // Always make sure we have 1 network
        if (!WiFi.hasCredentials())
                addNetwork(CommandList::WIFI_ADD_NETWORK,
                           gDefaultWiFiCredentials);
    #else
        Logging::warning(memberName, "WiFi function called on a non-WiFi device");
    #endif
}

I’ve also double checked that it has the added network since when I do “particle usb stop-listening” it immediately connects to my hotspot.

Few things to note:

  • Device is configured with:
SYSTEM_THREAD(ENABLED);
SYSTEM_MODE(SEMI_AUTOMATIC)

I’ve read the API docs + looked at examples on the forum and it seems that I am doing everything correctly. I don’t think I am missing anything else, but maybe someone with a fresh pair of eyes can point me in the right direction.

Can you run a particle serial inspect on the device to check all dependencies are correct?
Also make sure all stored credentials are valid (i.e. clear any preexisting via MODE button and set them again via particle serial wifi without any auto-detect).
Could it be your code calls WiFi.clearCredentials() inadvertently anywhere?

Hello @ScruffR,

I ran particle serial inspect and and everything seems fine. Note I updated to OS 2.0.0 as well.

 Platform: 12 - Argon
Modules
  Bootloader module #0 - version 1003, main location, 49152 bytes max size
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS
      System module #1 - version 1102
  System module #1 - version 2008, main location, 671744 bytes max size
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS
      Bootloader module #0 - version 1003
      Radio stack module #0 - version 202
  User module #1 - version 6, main location, 131072 bytes max size
    UUID: 6A3DC26AE0A9496A8456FA6FCB8AA4E8442350E43F4716467FA33D26CDADE186
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS
      System module #1 - version 1512
  NCP module #0 - version 5, main location, 1536000 bytes max size
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS
  Radio stack module #0 - version 202, main location, 192512 bytes max size
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS

I also manually added the wifi via the particle serial wifi command which worked fine. But then the device still goes back to listening once it reboots. Doing particle usb stop-listening puts it out of listening mode and then it automatically connects again. I think this shows the WiFi credentials are still there.

I’ll double check for WiFi.clearCredentials() but I do not think I am calling this at all anywhere.

Note I’ve double checked the code. I don’t see it calling WiFi.clearCredentials()" anywhere. Doing particle usb stop-listening` and exiting out from listening mode does cause the device to autoconnect to the network so I am pretty sure the credentials are still on the device.

Just as a shot in the dark, could you try particle usb setup-done and see whether that changes anything?
This can replace the dct_write_app_data() call and should only be required once.

If you don’t need mesh support you can now also use the latest release 2.0.0.
The safest way to update would be particle update -v

@ScruffR tried the particle usb setup-done command, device still goes into listening mode after boot up. I’ve also updated the device via particle update -v again and still the same result.

I am fimilar with how listening mode works (i.e. the set up flag, wifi no credentials or even putting it into listening mode programmatically withsomething like .listen() for WiFi/Ethernet/Cellular so this is puzzeling to me. I also tried this on another Argon I had and it still exhibits the same characteristics so I do not think this is a device specific issue.

One question is when excatly does the setup() function runs when the device is in SYSTEM_MODE(SEMI_AUTOMATIC) with SYSTEM_THREAD(ENABLED);? I found that adding WiFi.listen(false); into the loop() solves this issue but adding it to the the setup() does not. In the setup() function I also do both dct_write_app_data() and WiFiNetworking::init(). So either…I am somehow putting the device into listening in the loop() or things in my setup() are not getting initialized. I guess the next thing I’m gonna do is start commenting out portions of code slowly until I get a simple setup() and loop(). Any insights @ScruffR ?

@ScruffR one interesting fact I found…

While commenting out code in the .ino file I did get the Argon to not go into listening mode after rebooting. However, it seems that the area of code causing this has nothing to do with WiFi what so ever. The code causing the device to go into listening mode seems to also vary depending on what other code I comment out which makes no sense. So either I am doing something really dumb or maybe the problem is not code related.

One thing I notice is that my binary size is very very close to the maximum binary size allowed by Argons (~127kb +) and commenting out parts of my code changes the binary size here and there. This is a far fetch and crazy idea but Is it possible that somehow a large binary this is overwriting the flag set by dct_write_app_data()? What is the address of this flag and does it happen to overlap with the APP_FLASH? :face_with_raised_eyebrow:

I cannot promise that’s 100% accurate, but as far as your application code is concerned it will be something like this

  1. all static objects will be initialized
  2. any STARTUP() code will be exectued
  3. the system thread will be spun off
  4. setup() (independent of any network state)

If this is reproducible it might be interesting for the Particle engineers to look into to ensure stability.
@marekparticle, can you get someone to follow up on this as this could be an edge case that might count as bug worth squashing for LTS.

However, @slacker89 since the DCT area would usually be locked but gets unlocked by dct_write_app_data() can you remove that part from your code entirely and only use particle usb setup-done instead. This way we can at least tick off the possibility that this call may be contributing to the issue.
Please also file a support ticket with a reference to this thread and add the ticket number here too.

Thanks this is how I understood it as well. I also tried adding WiFi.listen(false); and the dct_write_app_data() to STARTUP() with no luck. From previous attempts I do know that this was not needed but thought I would try anyway.

Seems pretty reproducible to me. I would be happy to show a particle engineer. I do not want to give out the source code but I am okay with a video call and sharing my screen and show how this can reproduced.

Interesting, I tried your suggestion, removing the dct_write_app_data() followed by particle usb setup-done and it did resolve the issue… here is the following scenario:

  • Flashed Argon with dct_write_app_data()
  • particle usb setup-done and the device stops listening
  • reboot via particle usb reset device boots up with listening mode
  • Repeat with same build but removed dct_write_app_data() from setup and the device did not boot into listening mode after doing particle usb setup-done
1 Like

I’m going to follow up with @avtolstoy about this, thanks for bringing it to our attention both of you!

1 Like

Got an update. We are not too sure of the problem yet but in the setup() functions I called my own setSetupFlag function

image

This function was implemented as below with gSetupFlag declared as 0x01.

void setSetupFlag(uint8_t* flag) {
    dct_write_app_data(&flag, DCT_SETUP_DONE_OFFSET, 1);
}

Replacing this function call with the following code below in the setup() function seems to resolve this problem.

    const uint8_t flag= 0x01;
    dct_write_app_data(&flag, DCT_SETUP_DONE_OFFSET, 1);

I’ll use this for now since it fixes the problem but it still does not explain how the setup flag was being toggled in some scenarios. @marekparticle suggest to use the debugger to step through the code and he thinks that my gSetupFlag is being toggled somewhere somehow.