My Xenon does not seem to be able to publish if the radio module needs to be manually turned on/off. I realize there is an issue with Particle.connect()mentioned here, but I’m unable publish data even when using Mesh.on() followed by Mesh.connect().
Here is a short program for the Xenon that demonstrates my issue. It generates a random number every 3 seconds, stores them in an array, and after 2 minutes averages the numbers and publishes. My Xenon (and its Argon gateway) are on Device OS version 1.2.1-rc.2.
SYSTEM_MODE(AUTOMATIC);
float average;
int counter = 0;
float myArray[40];
unsigned long lastMillis = 0;
void setup() {
Serial.begin(9600);
Mesh.off(); // Start with Mesh radio off
}
void loop() {
unsigned long now = millis();
if (now - lastMillis >= 3000) {
// generate a random number every three seconds & add it to myArray
lastMillis = now;
float anyNumber = random(1, 20) * 3.142;
Serial.print(counter);
Serial.print(" : ");
Serial.println(anyNumber);
myArray[counter] = anyNumber;
counter++;
if (counter >= 39) { // 2 minutes expired: calculate avg & publish
float sum = 0.0;
for (int i = 0; i < counter; i++) {
sum += myArray[i];
}
average = sum / counter;
Serial.print("Average = ");
Serial.println(average);
char data[150];
snprintf(data, sizeof(data), "{\"avergae\": %.2f}", average);
Serial.println("Turning ON radio...");
Mesh.on();
Mesh.connect(); // Doesn't seem to have any effect
waitUntil(Mesh.ready); // Doesn't seem to have any effect
Particle.connect();
waitUntil(Particle.connected); // Doesn't seem to have any effect
Particle.publish("xenon-test", data, PRIVATE);
Serial.println("Turning OFF radio...");
Mesh.off(); // Turn off radio
counter = 0;
average = 0;
}
}
}
The Xenon’s RGB blinks cyan very briefly when connecting, but immediately goes white from Mesh.off() without actually publishing. Am I doing something wrong?
What’s even stranger is that if I use SYSTEM_MODE(SEMI_AUTOMATIC), the device will sometimes publish on the first publish call but always freezes immediately after the first Mesh.off() is called inside loop(). Why is this?
The Doesn't seem to have any effect comment doesn’t make a lot of sense for the waitUntil() statements.
Do they wait forever or not at all?
You may want to use waitFor() instead to be able to act upon the “forever” case.
Also AUTOMATIC mode is not the best choice for your use case.
Since your code seems to be running in non-connected mode mostly non-AUTOMATIC would be the obvious choice. SYSTEM_THREAD(ENABLED) is another option.
The waitUntil() was just part of me trying everything I could to get the Xenon to connect and publish. My comment //Doesn't seem to have any effect meant that using this call (even though it’s in AUTO and shouldn’t require it—that is, if I understand AUTO correctly) is still not getting the device to publish.
It’s not stuck in the waitUntil() call, that’s not the issue. The serial output and the brief RGB flashing indicate the device seems to think it connected, however it’s not actually publishing the data. I’ve tried manual, semi_auto, and auto modes, but none are actually able to turn the radio on and publish.
Is it possible that my Xenon is defective? Shouldn’t this code be able to run reliably? My mesh devices are from the pre-order batch and I haven’t tried integrating them into my normal field deploys until now.
I have several anemometers and barometers that are running on Photons without any problems. Using an Argon+Boron gateway would be ideal for locations where hurricanes are likely to knock out WiFi connectivity. If I can figure out why the mesh radio isn’t connecting that would be great.
Even with your original code the RGB LED pattern did what was expected, but since you immediately after calling Particle.publish() switched off the radio the event could never be published. Particle.publish() only enqueues the message but does return as soon that was done successfully, but the device OS needs some time to process that queue which you didn’t allow for.
However, I did find a device OS issue with SYSTEM_MODE(SEMI_AUTOMATIC)
This makes sense however I didn't see it documented, which is confusing when migrating from a Photon wherein I can publish and then call WiFi.off() without a problem.
Your code with the delay(100) was working but only ~50% of the time; bumping up the delay to delay(1000) works consistently.
@tve You're right Mesh.connect() on its own works in place of Mesh.on().
In the original code Mesh.on() was immediately followed by a Mesh.connect() so no-op or not, the actual problem was the missing delay between publish and Mesh.off().
In another thread I got this reply which may help mitigate the issue