Photon flashing red on particle.publish [SOLVED]

Hey

I have a code that runs mainly offline, but at a button press, it connects to wifi and publishes a given number of hours logged offline to a google drive document through IFTTT. Only problem is, every other time or so it flashes red after connecting the wifi, and then turns white again, without publishing. The string it publishes is limited to 30 or so characters and the Particle.publish is not called often, but is, however in a separate void postToDrive(), and I just read somewhere else that it’s better if it’s called in main loop! I’ll post the whole code, but it’s excruciatingly long, and the publishing is what I’m mostly uncertain of so for now I’ll post only that:
(mind you, this is only a part of the code, but all the necessary information should still be there. the code works perfectly without the publishing)

char* myStrings[12] = { 
  "VELOtrail",
  "FutureBuilt",
  "WorkLogger",
  "LeafBall",
  "Visual ID",
  "Schoolies"
};

void setup()
{
  WiFi.off();
}

void loop() {

  if (stopActivity) {
    WiFi.on();
    strip.setBrightness(maxValue);
    for (int i = 0; i < totalPixels; i++) {
      strip.setPixelColor(i, red / factor, green / factor, blue / factor);
      strip.show();
      delay(sweepAnimation);
    }
    if (workSec > 0 && workSec <= 30) workSec = 5;
    else if (workSec > 30) {
        workMin++;
        workSec = 0;
    }
    stopHrs = workHrs;      // save logged hours
    stopMin = workMin;      // save logged minutes
    stopSec = workSec;      // save logged seconds
    activity = false;
    stopActivity = false;
    postValues = true;
  }
  
  if (postValues) {
    if(WiFi.ready()) {
      postValues = false;
      postToDrive();          // call transmitter
    }
  }

void postToDrive() { 
    char publishData[25] = "";
    sprintf(publishData, "%s|||%u,%u", myStrings[project], stopMin, stopSec);
    Particle.publish("data", publishData);
    
    for (int i = 0; i < totalPixels; i++) {
      strip.setPixelColor(i, color);
      strip.show();
      delay(sweepAnimation);
    }
    workHrs = 0;            // reset hours
    workMin = 0;            // reset minutes
    workSec = 0;            // reset seconds
    WiFi.off();
    timeStamp = millis();
}

Thank you

First, if you are intending to run offline most of the time using SYSTEM_MODE(SEMI_AUTOMATIC) would be a better choice than going with default SYSTEM_MODE(SEMI_AUTOMATIC).

Next you'd need to call Particle.connect() and check for Particle.connected() rather than only WiFi.on()/WiFi.ready() in order to successfully Particle.publish().

Publishing without propperly established cloud connection might well result in a red SOS.

This might be a misunderstanding on your or a misconception on the sources side.
It's best to not call Particle.publish() from an ISR, a Particle.function() or a Particle.subscribe() handler and such, but it's OK to put it in a "normal" function.

1 Like

@batmanish in addition to what @ScruffR, the tireless Elite said, I have to add these comments:

  1. If workSec is an unsigned var then you don’t need workSec > 0 in your IF statement
  2. Assuming the above is true, then the else if (workSec > 30) is not necessary since values are either <= 30" or everything else is> 30’. So all you need is else {
  3. Calling Particle.process() right after Particle.publish() will ensure the publish gets processed asap.

If you want to save power, then run in SYSTEM_MODE(MANUAL) and write a function that:

  • Turns on WiFi and waits for WiFi.ready() with a timeout using waitFor(). You can decide what to do if the wifi doesn’t connect within the waiting time.

  • Connect to the Cloud and wait for Particle.connected(), again using waitFor()

  • Do the publish, call Particle.process and use one of two ways to ensure your publishes are complete:

    1. Do a millis() delay which calls Particle.process() every 10 ms while delaying or,
    2. Fire off a webhook using a publish as the last of your publishes. You would have subscribed to the webhook event in setup(). When the subscribe function gets called, you know your done!
2 Likes

@peekay123, In regard to your comments about ensuring that publish is complete, what does it actually mean when publish returns true? Is this only an indication that the device is connected to the cloud, or does returning true require some acknowledgement from the cloud, that the publish was successful? I’m asking about this in regard to knowing when, after a publish, I can put the Photon into deep sleep.

This only indicates that the data has been successfully handed over to the WiFi module, which will do its job asyncronously to your application.

@Ric, excellent question! The Particle.publish() function is managed by the system thread, in the background. So when you call Particle.publish() with or without the SYSTEM_THREADS enabled, the function will return false if there is no active cloud connection and true if the function successfully “passed” the call to the system thread. It does not, however indicate that the publish was successfully sent to the cloud nor that the cloud actually performed the publish.

So, first to make sure the Photon has actually published, you can call Particle.process() and/or wait after the publish. Another way is to add a extra publish which fires a webhook that you also subscribe to. When the subscribe function is called, you know the end-to-end publish has completed.

@peekay123, thanks for the response. I don’t understand the first option of calling Particle.process() – my understanding of that, is that it will cause an immediate process() to be called instead of waiting for the end of loop(), but you would still have to wait (for how long?) for the transmission to the cloud to occur, correct? For the second approach, do you need to use a webhook, or can the Photon just subscribe to its own extra publish event?

Thank you guys very much for all your responses. I added SYSTEM_MODE(MANUAL), enabled SYSTEM_THREAD, changed WiFi.on() and WiFi.ready() to Particle.connect() and Particle.connected() and added Particle.process() and the photon now publishes every time, without ever (so far) SOSing. @peekay123, about the whole workSec thing, the script is a timer, and that snippet you’re mentioning is just to round up to 0,5 or 1,0 minutes (actually hours, but minutes for quicker testing), and the numbers are temporary. They may be changed to once passed, say 15 seconds, round up to 0,5 minute, and passed 45 seconds, round up to 1,0 minute, if you catch my drift. Thank you though.

2 Likes

Also, I guess this is solved now, how does one mark a post as solved?

I guess you found out how to, as it is [SOLVED] now :wink:

1 Like

Nope, someone else must have done it.

OK, it’s rather easy.
When you click on the topic title, a pencil-symbol will appear next to it.
Click on that and just add the word [SOLVED] and press the tick button.

You know, I thought so, but it seemed so easy. Too easy! I was hoping there was a button. Oh well

2 Likes