Electron sometimes freezes on reconnect - Led Solid Cyan

While SYSTEM_THREAD(ENABLED) will usually be the better choice, if that was really the cause for the issue, there should be ways around most anticipated UI issues.

SYSTEM_MODE(MANUAL) may be the better choice especially if you can keep SYSTEM_THREAD(ENABLED).

And of course any of the gotchas mentioned above (if applicable) need to be taken into account

  • be careful what you do in any ISR (no logging, no high level calls, ...)
  • don't use system logging in Software Timers
  • guard against thread collisions where possible or issues may be likely (SINGLE_THREADED_BLOCK or ATOMIC_BLOCK)
  • encapsulate any access to shared resources in "one-place-of-(potential)-failure"
  • ...
1 Like

First of all, thanks for your help!

  • I have a buzzer playing a melody. Every time I call tone() the right note is played but I'm not able to call the function at the right time (Particle.process() blocking the loop I guess).
    This results in multiple second silences between each notes.
  • I must send command to a motor control loop each 20ms. This causes serious trouble as you can imagine...
  • other calls can be delayed without too much problems...

With SYSTEM_THREAD(ENABLED) I just noticed something blocking loop() while photon blinking green... I immediately went outside for better network and the blocking disappeared... I do not even know that I'm using "waiting for something" in my loop...
I read in the doc that Particle.xxx( ) are often blocking, but is there anything else?

Could this behaviour happen with this kind of code (using semi auto):

if(Particle.connected()) Particle.publish("event", buffer, 60, PRIVATE);

[loop thread] calling Particle.connected(), result is true, continue
[process thread] updating the result of Particle.connected() to false as network is off
[loop thread] blocked by Particle.publish()

Could SYSTEM_MODE(MANUAL) solve this?
Could SINGLE_THREADED_BLOCK solve this? (I'd say yes and try it now)

  • Another thing I noticed with the logs: network keep switching between 2G(900+1800) and 3G(900+2100)

  • I'll review my code one more time looking for your bullet list gotchas :slight_smile:

Depending on the actual code doing these jobs, Software Timers or even HW timed interrupts via SparkIntervalTimer might help you out there.

Since the cellular module on Electrons is connected to the ĀµC via a USART connection and the module does tend to block the ĀµC, while it's at work, a bad connection will keep impacting your code. You just need to find the way to make it least noticable.

That depends on the actual cause and use-case, but always worth a try. Some Particle.xxx() functions have been made blocking for SYSTEM_MODE( [SEMI_]AUTOMATIC ) + SYSTEM_THREAD( ENABLED ) but not for MANUAL mode, so best to test.

1 Like

Turns out I have 2 problems linked to "loosing network in a bad cell network area" which could be separated into:

  1. unknown resetS back to back. RESET_REASON_NONE every time. I don't know what are the conditions for this one. The only one I know is after a "particle flash --usb ...". I was kinda hoping a RESET_REASON_POWER_MANAGEMENT or a RESET_REASON_POWER_BROWNOUT. Are those implemented by the way? When is the result of System.resetReason() computed? I guess it's ok if I call it asap from setup.
  2. the deadlock. Which seems (so far) avoided by disabling threads OR removing all Particle.publish() from my code.

Really promising! I'll try! Thanks!

Unfortunately the deadlock is not solved:

  • software timer + System.reset() => nope
  • AppWatchdog + System.reset() => nope
  • hardware timer (SparkIntervalTimer ) + System.reset() => nope

perhaps Iā€™m doing something wrong with SparkIntervalTimer?

IntervalTimer myTimer;
// Pre-declare ISR callback functions
void resetIfUnresponsive(void);

void setup(){
...
myTimer.begin(resetIfUnresponsive, 10000, hmSec);
}

static uint8_t loopUnresponsive = 0;
void resetIfUnresponsive(void){
    if(loopUnresponsive>9){
        System.reset();
    }
    else{
        loopUnresponsive++;
    }
}

void loop(void) {
...
loopUnresponsive = 0;
return;
}

Another thing I found:

  • there is a 10-15 sec delay between the electron losing network and realising it. Even in MANUAL mode with a loop doing only
Particle.process();
Serial.printlnf("Cellular.connecting()  %u Cellular.ready()  %u Particle.connected()  %u           Cellular.RSSI().rssi  %i", Cellular.connecting(), Cellular.ready(), Particle.connected());
  • if I call: if(Particle.connected()) Particle.publish(ā€œeventā€, buffer, 60, PRIVATE);
    during this delay, Particle.connected() returns true and publish() is blocking, causing the deadloop.
    I can reproduce this very reliably:
  • if I do not call publish at all in the same situation, the electron does not freezes but resets a variable amount of time (reason 0)

perhaps Iā€™m doing something wrong with SparkIntervalTimer?

So thats why I guess