Electron 2G stuck cyan / green

Hey everybody,

I’ve an electron 2g which controls 2 SHT31 temperature/humidity sensors via I2C Wire1 communication pins (C4 and C5).
Everything works well for couple of time but after a random time, electron’s RGB led freezes on CYAN or GREEN, which makes impossible the communication with Particle Cloud. The only way to defreeze the electron is to reset it that i don’t want.
I don’t understand this behavior. Do you have any idea how to figure out this problem?

Thank you very much for your help !

My device firmware is updated at the 5.3.0 version and the code i use is:


#include "SHT31_Wire1.h"


// Disable GSM on boot
SYSTEM_MODE(AUTOMATIC);


/* Informations about time */
#define DEEP_SLEEP_TIME_INTERVAL_S (59*60)
#define POST_WIRE_BEGIN_DELAY_MS 100
#define POST_WIRE_END_DELAY_MS 100
#define POST_PUBLISH_DELAY_MS 5000
#define POST_PROCESS_DELAY_MS 100
#define TIME_EPOCH_START 1970


/* Enabling Backup RAM (SRAM) */
STARTUP(System.enableFeature(FEATURE_RETAINED_MEMORY));
retained uint8_t last_day_sync_d = 0;


/* Define a fuel gauge instance */
FuelGauge fuel;

/* Define two Adafruit_SHT31 instances */
SHT31_Wire1 sht31 = SHT31_Wire1();



/**************************************************************************/
/*
        Functions declarations
 */
/**************************************************************************/
bool syncTime(uint16_t timeout_ms = 1000)
{
  if (Particle.connected())
  {
    Particle.syncTime();


    // syncTime is non-blocking, so wait for a valid time to come back
    // from the server before proceeding
    uint32_t now = millis();
    uint32_t timeout = now + timeout_ms;


    while (Time.year() <= TIME_EPOCH_START && now < timeout)
    {
      Particle.process();
      delay(POST_PROCESS_DELAY_MS);
      now = millis();
    }
    return now < timeout;
  }
  return false;
}

String beginReadSHT31SensorsData()
{
  String sensors_data = "";
  uint8_t counter = 0;
  bool sucess;
  float humidity, temperature;


  sensors_data = String::format("%.2f ", fuel.getSoC());


  sht31.begin(0x45);


  counter = 0;


  do
  {
    sucess = sht31.returnTH(&temperature, &humidity);
  } while (!sucess && (counter++ < 5));


  sensors_data.concat(String::format("%.2f ", temperature));
  sensors_data.concat(String::format("%.2f ", humidity));


  Wire1.end();
  delay(POST_WIRE_END_DELAY_MS);


  sht31.begin(0x44);


  counter = 0;


  do
  {
    sucess = sht31.returnTH(&temperature, &humidity);
  } while (!sucess && (counter++ < 5));


  sensors_data.concat(String::format("%.2f ", temperature));
  sensors_data.concat(String::format("%.2f ", humidity));


  Wire1.end();
  delay(POST_WIRE_END_DELAY_MS);


  return sensors_data;
}



/**************************************************************************/
/*
        Function:  setup
 */
/**************************************************************************/
void setup()
{
  pinMode(C4, INPUT);
  pinMode(C5, INPUT);

  // Initialize the time zone to the US eastern one
  Time.zone(-4);
}



/**************************************************************************/
/*
        Function:  loop
 */
/**************************************************************************/
void loop()
{
  // String variables which contains temperature and humidity data from SHT31 sensors
  String sensors_data = "";

  // Synchronise hardware time with Particle Cloud one
  if (Time.day() != last_day_sync_d)
  {
    syncTime();
    last_day_sync_d = Time.day();
  }

  // Begin and read data from sensors
  sensors_data = beginReadSHT31SensorsData();

  // Publish sensors data to Particle cloud
  if (Particle.connected())
  {
    if (Particle.publish("d", sensors_data, PRIVATE))
    {
      delay(POST_PUBLISH_DELAY_MS);
      // Activate deep sleep mode of the device for DEEP_SLEEP_TIME_INTERVAL_S seconds
      System.sleep(SLEEP_MODE_DEEP, DEEP_SLEEP_TIME_INTERVAL_S);
    }
  }

  if (Particle.connected())
  {
    Particle.process();
    delay(POST_PROCESS_DELAY_MS);
  }
}

Just a few things to start with:

The comment and instruction don't really fit together

You'd only need

SHT31_Wire1 sht31;  // this already calls the default constructor

You should not mix the datatypes here, but use uint32_t all the way through and also rearrange the calculation/value check.
The background can be found here
Millis() and rollover tutorial

Try to reduce your use of String where possible to avoid risk of heap fragmentation. As long you don't need the Steing class methods, C strings are safer.

If your LED gets stuck on a solid color, it's most likely the I2C connection hangs for some reason.
What value pull-up resistors are you using and to what voltage?

1 Like

Thank you for your advises, i’m going to apply them right now.
When you say start with:

>     // Disable GSM on boot
>     SYSTEM_MODE(AUTOMATIC);

You mean before the #include “SHT31_Wire1.h” ?

I’m using the adafruit SHT31 breakout (https://www.adafruit.com/product/2857) including 10kOhms pullups resistor on SCL and SDA pins where logic signals are in 3V3, which is connected to electron device by a cable of 35 cm of length. Do you think the fact that my pullups resistor are 35 cm away from Electron could deform the signal and thus makes the electron frozen?

I’m testing your modifications and verifying my wiring right now.
Thank you !

Xavier

No, I meant to start with the least important point that the instruction does not disable GSM on boot up - as the comment states - but exactly the opposite :wink:

And try it with considerably shorter wires - 10k @ 3.3V and long wires will not give you the best signal shapes.
Try adding another set of 10k resistors near the Electron.

A coincidentally rather similar question just got answered similarly :wink:

Haha, that exactly what i was thinking.
I tell you if that figure out the problem.

Thanks a lot for your help, i really appreciate the Particle community reactivity.

1 Like