Putting back in box (update: took back out of box...)

Not no redemption, and it’s not a matter of past sins, but something had to happen to prove it was a one-off.

Anyway, I spoke to soon, the system code crashed, the mesh network is completely unreachable from the console, but my user program is still running (the uptime counter on the OLED is still running).

We’re in the process of preparing a release, rc.27, which includes very low level updates to both the Nordic 802.15.4 device driver as well as the version of OpenThread that powers Particle Mesh.

We believe that the Nordic Driver update will resolve the SOS-7 issues that others have reported, and hope that the updates to OpenThread will improve mesh reliability as well.

rc.26 was highly focused on helping customers who could not setup their devices to do successfully. Now that it’s out, we’re turning our efforts to overall mesh reliability and stability improvements.

Would you be willing to share the “Uptime counter” code that you’re using? Seems like a great way to monitor and compare the stability of subsequent firmware releases to ensure that the quality of the mesh networking experience continues to improve over time.


I’m certainly willing to share my code. I’m not sure how useful it really is, it just takes the value of millis(), parses it to hours, minutes, and seconds, and displays it on an I2C OLED using adafruit’s SSD1306 library. But that said, if you feel it will help people, I have no problems sharing. Do I just post it here or is there some better way? It also runs a handler for a Mesh.publish event from a xenon with an attached DS18B20 temperature sensor and displays that value on the OLED as well. Is it better if I clear out that part so it’s a simple counter on the display?

For what it’s worth, after the last lockup 3 days ago, I didn’t get around to rebooting the devices that night and left them running overnight in the non-responsive state. They recovered on their own at some point 2 to 6 hours after the lockup and the mesh has been running perfectly ever since. I’m currently at just over 120 hours of uptime on the Argon with only that one window of unresponsiveness around the 48 hour mark.


Feel free to share it here! If you’re okay with it being public, that’ll allow us to have more eyes on it so more people can try it out and see if they notice anything that may cause conflicts.

For readability, you could consider using the “preformatted text option” (looks like </> on the post editor here). It’ll preformat your text and should retain spacing.

 Like so!

Okay, let’s try it :). This is the code running on the Argon. Hardware-wise it’s just a normal 0.96" 128x64 OLED connected via I2C. It displays 3 lines, the word “Temperatur”, the temperature in celsius reported by the Xenon, and the Argon’s uptime as " h:mm:ss".

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>


char    szInfo[64];
double  celsius;
long    sampleTime;

#define OLED_RESET D4
Adafruit_SSD1306 display(OLED_RESET);

#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");

