Device Breathing Cyan But Cannot Connect

A device that is breathing cyan but cannot connect (e.g. you cannot ping the device in the Console) has three likely causes, both of which should be easily actionable to the user. The following outlines a few strategies to debug.

The console online indicator

It's worth explicitly stating that the Console's Online Indicator is not a real-time status indicator. For cellular devices, it has a lag of up to as much as 46 minutes (two successive missed Keep-Alives). This article is not meant to address Devices that are "online" in the Console but not breathing Cyan in the field.

Keeping system firmware up to date

Prior to Device OS 1.3.1, firmware connectivity-blocking issues can be disguised as a "Breathing Cyan But Cannot Connect" state. This is because Particle.connected() returned true immediately after successfully resuming a session, but not prior to a completed handshake. While Device OS 1.3.1 fixes this issue (link), we recommend upgrading system firmware to at least the most recent production version following the instructions here (link). Note: updating your Device OS may not result in a successful connection, but it may kick the device out of the Breathing Cyan state - allowing the Status LED to show more useful information about its connectivity status.

Checking for sporadic RF issues

An environment that has just enough cellular connectivity to allow for successful connections but not enough to prevent constant timeouts and long roundtrip times could put a device into this condition.

The Particle Console provides you with current and historical Device Vitals that are helpful in debugging cellular connections. To see Device Vitals, head to the console, and click on the device you are interested in. These values will not appear if the device has never connected in the past - if this is the case, please skip ahead to "Sim Management" below.

On the right-hand side you will see “Last Vitals”, and you can press the reset button to request the latest numbers from the device. (You can also do so by selecting "Run health check" on the bottom of the panel). For devices that are Breathing Cyan but can't connect, we recommend downloading the CSV file with your vitals history to dig into more details. In order to do so, click "Download History" on the underside of the Vitals panel.

This is a very information-dense document, but the key things to look out for are:

    This value corresponds to signal “Strength”, with desirable values higher than -85dBm, with a steady decrease in stability as you approach -120dBm. We recommend you use our "%" metrics to scale these values accordingly as there are differences between RSCP and RSRP measurements for 2G/3G and LTE devices respectively.
    This value corresponds to signal “Quality”, lower values (< -14dBm) may indicate the device has trouble talking to the tower (eg. potentially due to interference).
  3. Number of recent disconnects from the Particle Cloud.
    Frequent disconnects can point to issues with signal quality (Low Signal Quality values will correlate) and/or local interference.

Watch for low % values in either of the above categories (e.g. < 20%), and watch for high rates of disconnects. Any of these three metrics point to an environmental/RF issue as the root cause of this device Breathing Cyan.

Identifying blocking firmware

In some edge cases, application firmware can interfere with a device's ability to respond to things like Pings or Function Calls (e.g. devices that reset themselves constantly, that perform blocking actions without Threading enabled, etc...). While root cause in firmware might take some time, it is easy to identify whether or not application firmware is a contributing factor to devices the Breathe Cyan but cannot connect.

In order to establish whether or not your application firmware is blocking, flash blank firmware down to the device that runs with SYSTEM_MODE_AUTOMATIC and has an empty loop(). However - please take care to ensure that a blank sketch is safe for your device's hardware configuration, making all the necessary initializations in setup() while keeping your application functionally minimal:

void setup() {  
// any necessary hardware initializations  

void loop() {  
// empty, if at all possible  

// refrain from declaring any interrupts and try and keep your test firmware as empty as possible

It is worth stating that the majority of these issues do boil down to blocking firmware, so performing the above test is an essential component of the troubleshooting process.