Can Ping Electron but device not actually online?

So I have deployed 2 Electrons both running the same code…

They are capable of of turning something off and on via HTML and or SMS. (3rd party sim)

I am having issues with one of the Electrons. It’s dropping from the server but SMS still works??. When I try to turn it off via HTML which is basically the same as the particle example I get this response.

{“ok”:false,“error”:“Exception during function call”}

When I go to the Particle Console and select the Electron and use the Ping feature it says the device is on line. When I try to flash it remotely via OTA it also says flash successful. I know it is incorrect and did not actually flash as I have set the Electron to send me a SMS on boot up which it would if it flashed and rebooted. (I am flashing the right one)

Also when I access the Particle mobile app I can see it is actually not online.

The Electron that is no longer working via HTML is in a location with weaker RSSI. then the one that is working.

so,

  1. Could poor signal Strength be causing it to disconnect from the cloud and not reconnecting? (I’m running Semi-Automatic mode).

  2. When The device is powered down and rebooted it connects for a while maybe 12 to 24 hrs then drops again. (I am running keep alive at 120 on both electrons. remember on working perfectly)

  3. It is currently in a location that I have no access to. I can preform a “System.reset();” via SMS but from memory that does not reset the modem.
    There is a possibility that I can turn the
    Cellular.off(); for ten seconds then,
    Cellular.on(); followed by,
    STARTUP(cellular_sms_received_handler_set(smsRecvCheck, NULL, NULL)); STARTUP(cellular_credentials_set(“telstra.internet”, “”, “”, NULL));. (third party sim APN)
    all via SMS but;

If I do this is it likely to connect to the cloud or try to??

I am hesitant to try this as I do not want to loose my ability to control it via SMS since I have already lost HTML.

Any help or thoughts would be appreciated. Cheers

Have you had a look at Particle.keepAlive()?

Yes have Particle.keepAlive(120); on both devices.

Hi,

I have found on my Electrons that I needed to drop my keepAlive down to 15 when using a 3rd party sim cards in my region.

Particle.keepAlive(15);

Might be worth trying.

I have used the following to successfully reset the modem and micro.

Cellular.command("AT+CFUN=16");
System.reset();

Hope this helps.

2 Likes

@ShawnC I did extensive testing on the keep alive function and settled on 120. 150 was fine but wanted some room for error. The only issue with lower keep alive is the current draw. the more you can stretch it out the less duty cycle.

When I can Ill update a SMS function to reset the modem with your suggestion. Thanks
Just wish I could put my finger on what the problem could be.

Building on this, under what circumstances does the console Ping return for an Electron?

I am seeing a (remote) device return a ping, but cannot observe its variables or states. The only thing I know for sure is that the “Last Handshake” shows over two hours ago and particle list from the command line shows the device as online.

The most common reason for this is when the device came online, it had trouble communicating by cellular and the message containing the function and variables was lost. The device will be missing its functions and variables until it's reset, which is a bug. Sometimes you can fix it by doing an OTA flash of the device, which will cause it to reboot.

The last handshake for an Electron is not a reliable indicator. When an Electron reconnects to the cloud it can often reuse its session, and if it does, the last handshake is not updated.

2 Likes

Thanks @rickkas7,

follow-on question:

I want to publish() from Electron but don’t want any possibility of blocking.

So how would I do a quick check to see if cellular connectivity is available? Is it as easy as:

if (Particle.connected() and !Cellular.connecting()) {
  Particle.publish("event", "data", PRIVATE);
}

Does Cellular.connecting() return true as soon as the cellular connection is lost and false the moment it is connected? I want near zero blocking for this check.

Particle.publish should not block if:

  • You are using SYSTEM_THREAD(ENABLED)
  • You do NOT use WITH_ACK
  • Particle.connected is true

All three conditions must be true to avoid blocking.

The check for Cellular.connecting() won’t hurt, but I don’t think it will have any effect. I could be wrong about that.

The second condition is because WITH_ACK, it blocks waiting for the ack, which takes a while if not connected.

The third condition is because if not connected, it will try to connect first, and blocks doing it (I think).

I am using
SYSTEM_THREAD(ENABLED)

I am not using WITH_ACK

I do not want to even attempt to publish if there isn't any chance that it will actually be sent.

let me be clear...

Particle.connected() on Electron is only updated at the setListenTimeout() interval. As you described it, you can check for Particle.connected() and it can return true even if cellular is lost, yes or no?

So if Particle.connected() returns true, that is therefore insufficient as to determine if a Particle.publish() will actually be sent. Adding the test for Cellular.connecting() in my mind is a belt and suspenders check, no?

If Cellular.connecting is true, I’m pretty sure Particle.connected will already be false.

The problem is that between the keepalive ping intervals, the Electron won’t know that it lost connectivity until it goes to send data - during the publish. In other words, the only way you can know for sure you’ve lost connectivity between pings is to send something.

The check for Particle.connected catches the obvious case where you know you’re not already connected.

so then am I to understand that the best way to check before publishing is just:

if (!Cellular.connecting()) {
  Particle.publish("event", "data", PRIVATE);
}

Sorry if I'm coming off as a bit thick, I'm just looking for best practices on this. I'm thinking:

!Cellular.connecting() === device is breathing cyan

I was thinking:

if (Particle.connected()) {
  Particle.publish("event", "data", PRIVATE);
}

Cellular.connecting returns true if it’s in the process of connecting - blinking green. It’s false if it’s not connected (off, breathing white) or connected (on, breathing green or breathing cyan).

OK Rick, so maybe spoon feed me here…

Then you believe that Particle.connected() is all I need to determine if the device is online and cellular connected?

This device’s connection is erratic, so we wish to avoid sending data if we can determine its connection state. I may wish to buffer the messages until the connection is re-established.

Cellular connected? Particle.connected() is one step further: Cloud connected.
For cell connection you have other possibilites: Cellular.ready() and Cellular.resolve() just to name two.

Correct. If

  • You are using SYSTEM_THREAD(ENABLED)
  • You do NOT use WITH_ACK
  • Particle.connected is true

then it’s safe to Particle.publish. It won’t block. Sometimes it will try to send and fail, which will cause the Electron to go from breathing cyan to some other blinking mode, probably blinking green or blinking cyan, but there’s no way to avoid that.

If the Electron is already not connected (breathing green or white, or blinking), then Particle.connected will return false and the publish will be skipped, since it definitely won’t work.

It's all well and good to throw out a bunch of options, but this is really a simple question.

So, it is possible that even though I test for cloud connection immediately proceeding , a publish may fail. And if I use WITH_ACK, then I'm screwed because that blocks loop() for a long time.

Let me mull that, because then there is no sense in me queueing the publishes if I can't be assure that my sent publish made it (without using the loop-blocking version, which stalls the program entirely).

That is correct, and a hard problem to solve. The reason is that there's no way to know that the publish won't work until you do it. What I'd like to see is a non-blocking version of WITH_ACK that takes an asynchronous completion function.

2 Likes

Or do something like this technique for SSE with guaranteed delivery. It’s end-to-end guaranteed, doing a retry if the publish fails (cellular or Wi-Fi problem), a cloud problem, or a problem your server (SSE client).

1 Like

@rickkas7

I wonder if it would be possible for Particle to create a "backdoor" method, called from the Particle Console that would allow for a Reset; much like the Ping button...

something to consider while this bug gets squashed...