Battery power Xenon

I just tried it, since it’s within the Spec’s and I have a box full of Xenons that I don’t use.
5.452 V into the Li-Po Connector worked fine.
I used a power supply and tested at room temperature, confirmed with MM.

IMHO, 3xAA L91’s into the Li-Po connector @ -20C should work fine; no additional regulators, etc.
Just take preventative measures to ensure the Xenon cant attempt to “recharge” the L91’s if someone connects it to USB / power source.

What’s the Xenon’s Sleep Current, with the latest firmware?
I haven’t noticed that on the forum yet.
But if you measure your sleeping current @ -20 degrees C, then that will tell you pretty quick which direction to take for your battery pack for a 1 year life (assuming a low duty cycle).

If you plan on the Xenon waking up on a specific schedule, then Shutdown w/ the EN Pin ( as @ScruffR mentioned) & an external timer will be the best Low-Power solution. I’ve performed a lot of tests (and several posts) with the TPL5111 for a Boron LTE on 0.9.0 that could get you started. The TPL5111 is cheap and easy to implement if your sleep time is <= 2 hours.

I “think” a Xenon will use ~ 1Wh over a year of Shutdown w/ EN pin, but that should be confirmed.
I haven’t tested the Xenon much myself.

1 Like

Thanks for going to the trouble of doing that test. Room temp is perfect for the test anyway since I’ll be powering and setting up the device at room temp before installing it in the deep freeze and that’s probably the worst case anyway. 3xAA Lithiums should give me plenty of power for the year, without the regulator overhead.

I don’t know about sleep current for the latest firmware, the guide I’ve been using is a February forum thread here Early 0.9.0 Xenon current consumption measurements that puts it under 50uA and leads me to believe 10 seconds on every 10 minutes will give me my year with power to spare. Sampling every 10 minutes is ideal and dropping to 15 or 20 if needed is still acceptable.

I am planning to wake on a schedule. I just read the TPL5111 datasheet. It’s an impressive chip that would work perfectly here if I need the extra power savings. And the Xenon in sleep mode takes about 1500 times as much power as the TPL5111. That’s also the first time I’ve ever seen the quadratic formula used in a datasheet which was interesting. Eventually I want it to log any exposure to light if the enclosure is opened, I was thinking a phototransistor on an interrupt would do that, but for now I’m focused on basic data-logging. It would probably work with the TPL5111 ON pin anyway.

1 Like

Quick Calc’s:
every 10 minutes = 144 Wake events per day.
144 Events * 10 second duration = 24 minutes of runtime per day.
Assume 15 mA (guessing) = 6 mAH per day during runtime

Assume 0.050 mA Sleep current * 24 hours = 1.2 mAH per day during sleep.

6 mAH “run” + 1.2 mAH “sleep” = 7.2 mAH per day = 2,628 mAH per Year.

L91 is rated at 3,500 mAH, so you have some margin on your side.

Looking at the datasheets, the L91’s shouldn’t have trouble meeting the current spikes until discharged to ~ 1.35V each, or below.
So “In Theory”: 2xAA might meet your 1-year goals also before you see Brown-out on the Xenon.
That’s straight out of the box, using the Li-Po connector and System Firmware for Stop Sleep mode, no external timer for En Pin, no extra regulator.

I’d try 3xAA myself, but if you didn’t like the 3xAA for any reason, a 2S2P pack (as you previously mentioned) gives you a significant safety factor.

How are you planning on protecting the Xenon from the frost in the freezer ?

Correct me if I’m wrong, but I think the calculation is actually even more in my favor with 3 cells and less with 2. Your 2,628mAh per year calculation is at 3.3V. The L91’s should give me those 3,500mAh at 1.5V per cell, so at 3.3V, 2 cells will give me 3,180mAh and 3 cells will give me 4,770mAh at 3.3V. But I should factor in an 85% efficiency (to be on the safe side) for the Xenon’s regulator, so I will have 2,700mAh with 2 cells and 4,040mAh with 3 cells. If all of that is right, 2 cells are borderline but will be close enough to be good enough. 3 cells will give me a significant safety margin, so 3 is the way to go, especially since I don’t have to worry about that releasing the magic smoke.

I’m planning to put the Xenon in a plastic project enclosure and then put electrical tape around the seam. But one important test I haven’t done is if I can actually connect to the Mesh from within the freezer, I hope the metal shell of the freezer doesn’t block the signal. I can put another mesh node fairly close to the freezer if needed.

Absolutely. I only mentioned the 2xAA again since 3xAA is very near the Specified limit on the datasheet.

