Cellular Network Unhealthy

Hi,
I have been running a Particle Electron 2G/3G for about 2 weeks now. The last two days it is not communicating or very randomly. When I run the diagnostics it says the Cellular Network is unhealthy >>no cellular session. Does this mean the network is down? Is there someplace I can find out the health of the network in may are? I did reset the device as a test but that doesn’t seem to be consistent fix.
Thanks.
David

What is the signal strength of the device? If you have Device OS 1.0.0 you can find that from running diagnostics. If not, flash firmware that periodically calls Cellular.RSSI() and extracts the rssi and qual values from it, per the docs

Also I assume you are using the standard Particle SIM?

4/5 bars. Running Particle SIM. When I went to check last coonection which was at 7:00 AM this morning, I found it is just connected. at 6:15 PM with 4/5 bars. Just ran diagnostics and is now same error.
David

In most cases the application code is causing such behaviour, but to be sure we’d need to see your code.

That is interesting as I did not change my code over the last 2 weeks. However, here is the code that is running. I am new to any of this so I could be overlooking something.

David

// This #include statement was automatically added by the Particle IDE.
#include <ThingSpeak.h>

// This #include statement was automatically added by the Particle IDE.
#include <Adafruit_DHT.h>

// Sensor type
#define DHTTYPE DHT22    	// DHT 22 (AM2302)

// DHT22 sensor pinout:
// Pin 1 (on the left): +3.3V
// Pin 2: output
// Pin 4 (on the right): GROUND
#define DHT_5V_PIN D1
#define DHT_SENSOR_PIN D2
#define DHT_GROUND_PIN D4

DHT dht(DHT_SENSOR_PIN, DHTTYPE);

/* Thingspeak */
TCPClient client;
unsigned long myChannelNumber =” XXXXXXX”;
const char * myWriteAPIKey = "XXXXXXX";

void setup() {
    // Connect to ThingSpeak
    ThingSpeak.begin(client);

    // Give power to the sensor
    pinMode(DHT_5V_PIN, OUTPUT);
    pinMode(DHT_GROUND_PIN, OUTPUT);
    digitalWrite(DHT_5V_PIN, HIGH);
    digitalWrite(DHT_GROUND_PIN, LOW);

    // Wait for the sensor to stabilize
    delay(1000);

    // Initialize sensor
    dht.begin();

    // Read Sensor
    double temperature = dht.getTempCelcius();
    double humidity = dht.getHumidity();
    double temperaturef = dht.getTempFarenheit();


    // Update the 2 ThingSpeak fields with the new data
    ThingSpeak.setField(1, (float)temperature);
    ThingSpeak.setField(2, (float)humidity);
    ThingSpeak.setField(3, (float)temperaturef);

    // Write the fields that you've set all at once.
    ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);
    
     // Give time for the message to reach ThingSpeak
    delay(5000);
    


    // Sleep for 15 changed to a minute save data costs, 15 gives a 20 minute interval.  Change back to 15 and see what that gives
   System.sleep(SLEEP_MODE_DEEP, 30 * 60);
}

void loop() {
    // This will run because the system is sleeping
      
}

Some issues may need some time to develop.
One suspicion I had was that your code may have accumulated heap fragments and hence can’t reconnect due to lack of big enough consecutive memory for dynamic allocation.
But since you are using deep sleep, which does reset the memory map that’s obviously not the reason.

However, there might be other things that may pile up in the cellular module to prevent proper functionality over time.
You could try Cellular.off() with some “soft delay” before going to sleep.

BTW, I’d replace your delay() calls with soft delays too.
e.g.

inline void softDelay(uint32_t t) {
  for(uint32_t ms = millis(); millis() - ms < t; Particle.process());
}

If you want to reduce data cost and don’t really need the Particle cloud connection all the time, I’d suggest you go for SYSTEM_MODE(SEMI_AUTOMATIC) and call Cellular.connect() to only connect to the cellular network but not to the Paricle cloud. That should save you about 6KB on each wake.

Like this