void setup()   {                
  pinMode(D7, OUTPUT);
  digitalWrite(D7, HIGH);
  Mesh.subscribe("dsTmp", processTemp);

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3D (for the 128x64)

void loop() {
  display.setCursor(0,0);                   // print title on line 1
  display.setCursor(0,20);                  // print temperature on line 2
  sprintf(szInfo, "%2.1f C", celsius);
  display.drawCircle(79, 23, 3, WHITE);
  display.drawCircle(79, 23, 4, WHITE);
  display.setTextSize(2);                   // print uptime on line 3
  sprintf(szInfo, "%2d:%02d:%02d", millis()/3600000, (millis()/60000)%60, (millis()/1000)%60);
  if (millis() - sampleTime > 20000) digitalWrite(D7, LOW);     // if we didn't receive an update for the temperature for at least 20 seconds, turn off LED.

void processTemp(const char *name, const char *data) {
    celsius = atof(data);
    digitalWrite(D7, HIGH);
    sampleTime = millis();

and this is the code running on the Xenon. The hardware is a DS1820 temperature sensor on pin D2. It reads the temperature every 2.5 seconds and Mesh.publishes it for the Argon. If the temperature is over a threshold, it does a Particle.publish to create an event that will be monitored to sound an alarm. And every 30 seconds it Particle.publishes the temperature for datalogging purposes.

#include <DS18B20.h>

const int      MAXRETRY          = 4;
const uint32_t msSAMPLE_INTERVAL = 2500;
const uint32_t msMETRIC_PUBLISH  = 30000;

DS18B20  ds18b20(D2, true); //Sets Pin D2 for Water Temp Sensor and 
                            // this is the only sensor on bus
char     szInfo[64];
double   celsius;
double   fahrenheit;
uint32_t msLastMetric;
uint32_t msLastSample;
long lastAlarmTime;
int alarmSetPoint = 29;

void setup() {
  pinMode(D7, OUTPUT);

void loop() {
  if (millis() - msLastSample >= msSAMPLE_INTERVAL){     // take a measurement every interval, just publish within Mesh network
 if (millis() - msLastSample < 100) {                   // pulse the D7 LED every time a measurement is taken, act as a heartbeat
     digitalWrite(D7, HIGH);
 if (millis() - msLastSample > 300) {
     digitalWrite(D7, LOW);

  if (millis() - msLastMetric >= msMETRIC_PUBLISH){     // take a sample every intervale, this time publish to cloud

void publishData() {
  sprintf(szInfo, "%2.1f", celsius);
  Particle.publish("dsTmp", szInfo, PRIVATE);
  msLastMetric = millis();

void getTemp(){
  float _temp;
  int   i = 0;

  do {
    _temp = ds18b20.getTemperature();
  } while (!ds18b20.crcCheck() && MAXRETRY > i++);

  if (i < MAXRETRY) {
    celsius = _temp;
    fahrenheit = ds18b20.convertToFahrenheit(_temp);
  else {
    celsius = fahrenheit = NAN;
    Serial.println("Invalid reading");
    sprintf(szInfo, "%2.1f", celsius);
    Mesh.publish("dsTmp", szInfo);
  if ((celsius > alarmSetPoint) && ((lastAlarmTime + 600000) < millis()))    // if the temperature is too high, publish a cloud event as an alarm.   
  if (celsius > alarmSetPoint)                                               // throttled to once every 10 minutes, not within first 10 minutes of powerup  
      Particle.publish("tempAlarm", "overTemp");
      lastAlarmTime = millis();
  msLastSample = millis();

It’s pretty much quick and dirty code heavily based on examples. I haven’t done much to clean it up and get it ready for prime-time. So be kind with how messy it is, but if you’ve got some feedback on how I’m actually doing things, I’d be happy to hear it


Is this doing what you expect it to do or not?
Are you merely asking for “code criticism” or do you need help to make it work?

If you look right above my 2 recent posts, Will and Matthew suggested I share the code I’m currently running on my mesh devices here in case it is of any interest to other forum users.

One thing we found out with most recent rc.27 that might impact your tests.
Due to some bugs in the nordic drivers (again :blush:) you may find your device get into a SOS+10 panic when you call Mesh.subscribe() before the mesh connection is fully up and since you are using SYSTEM_THREAD(ENABLED) and call Mesh.subscribe() in setup() you might fall into that.
The current workaround till this will be addressd in rc.28 beginning 2019 (sounds really long to go, but isn’t) you can alter your code like this

void setup()   {                
  pinMode(D7, OUTPUT);
  digitalWrite(D7, HIGH);
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3D (for the 128x64)

  Mesh.subscribe("dsTmp", processTemp);

That’s good to know, thank you. It’s the sort of thing that could easily trip me up. I haven’t had that error yet, but I will add the line you suggest for the test program.

Thinking big picture though, if I just add it as is, then my program will block forever at that point if it never connects to the Mesh? Since this is running on the Argon which is the gateway, it should not block forever there unless something else is seriously wrong, right?

1 Like

You can also use waitFor() with a timeout and then just procede without the subscription if it takes too long and try to subscribe later on once your code finds Mesh.ready().

1 Like

New user to the Particle platform. Sounds like “some” of this is related to what I’m seeing on my new Argon with certain projects. Surprised to read here that the PietteTech_DHT example worked for someone - it hangs my Argon, then makes it impossible to flash unless I put it in safe-mode (different thread). Console output stops at 0: Retrieving information from sensor:. Tried each example from GitHub repo - all end the same way. And it just stays in the cyan breathing mode even though web IDE says it flashed correctly if I try to flash with a simple blink program. Other times it times-out and says flash unsuccessful. Can start a new thread on this but spent the better part of the day working through this so I can echo the frustration. Working from a Mac, installed the particle CLI tools and can flash from CLI, get info, etc. Much is working as expected/design but there’s a significant curve here. Device OS: 0.8.0-rc.27.

Yup, due to some “regression” with rc.27 PietteTech_DHT library is now half-broken (works but is unreliable)

But if you want to continue a discussion about that library, you better post in the following thread

Thanks. That’s the last of the “sensors” in the grove Particle Mesh sensor package to get working. Everything else seems to work, though not always consistently. As others have pointed out, with a Xenon in the mesh, it seems to have a limited run time. I used @nrobinson2000 port of the BNO0555 sensor and that’s working, but will also cut out after a couple minutes and just send 0’s - and that’s with the WiFi turned off so I don’t think that’s a cloud issue. I run that exact sensor on a Pi, a CHIP and an Arduino with no problems so pretty sure it’s not the sensor. The 4 digit 7-segment display is consistent, I can run digital on the analog pins pretty consistently (though occasional hiccups there), and can control the RGB LED with inputs from the pot and ultrasound sensor. Just seems buggy, although I admit that’s not helpful. I’d like to be helpful, just not a lot of Particle experience so it’s not clear to me where to look.

1 Like

You should be able to use the Adafruit_DHT library with rc.27 now, since the timing issue that previously interfered with it has been resolved.


Here’s an update on my situation… Using the RC.27 system firmware, I continue to have the problem that my Xenon units all lose internet connectivity after being connected through my Argon gateway for an extended period (> 1 day). They still have mesh connectivity, and can communicate between themselves just fine. By ‘lose internet connectivity’ I mean that I can’t ‘signal’ them, I can’t flash them with new code from the web IDE, and the particle app can’t access any of the published variables. Resetting the Argon gateway fixes the problem. I attempted to install the debug system firmware as recommended, however despite my best efforts, I could find no way to verify that the debug system firmware was installed properly. The debug output I see from the secondary Xenon device that relays the serial data from the Argon gateway, looks identical (to a novice’s eye) from when it was the RC.26 debug firmware and the latest RC.27 firmware. The 3 Xenon units are running a variety of samples and are stable in their own right. The most complex is one that reads a microphone, does a DFT, and then drives an OLED device displaying a graph of the frequency components over time. The Argon gateway is running sample code that measures a light sensor and publishes functions for turning the light on and off - nothing fancy.

Hey Patrick,

@avtolstoy has informed me this issue has been resolved in this pull request https://github.com/particle-iot/firmware/pull/1661

1 Like

YouTube video… Short info / updates video posted on Particle YouTube Channel.

1 Like

That would be really helpful. For a newbie, this stuff has been aggravating and a bit disappointing. I was looking forward to playing with these, but ahh. I’m anxiously awaiting the next firmware update.

I have just pushed an update to the PietteTech_DHT library (now v0.0.7) to work around this issue