Well, that’s not exactly how it works, to my knowledge anyway.

Once you’re ready to actually calculate a power budget, I’d use watt hours instead.
Especially since we normally can’t operate over the same voltage range that’s used by battery manufacturers to determine their capacity rating.
Also, I don’t think you need to worry about the 85% efficiency you mentioned for the Xenon. The current measurements for the system (external) are still valid.

Take real measurements at your operating conditions, both current and voltage.
Perform the test at both ends of the L91’s operating range that can provide the current required by the Xenon and peripherals.
Take a large enough sample set to comfortably decide on the required Run-time for each wake event (successful Mesh Connect and Publish) from the freezer. This is the most important test, if you decide not to perform the current & voltage test. Example: if the assumed 10 seconds actually averages 30 seconds from the freezer, the rough calc’s would be WAY OFF. :sunglasses:

Since the battery voltage isn’t constant over its life, you’re right, I should be looking at Watt-hours. I think my way would have worked (at least for DC) if I could have assumed constant voltages. And good point about the regulator efficiency already being factored in.

My software still isn’t far enough along to take meaningful readings, especially during sleep mode, but I will do it.
Actually, the run-time during the wake event is my biggest issue right now. I’m using a DS18S20 to read the temperature, and for the first minute or so after power-on I get garbled data that fails the CRC check. After that it works flawlessly, but a minute for each on-event is not workable. Plus, of course, that is at room temperature. If I can’t work it out I’ll have to choose a different sensor.
I was planning to note millis() at wake-up and take the difference just before shut down and publish that as part of my status update. Over time that will collect some good sample data.

Also add some desiccant sachets to the enclosure just to absorb any residual moisture as it is sealed…

I’ve made enough progress on my code to do some testing.
I’m measuring wake time by noting millis() right before it goes to sleep each time, and then comparing the time between wake/sleep cycles and subtracting the sleep time I’m taking the rest as wake time. If that method is accurate, I seem to be averaging 3 seconds of uptime each call which seems amazingly good. Sometimes it’s as bad as 5 seconds, the best 0.8 seconds. Is my method reasonable?

I can’t think of a way to measure current under actual conditions since I can’t leave my meter inside the freezer and read it.

One big problem I have though is when the mesh gateway is not available. The when the Xenon wakes up and doesn’t find the mesh netowrk, it stays on blinking green forever, which will drain the battery in a few days. Is there some way to have it timeout and go back to sleep if it doesn’t find the mesh in 5-10 seconds? At least until the high availability mesh becomes available, if the power goes out, I lose the mesh and I’ll only be draining the battery for nothing.


I believe you’d use:

int connectionFail = 10000 ;