SYSTEM_MODE(SEMI_AUTOMATIC)
SYSTEM_THREAD(ENABLED)
...
void setup() {
  Cellular.on(); // just to be on the safe side due to open issue
  Cellular.connect();
  if (waitFor(Cellular.ready, 300000)) { // wait up to 5 minutes for the connection to establish 
    // Connect to ThingSpeak
    ThingSpeak.begin(client);
    ...
  }

  Cellular.off();
  for(uint32_t ms = millis(); millis() - ms < 500; Particle.process());
  System.sleep(SLEEP_MODE_DEEP, 30 * 60);
}

Thanks for your help. As I said, I am new to this and am basically cutting and pasting until I relearn “C” from years ago as well as figure out the grand picture of what is happening! I appreciate the code hints.
So it would seem the error Cellular Network>>> Unhealth>>>No Cellular Session relates to the fact that there is no active connection to the Particle vs network health.
Thanks.
David

As for the system diagnostics cellular connection and cloud connection are treated as one thing as the Particle cloud only knows about the state of your connection when connected to the cloud. Once connected to the cloud it may read the signal strength tho’.

Since you are running SYSTEM_MODE(AUTOMATIC) (by default) your code won’t start running unless the device actually made it to the Paricle cloud. Consequently you need both connections to succeed to get the diagnosticas and/or your data report.
With SEMI_AUTOMATIC your code will run immediately and give you the choice when and how you want to connect.

(in response to the now deleted post)
I added the closing curly brace in the post above.
With that there and the function defined on the same level as void setup() you should be fine.
Or you just use the for() loop directly as I did in my second code snippet.

