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

Woohoo! I got it to flash! Thanks! How do you eat an elephant? One bite at a time!

1 Like

Thank you so much for having patience. Not only did I get the program to flash, but I was able to add the particle variables and particle publish to the code and get it to work as well. Huge confidence booster. Thanks for putting up with me.

3 Likes

Will give it a try today, a good excuse to hook up the debugger and learn how to make it work :slight_smile: At least I assume it will capture the serial output for me… Was in my usual broken state this morning, and can verify that I can signal the argon when in the broken state (but not the xenons). Power cycled the argon, and can now signal and interact with at least one of the xenons. The second xenon was slow to start and complete the green light ‘reconnect to network’ process, and then was still not accessible - although happily running my code and responding to mesh network events. Power cycled the second xenon (had been running 2 days) and its now accessible. Will give the debug firmware a try.

Ok, I’ve got a slave device relaying the serial1 output through the usb output. We’ll see what we get!

Since last time I posted, my uptime is now 44 hours and there’s been no problems. I haven’t touched the devices and just periodically checked to make sure events are still being published from the Xenon, which they are without fail. I’m running the exact same code as before except that I added SYSTEM_THREAD(ENABLED);.

I’m going to start power cycling the xenon to make sure it reconnects properly, but I doubt that has anything to do with the crashing before.

So it seems, to work now but it’s already proven itself unreliable. How do you get to a point where it can be trusted for anything important?

1 Like

Hmm, not sure how to take that :confused:
Since there were problems in the past (which - as it seems - were addressed and many of them fixed) there will not be any redemption for “past sins” - no matter what, even despite …

I’m confused :confused:

By more testing, finding more (previously not found) bugs, fixing the ones not yet fixed and further improving on basis of what we already have.

Just like said here

1 Like

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.

5 Likes

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.

3 Likes

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>

SYSTEM_THREAD(ENABLED);

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!");
#endif

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)
  display.clearDisplay();
}


void loop() {
  display.clearDisplay();
  display.setCursor(0,0);                   // print title on line 1
  display.setTextSize(2);       
  display.setTextColor(WHITE);
  display.println("Temperatur");
  display.setCursor(0,20);                  // print temperature on line 2
  display.setTextSize(3);
  sprintf(szInfo, "%2.1f C", celsius);
  display.println(szInfo);
  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);
  display.println(szInfo);
  display.display();
  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() {
  Serial.begin(115200);
  
  pinMode(D7, OUTPUT);
}

void loop() {
  if (millis() - msLastSample >= msSAMPLE_INTERVAL){     // take a measurement every interval, just publish within Mesh network
    getTemp();                                          
  }
 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
    publishData();
  }
}

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);
    Serial.println(fahrenheit);
  }
  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

2 Likes

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)
  display.clearDisplay();

  waitUntil(Mesh.ready);
  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.