Why are Particle.function() and .variable() BLOCKING startup() and loop()?

Hi all,

A little help needed. I’m sure I’m just overlooking something small.

with SYSTEM_THREAD(ENABLED), I understood from docs that setup() and loop() would run immediately after a power-on/reset. Calls like Particle.function() and Particle.variables() would not block startup() execution whilst a connection was being established (although .publish() would)

I’m finding that the moment I call either .function() or .variable() in startup(), it hangs until the connection to Particle Cloud is established. I only get “StartUp DONE!” once wifi/cloud connection is made.

That’s no good for me. I need startup() and loop() to continue independently with other things in the meanwhile until connection is good. I check Particle.connected() before .publish() which should be the only blocking call as far as I can tell???

My sample code fragment below

SYSTEM_THREAD(ENABLED);

double Batt = 13.4F; // 'Batt' Holds the battery voltage (v) to be updated in the Photon cloud

void setup() {
  Serial.begin(9600);
  while (!Serial.available() && millis() < 15000) {
    Particle.process();
    Serial.println("Press ENTER");
    delay(1000);
  }

  bool Result;
  Result = Particle.variable("Batt",  Batt);
  if(!Result) Serial.println("   *** Failed to register variable");

  Result = Particle.function("Main_12v_Bus", toggle12Vbus);
  if(!Result) Serial.println("   *** Failed to register function");

 Serial.println("StartUp DONE!");
}

void loop() {
  delay(2000);    // Do nothing
}


int toggle12Vbus(String command) {
    if (command == "on") {
        Batt = 13.4F;
        return 1;
    }
    else if (command == "off") {
        Batt = 0.0F;
        return 0;
    }
    else {
        return -1;
    }
}

@DominoX, try moving the Particle.variable() and Particle.function() calls BEFORE the “Press ENTER” delay. Also, which version of system firmware are you running?

1 Like

Aw crap … it can’t be THAT simple???

Did what you asked, and suddenly, startup() continues as expected. I get the ‘Press ENTER’ almost immediately and then ‘StartUp DONE!’ almost immediately after that.

WTF?

Firmware 0.6.2

SYSTEM_THREAD(ENABLED);

double Batt = 13.4F; // 'Batt' Holds the battery voltage (v) to be updated in the Photon cloud

void setup() {
  Serial.begin(9600);

  bool Result;
  Result = Particle.variable("Batt",  Batt);
  if(!Result) Serial.println("   *** Register variable failed");
  Serial.println("All variables registered");

  Result = Particle.function("Main_12v_Bus", toggle12Vbus);
  if(!Result) Serial.println("   *** Register function Main12Bus failed");
  Serial.println("All functions registered");

  while (!Serial.available() && millis() < 15000) {
    Particle.process();
    Serial.println("Press ENTER");
    delay(1000);
  }

  Serial.println("StartUp DONE!");
}

void loop() {
  delay(2000);    // Do nothing
}


int toggle12Vbus(String command) {
    if (command == "on") {
        Batt = 13.4F;
        return 1;
    }
    else if (command == "off") {
        Batt = 0.0F;
        return 0;
    }
    else {
        return -1;
    }
}

PK, you’re DA MAN !!!

That worked perfectly. Only headache now is I can’t see any Serial.println() BEFORE the board boots … like any failures on the .function() and .variable() calls.

Anyway, great workaround. Any idea what’s happening here?

It takes a while for the serial monitor to connect (I believe), so if you don't want to put any delays in setup(), you won't be able to see that initial printout directly. You could make Result, and another variable for the Particle.function() result globals, and print out the values of those variables later (in loop maybe).

1 Like

@DominoX, the timing on the calls to Particle.function() and Particle.variable() in setup() is touchy and need to be done without significant delay. This is getting addressed in firmware pipeline so these calls can be made at any time.