I am still confused.
I put in the line right after one of the delays I commented out the delay()
eg //delay(5000)
the code
inline void softDelay(uint32_t t) {
for(uint32_t ms = millis(); millis() - ms < t; Particle.process());
}
and get
a function-definition is not allowed here before ‘{’

I’m not sure if you know this, but if you tap the MODE button with the Electron connected to cellular, the RGB LED will flash in green to tell you “how many bars” it sees.

Have you read that?

Function definitions are not allowed inside another function.
But as said you can

To remove all possible doubt

inline void softDelay(uint32_t t) {
  for(uint32_t ms = millis(); millis() - ms < t; Particle.process());
}

void setup() {
  ...
  softDelay(1000);
  ...
  // or directly
  for(uint32_t ms = millis(); millis() - ms < 1000; Particle.process());
  ...
}

I did read it but didn’t understand it but now that you added the longer error information and additional code of softdelay((1000) or alternatively adding the timing statement directly
I think I see what is going on. I had googled the error but apparently didn’t understand what was being said. I learned a whole lot as now I understand the programming construct.
Thank you again for explaining it to me. I’ll give it a try as soon as I get up.
……one coffee later it ran!! Now we will see if it reports back home after a few weeks!
Thank you again.

1 Like

Update - I disconnected everything for 5 days and than restarted and it seems to be connecting. I added the code as suggested but it seems to read every 3 -4 minutes regardless what I put in the sleep command. I am wondering if I coded this correctly or I need to change the cellular_off() if statement.

I have:

void setup() {
    
//line 34 5o 36  added in order to make sure cellular module working see https://community.particle.io/t/cellular-network-unhealthy/47802/6
  Cellular.on(); // just to be on the safe side due to open issue
  Cellular.connect();
  if (waitFor(Cellular.ready, 300000)) { // wait up to 5 minutes for the connection to establish

    // Connect to ThingSpeak 

    ThingSpeak.begin(client);
…

And at the end ….

Cellular.off();
  for(uint32_t ms = millis(); millis() - ms < 500; Particle.process());
   System.sleep(SLEEP_MODE_DEEP, 60 * 60);

One other question – it was reading humidity initially but is now not reading it and gives 0.

It is a DHT22. I read about timing issues but I don’t think that is the cause.

Thanks.

David

You are sure the WKP pin is not going high and wake the device?
Your power supply is not causing any surges that may wake the device?
You are really running the updated code? (add some features to check that the update actually took - e.g. Serial.print() a version number)

Repost your entire code

I flashed the code again - which I had done multiple times last night so a bit confused as it now seems to working. Stupidly I unplugged the power supply to see if that was the issue - which made two changes at once. I should have not done both at once but I did plug power supply back in and it seems to be still working. So perhaps for some reason though it has said the code was flashed successfully it was not.
Here is the code.
To see if it flashed correctly I added a duplicate temperature to send to ThingSpeak to see if it flashed correctly and ThingSpeak is getting the new variable.

I will let this run and increase the interval later in the day to see if it works.

If the Electron is in System.Sleep mode I assume you can not flash code. I have been sending code either near the time it is connecting (flashing green) or put in Safe Mode and re- flash. Is this a correct assumption? When I get this works it will be sitting in a building across town. How do you flash it if not in physical proximity?]
Thanks.

Here is the code…


// This #include statement was automatically added by the Particle IDE.
#include <ThingSpeak.h>

// This #include statement was automatically added by the Particle IDE.
#include <Adafruit_DHT.h>

// Sensor type
#define DHTTYPE DHT22    	// DHT 22 (AM2302)

// DHT22 sensor pinout:
// Pin 1 (on the left): +3.3V
// Pin 2: output
// Pin 4 (on the right): GROUND
#define DHT_5V_PIN D1
#define DHT_SENSOR_PIN D2
#define DHT_GROUND_PIN D4

DHT dht(DHT_SENSOR_PIN, DHTTYPE);

/* Thingspeak */
TCPClient client;
unsigned long myChannelNumber = *****;
const char * myWriteAPIKey = "******";

//set timer soft delay

inline void softDelay(uint32_t t) {
  for(uint32_t ms = millis(); millis() - ms < t; Particle.process());

}
void setup() {
    
//line 34 5o 36  added in order to make sure cellular module working see https://community.particle.io/t/cellular-network-unhealthy/47802/6
  Cellular.on(); // just to be on the safe side due to open issue
  Cellular.connect();
  if (waitFor(Cellular.ready, 300000)) { // wait up to 5 minutes for the connection to establish

    // Connect to ThingSpeak
    ThingSpeak.begin(client);

    // Give power to the sensor
    pinMode(DHT_5V_PIN, OUTPUT);
    pinMode(DHT_GROUND_PIN, OUTPUT);
    digitalWrite(DHT_5V_PIN, HIGH);
    digitalWrite(DHT_GROUND_PIN, LOW);

    // Wait for the sensor to stabilize
    softDelay(5000);



    // Initialize sensor
    dht.begin();

    // Read Sensor
    double temperature = dht.getTempCelcius();
    double humidity = dht.getHumidity();
    //Temperature here to see if code was upated being sent to ThinkSpeak
    double temperature2 = dht.getTempCelcius();



    // Update the 2 ThingSpeak fields with the new data
    ThingSpeak.setField(1, (float)temperature);
    ThingSpeak.setField(2, (float)humidity);
    ThingSpeak.setField(3, (float)temperature2);

    // Write the fields that you've set all at once.
    ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);
    
     // Give time for the message to reach ThingSpeak
     softDelay(5000);
  }
    
    
  

    // Sleep for 15 changed to a minute save data costs, 15 gives a 20 minute interval.
    //Change back to 15 and see what that gives 02212019 change to 10 to test sleep not messing up connections
    //Line 81 to 82 added for cellular potential see link lin 33
    Cellular.off();
    for(uint32_t ms = millis(); millis() - ms < 500; Particle.process());
    System.sleep(SLEEP_MODE_DEEP, 10 * 60);
}

void loop() {
    // This will run because the system is sleeping
      
}

If you have access to the device putting it in Safe Mode is the easiest way to go.
If haven’t got it nearby you need to take some provisions in your code to actually Particle.connect() and then stay active for a few minutes to flash.

The tricky bit is how to tell the device that it should enter that mode.

An alternative solution is to make the device part of a product and then enter the flash state e.g. once a day and let the cloud automatically push the new firmware to the device.

Thanks for the information. I suppose you could set up some timer in the code so you knew it would be on at a certain time. I will look into the product idea. The other dirty method is have two or three and assume they all don’t fail at once. It is for large old church whose furnace fails and in winter not a good idea! My next project will be to actually monitor furnace being off. This was suppose to be a quick and dirty project! Dirty it is but not quick! However, the more I think about it you could set up a Mesh and monitor energy consumption and idealize it to be minimal. I did not want to use an off the shelf wireless heat alarm that would connect to their WiFi so we would not have to worry about network security.
I appreciate your help.

1 Like