[solved] 1.4.2 Red SoS with semi automatic, particle.connect causes hard fault


#1

Basically if you don’t call wifi.connect, then a large delay and call particle.connect, it will red sos flash.

Another day, another glorious round of bugs.


#2

Happy to be shown test case code of best practice how you are meant to use semi automatic with system thread and connect to wifi and cloud in a post 1.1.1 (ie 1.4.2) world.

  • Include particle.variable and functions
  • Include wifi.?
  • Include particle.connect / other mechanisms to detect it’s ready to proceed towards the glorious future of being online.

I’m presuming the current documentation is out of sync because it says particle.connect wraps up wifi.connect et al. Which is how it’s worked since it was a spark core and not a particle p1. Now after 1.1.1 I’m having to put a wifi.connect call, then a large delay, then call particle.connect. Otherwise a glorious display of red SoS.


#3

Is this with P1 or Photon? I am using Photon and haven’t noticed this as a problem with 1.4.1 or 1.2.1.

Just to be clear I am using SYSTEM_MODE(SEMI_AUTOMATIC) and SYSTEM_THREAD(ENABLED) in all applications and do the following in setup()

  • Particle.function() and Particle.variable() declarations
  • Check for stored WiFi credentials
  • if stored credentials then WiFi.connect(), waitFor(WiFi.ready, 6s x number of stored APs)
  • if WiFi.ready() then Particle.connect(), waitFor(Particle.connected, 8s)

I have been doing it like this since 0.7.0 - the waitFor()s and checking successful before next step is critical IMHO.


#4

Hi @mterrill, thanks for reporting this!

Are you able to reproduce this issue with a smaller, abstracted version of the code above (just the important bits necessary for the hard fault)? Would love to test this myself, thanks.


#5

The issue opened in GitHub above has a test app that does not compile and is incomplete. Can you post a compilable test app that shows the error - this way we can focus on the issue and not have to make assumptions about what your code is supposed to do?


#6

Hi Marek, I did post a gist afterwards to make it super easy for folk. https://github.com/particle-iot/device-os/issues/1958#issuecomment-550599059

Includes steps on how it works on everything from 0.5.5 up to roughly 1.1.1 but hard faults on 1.4.2


#7

With a P1.

Do you have a gist copy/paste of the relevant section available? I’m interested particularly in your 6s x number of stored APs approach.


#8

At the end of the day sometime after 1.1.1 some changes were made that meant the timer contained particle.connect isn’t thread safe anymore. Also a new need to run wifi.connect before particle.connect.

There’s no documented best practice code for how semi automatic + system thread should register functions, go online, and all the normal things. A compilable code shim would be good.


#9

The upshoot is our devices being assembled and flashed in china fail to register in anything resembling a timely fashion their functions. So we’re having to turn off the board validation where we check via particle cloud that it’s reading according to our tolerances. Normally it’s pass/fail, and rarely fails, so we’ll have to presume it’s ok because it’s been a week of delay so far and we need the product in Australia.


#10

My memory was bad - actually 8 seconds. Code snippet below (see the comments about blocking and non blocking). Once the IP address is assigned the Cloud connection is straight forward.

        if (!WiFi.ready() && !isWiFiOutofRange)                     //wifi is off but WAP not known to be out of range
        {
            WiFi.on(); 
            delay(100); 
            hasStoredCredentials = WiFi.hasCredentials();           //should be non blocking before connected
            int sap = WiFi.getCredentials(ap, 5);
            unsigned long timeout = 8000 * (unsigned long) sap;
            if (hasStoredCredentials && !hasBadCredentials)         //credentials exist but they may not be in range or may be wrong
            {
                WiFi.connect(); 
                delay(100);
                waitFor(WiFi.ready, timeout);
                if (!WiFi.ready() && hasStoredCredentials)          //stop trying to find WAP and block application if there are credentials but a wifi connection to one of them cannot be made
                {
                    if (isStartup) hasBadCredentials = true;
                    else if (wasWiFiConnected) isWiFiOutofRange = true;
                    else hasBadCredentials = true;
                }
            }
        }

#11

when do you particle.connect?


#12

Hi all, @avtolstoy solved it. It’s actually related to the wifi.macaddress call and system thread enabled. Being tracked and solved via https://github.com/particle-iot/device-os/issues/1858


#13

when do you particle.connect?

Just after the code snippet I included. If the local IP address is assigned (tested with WiFi.ready()) then I proceed to calling Particle.connect(); I know some view the WiFi.ready() as not reliable and therefore test for local IP address set (not all 00s) but I haven’t observed this issue.

Interesting that the WiFi.macAddress() was the cause - when are you calling this? Before or after WiFi.ready()/local IP address assigned? I do it after I have connected to WiFi and I haven’t noticed an issue. Is that a work around?

Anyhow, glad to hear that Andrey has solved the issue - just wonder when 1.5.0 will be out?


#14

I was calling wifi.macaddress after wifi.connect. With a delay it doesn’t SOS. Without a delay it does.

I should have stripped the code down further and I’d have found it but it seemed pretty innocent.

I’ve gone back to my old process of just calling particle.connect from the timer, which works fine.


#15

I received our shipment this afternoon. Seems that approach doesn’t cover all our test cases.

At the moment it seems if it sees particle.subscribe before a connect red SOS. More time to test…