You would manually connect after waking from a sleep cycle, then something like this to limit the connection attempt before performing the disconnection process and going back to sleep to save battery.
if (waitFor(Particle.connected, connectionFail)) {
// do your stuff here

Note: this may change for Mesh, IDK.

For example: This is what I did for cellular, a similar concept might work for you with the proper Mesh Calls and using the best Sleep mode for the Xenon for your case:

This could be interesting - 35nA sleep consumption …

@Rftop thank toy for that. It very much pointed me in the right direction. In case anyone reads this thread in the future, SYSTEM_MODE should be SEMI_AUTOMATIC, not manual. And before the if (waitFor… statement, you need to call Parrticle.connect(). But I can confirm it works perfectly on mesh and your post was very helpful.

@shanevanj the TPL5111 was discussed upthread, but it really is a very interesting device. It would work perfectly here but I think the power consumption is low enough that I’ll get my required battery life without it. And that’s a great idea about desiccant. I think the next few times I get one in a package, I’ll toss them in the project box.

Just a note on that: The combo SEMI_AUTOMATIC and SYSTEM_THREAD(ENABLED) does exhibit in some circumstances (IMO unnecessary) blocking behaviour and not in others.
In my experience MANUAL mode behaves much more consistent in that regard and in combination with SYSTEM_THREAD(ENABLED) the need for your code permanently calling Particle.process() becomes a non-issue too.

You can read something about this here


I’ve made a lot of progress on the code for my project. I’ve got a couple of really odd things that I can’t see what is cause. I’m wondering if there’s still known issues with the mesh tech.

The Particle.publish() calls from the Xenon don’t seem to be getting through. I have maybe 5% of them showing up in the web console. It’s not a throttling issue, it’s 1 publish every 2 minutes. The Mesh.publish() data seems to be nearly flawless. So right now, I have Xenon using Mesh.publish(), and the handler on the Argon is basically doing nothing except passing it on to a Particle.publish() which seems to work.

The big problem I’m having this, is my system seems to work flawlessly for 6-18 hours and then the Xenon loses the ability to connect to the mesh. I have the sleep timer set to 2 minutes instead of 10 because I’m still testing. When it fails, I still see the Xenon wake up every 2 minutes, flashes green for my 10 second timeout window, and then goes back to sleep. The Argon is still online and appears to be working properly. My first thought was it’s a battery/low temperature issue, but if I press the reset on the Xenon without taking it out of the freezer, everything starts working perfectly again for the next 6-18 hours until it happens again, and warming it up doesn’t solve the problem.

It’s not an intermittent issue though in the sense that it never fails to connect until the time it does and then it fails every single time after that until it is reset.

@ScruffR Is it possible the blocking you’re talking about is causing the problems that I described above?

And to be clear, as long as I have SYSTEM_THREAD(ENABLED), I never have to call Particle.process()? My issue with manual was making sure I call Particle.process() appropriately.

Yes, that should be so.

So far we mainly focused on the HW side of things, but this seems to be a SW issue, so we may need to have a look at your code - I’d have a suspicion but would rather want to see the code first :wink:

This is the code running on my Xenon:

#include <DS18B20.h>


const int      connectionFail    = 5000 ;
const int      MAXRETRY          = 120;
const int      sleepTime         = 120;

DS18B20  ds18b20(D2, true); //Sets Pin D2 for  Temp Sensor and 
                            // this is the only sensor on bus
char     szInfo[64];
double   celsius;
long     wakeTime;

void setup() {

void loop() {
 if (waitFor(Particle.connected, connectionFail)) {     // if connected to the cloud, process this cycle
    getTemp();                                          // take a measurement every interval, just within Mesh network
    if (!isnan(celsius))
      sprintf(szInfo, "%2.1f", (float)((int)(millis()-wakeTime))/1000);
      Mesh.publish("WorkingTime", szInfo);

      System.sleep(D6, RISING, sleepTime);
      wakeTime = millis();    
    System.sleep(D6, RISING, sleepTime);   // unable to connect to cloud, go to sleep and try again next time.

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

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

  if (i < MAXRETRY) {
    celsius = _temp;
  else {
    celsius = NAN;
  sprintf(szInfo, "%2.1f", celsius);
  Mesh.publish("dsTmp", szInfo);

It might be a timing problem.
You could add a delay(200) between the publish and the sleep statement or use something like this

  auto result = Mesh.publish("WorkingTime", szInfo);
  if (!result)
    System.sleep(D6, RISING, sleepTime);
    Serial.printlnf("That didn't work (code: %d)", result);

(updated, see following posts)

If you don’t use the return value the publish call will not wait for the success feedback but if you do it will await the outcome before proceeding.

1 Like

@ScruffR Thanks. I thinkI have something else wrong though. I made that change to the code, and I get into the “else” clause of the if statement. The publish call is working successfully, the Argon gets the data, but result is false.

When I replaced Mesh.publish, with Particle.publish, the reliability seemed to be 100% (as opposed to 5% the way I had the code before), so it fixed the issue I was describing, but I don’t know why it’s returning false. I “fixed” it by adding the sleep command to both if clauses, but I still get to “That didn’t work”.

Also, I still have the issue of the xenon failing to connect every time after 6-18 hours of working fine.

How does it behave when you add delay(250) between the Mesh.publish() and the if() statement?

This might be something for @joel to chime in on.

@DevRandom, I inquired about this and Rick helped me understand that there is some inconsistency between Particle.publish() and Mesh.publish() where the former returns a (future) bool where true indicates succes but the latter returns an int with 0 (aka false) indicating success. (don’t ask why - I don’t understand the logic either :face_with_raised_eyebrow::upside_down_face:)

So I changed the code above to prevent future readers from falling into that trap.

BTW, here is a list of possible return codes

Currently the docs do lie about the fact too

(I’m sure this will be fixed in a few minutes :wink: )

I think you can safely go to 5.5V on Li+ as @ScruffR says, but I think the range for BAT_DET that maxes out at 4.6V was a design decision rather than based on safety limits. It will be good if in the next design iteration the R15/R16 is changed to be able to measure up to 5.5V. With the current design, when the Li+ input is 5.5V, there’s usually an ESD protection diode at the input that will conduct away excess current. With the current values of R15/R16, this current is around 0.6uA, not enough to cause any damage IMHO. A side concern is a constant drain of ~2.4uA@5.5V due to R15/R16. While this may not sound like much, when you are a battery, every uA counts!