Photon keeps disconnect and reconnect to the cloud

I have a photon connected to a vehicle loop detector. When a vehicle is detected, photon will publish to telegram’s webhook. I can see the telegram message and notification on my smartphone/desktop. This is working as I wanted so far. And I have been following this tutorial

Problem is this Photon keeps disconnecting from the cloud. I can see that the LED will change from “breathing cyan” to “high speed flashing cyan” and back to “breathing cyan”. I can also see that the events:

  • device came online 8:33:01
  • device went offline 8:32:58
  • device came online 8:30:10
  • device came online 8:28:22
  • device came online 8:26:52
  • device went offline 8:26:51
  • device came online 8:25:23
  • device went offline 8:25:21

While the device is offline (high speed flashing cyan), photon does not trigger/publish the event/webhook even though the loop detector detects a car. This means there are chances that I miss out some passing cars.

  1. Anybody know why my photon keeps disconnecting and reconnecting to the cloud?
    This question is not that important, since there are many reasons why it just happens.

  2. So while it is disconnected (high speed flashing cyan), how do we make the photon to publish to the webhook as soon as the photon is connected back to the cloud?

Particle.publish(“telegram-user”, “A car just passed.”, 60, PRIVATE);

Most likely your code is blocking long enough to cause the cloud drop. Seeing your code would be helpful.

By the text sent with this event, if you should happen to have this reporting traffic on a busy road you may be exceeding the rate limit of max. 1 even/sec.

1 Like

My original codes were similar to that tutorial:

void setup() {
        pinMode(D0, INPUT_PULLUP);
}

void loop() {
    if (digitalRead(D0) == LOW) {
        Particle.publish("telegram-user", "A car just passed.", 60, PRIVATE);
        while (digitalRead(D0) == LOW);
    }
}

Currently the photon + loop detector are still on my table. And it will be used in private street so it won’t hit that rate limit.

I don’t see any code blocking delay() in that original code.

Reading here and there, I added a Particle.process() every second in the while loop.

    while (digitalRead(loopDetector) == LOW) {            
        if (millis() - lastTime >= 1000) {
            Particle.process();
            lastTime = millis();
        }
    }; // hang tight here until vehicle leaves

I guess this has solved your problem since this line was potentially killing the cloud connection if you had D0 == LOW for more than 10 seconds.

Since it doesn’t hurt to call Particle.process() in rapid succession, you can have the solution much simpler like this

while (digitalRead(D0) == LOW)
  Particle.process();

But in general it’s best not to block loop() at all and rather go with something like this

void loop() {
  static int prevState = -1;
  int currState = digitalRead(D0);
  if (currState == prevState) return; // only proceed when state has changed
  
  if (!currState) {
    Particle.publish("telegram-user", "A car just passed.", 60, PRIVATE);
    delay(1000); // "debounce" and obey the rate limit
  }

  prevState = currState;
}

Your code/solution does make more sense. Thanks!

Not really sure it is needed, but I added a while loop to ensure that the event has been published correctly. I assume doing a Particle.publish() without checking Particle.connected() first is not sufficient. If somehow the photon is not connected to the cloud, and Particle.publish() has been launched, that particular event will be lost.

bool success = false;
do {
    success = Particle.publish("telegram-user", "A car just passed.", 60, PRIVATE);
    delay(1000); // "debounce" and obey the rate limit
} while (!success);

If you want to make sure the event has actually been published, checking the return value alone isn’t really helping there since it only reports whether the event could be handed to the radio module successfully, but not whether the module could deliver the event.
If you want that, you should use the WITH_ACK flag like this

  success = false;
  if (Particle.connected()) {
    success = Particle.publish("telegram-user", "A car just passed.", 60, PRIVATE | WITH_ACK);
    delay(success ? 1000 : 0); // long only delay on success, otherwise short for debounce
  }

  if (!success) {
    Log.warning("event not published)";
    delay(50); // short delay to debounce when there was no publish
  }

https://docs.particle.io/reference/firmware/photon/#particle-publish-

I didn’t know about that WITH_ACK part. Great to know.

I left my photon on my table for an hour and I already saw 3 lines of “device came online/offline”. I am still not sure why but it just happens. Since I am planning to install this vehicle detector in a remote location, I will surely miss out that log.warn(“even not published”) to serial over USB interface message. Instead of logging, I will just keep doing the Particle.publish() until it returns true WITH_ACK. And another Particle.process() is thrown in for just in case.

    bool success = false;
    do {
        success = Particle.publish("telegram-user", "A car just passed.", 60, PRIVATE | WITH_ACK);
        
        if (success) { // The event has been published successfully
            delay(1000);
        }
        else { // The event has not been successfully published
            delay(50);
            Particle.process(); // Keep the cloud connection alive
        }
        
    } while (!success);