Help choosing correct SLEEP mode w/ Asset Tracker v2

Thanks @ScruffR (and @gusgonnet for jumping in!).

At your suggestion, I’m using System.sleep(SLEEP_MODE_SOFTPOWEROFF, TIME_PUBLISH_BATTERY_SEC); which seems to work mostly. At times it just won’t wake up though, unless I press the reset button. Seems to be related to this issue.

I have yet to try the AssetTrackerRK you mentioned earlier, but in your opinion, does it offer a better/more reliable “wake up from sleep on movement” experience? As is, if I cannot trust this to wake up when there’s motion, then I might as well throw it away.

@gusgonnet, do you have issues with yours waking on movement? (Or are you doing something else with yours?)

Yes, but I see the creator is about to answer :wink:

Actually, not necessarily. When your tracktor is stolen, it might not wake up on first move, but then your regular timed check might still do :wink:
And after that chances are that a subsequent move will do again too.


I wrote both implementations of wake-on-move. The one in AssetTrackerRK is way better than then one in the official AssetTracker library. I’ve been meaning to merge the change into the official version but I haven’t had a chance to.


You’d think so… but in my limited testing since flashing it last night, it doesn’t seem to wake up (at all - timed or motion-activated) if it goes to sleep while moving or (perhaps) if it wakes up and continues moving lots while waking up. I’m going to watch for messages on the console thru the day. Should know within 4 hours.

That’ll be my homework tonight. :slight_smile: If I can’t figure out how to get it working, I know where to come! Thanks both of you.

1 Like

@rickkas7 I’m afraid I might’ve encountered a bug. Wondering if you have any thoughts.

I loaded AsstTrackerRK example 3-wakeonmove, and just like the non-RK version, it still has problems if the device is moving when it falls asleep. Basically what I did was shake the device until it fell back asleep. Then if I smack it again later, it will not wake back up. I waited TIME_PUBLISH_BATTERY_SEC seconds but it never woke itself back up again. The device is dead to the world until I hit reset.

Here is the serial output (modified slightly to reduce repetition):

Opening serial monitor for com port: "/dev/cu.usbmodem1411"
waiting to come online
no location
resetting accelerometer
no location
failed to get GPS fix
resetting lastMovement int1_src=0x59
resetting lastMovement int1_src=0x69
resetting lastMovement int1_src=0x59
resetting lastMovement int1_src=0x69
going to sleep

I have pretty much no idea, but might it have something to do with this: accel.calibrateFilter(2000); just before sleeping? Would it maybe be smart to determine if the accelerometer is firing, and not go to sleep until it’s quiet?

I’ve searched around and this seems like it might be a known issue. I can’t tell if it’s been resolved. Is this how your devices respond as well?

EDIT: looks like this bug still. @rickkas7 were you ever able to replicate that bug? Because it certainly seems as though I am!

1 Like

This currently seems to be the best workaround (if you need the timed wake).
In order to minimise power consumption in case of “permanent” movement for a long time (e.g. during legitimate use of the tractor) you could send the device to sleep (e.g. 15 minutes) without a wake-pin set (0.8.0-rc.2 allows this for deep sleep, otherwise System.sleep(BTN, FALLING, 15*60) should work and gives you the option to wake the device via the SETUP/MODE button).

The underlying problem is in the Particle firmware issue #1262 that you already found.
The resolution for this issue is planned for 0.8.0 (providing it’s not an unresolvable hardware bug of the STM32F2 µC).

Alternatively you could rely on the WKP pin only and drop the timed wake, as this issue should not apply for System.sleep(SLEEP_MODE_DEEP) (stated in #1262 comment).
And in that connection, you could implement an external wake-trigger - e.g. with a CD4541B (or other low power, long periode timer chip) that just pulls RESET when needed.


What ScruffR said. Plus:

Sleep while moving is problem inherent in how the LIS3DH works, and yes, you need to wait until you stop moving until you go to sleep with wake-on-move. Here’s why:

In order to do wake-on-move, the accelerometer has to compensate for the force of gravity. Higher-end inertial measurement units have gyroscopes that can determine the tilt of the device, but the LIS3DH does not.

The official AssetTracker library just ignores the Z axis to do this. The problem is that if you don’t set the AssetTracker down flat, it does not work.

The AssetTrackerRK uses the concept of calibration before sleep, so it can figure out which way the device is oriented and cancel out the effect of gravity in any axis (or a combination).

The issue is that this only works when you are not moving. If you calibrate while moving, you’ll get incorrect values.


So my next step: determine when I’m not moving.

Here’s what hasn’t worked:

bool readyForSleep = accel.calibrateFilter(2000);  // <<-- this doesn't work! need to figure out how to detect non-movement.
if (readyForSleep) { do stuff }

Giving it more time ala accel.calibrateFilter(2000, MORE_SECONDS); is more of the same, but takes longer. I was hoping the bool would be false if it wasn’t able to calibrate b/c of movement, but it appears to always be true(?). Any chance this is a good fix but I’m implementing it wrong?

Also what doesn’t seem to work is using something like this from 4_Position to figure out when the detector is not moving:

void loop() {
        LIS3DHConfig config;
    	LIS3DHSample sample;
        if (accel.getSample(sample)) {
			Serial.printlnf("%d,%d,%d", sample.x, sample.y, sample.z);

I was hoping I could watch on the serial monitor that once it’s flat and not moving it would either show (0,0,0) or at the very least (stable, stable, stable) but it’s sitting here, undisturbed on my couch and it’s oscillating like crazy… 256,0,512 -> -256,0,0 -> 0,256,-768 -> 0,0,0 -> -256,-256,768 -> etc and it happens very quickly despite no noticable movement!

Is there a solution here that I’m perhaps implementing incorrectly? Or something completely different? I’m struggling here… :neutral_face:

Actually that is exactly the opposite. The second parameter doesn’t allow for more time to calibrate but actually limits the max time the calibration process is allowed to take. If you omit this parameter (or set it as 0) the calibration will wait indefinetly for a periode of 2000ms “silence”. With a value != 0 the process will be terminated even when no silence was detected and in that case you should see false returned.

This is the (current) implementation of the function

bool LIS3DH::calibrateFilter(unsigned long stationaryTime, unsigned long maxWaitTime) {
	bool ready = false;

	unsigned long start = millis();
	unsigned long lastMovement = start;
	unsigned long lastRecalibrate = start - RECALIBRATION_MOVEMENT_DELAY;

	while(maxWaitTime == 0 || millis() - start < maxWaitTime) {
		uint8_t int1_src = readRegister8(REG_INT1_SRC);
		if ((int1_src & INT1_SRC_IA) != 0) {
			Serial.printlnf("resetting lastMovement int1_src=0x%x", int1_src);
			lastMovement = lastRecalibrate = millis();

		if (lastRecalibrate != 0 && millis() - lastRecalibrate >= RECALIBRATION_MOVEMENT_DELAY) {
			lastRecalibrate = 0;

		if (millis() - lastMovement >= stationaryTime) {
			ready = true;

	return ready;
1 Like

Bummer. I feel like i was sold a false bill of goods!

Can you explain what you mean by “regular movement-interruption”? Thanks

@Vitesze, you share link is no longer valid so you must have deleted the app. I have a strong suspicion that your FSM is not working as you would expect.

@jschwalbe, not sure which “bill of goods” you feel cheated on. @Vitesze’s challenges with coding a solution is not a reflection of the Asset Tracker’s capabilities!


There is another discussion about this topic here (after move it’s actually this very thread)

But for the “bill of goods” I can’t see any statement that the wake-on-move will always work under all thinkable circumstances, so if you bought something based on assumption I’d not call it “being sold a false bill of goods”.

And as mentioned in the other thread, some “issues” contributing to the problem are being addressed too.

1 Like

What I mean, is that while in Deep Sleep for the LIS3DH I was only able to set an interrupt based on movement, but not on orientation. Mind you, I posted this topic half a year ago, but for my project I wanted to put the Asset Tracker in Deep Sleep and wake it up as soon as it moved beyond a certain angle.

Perhaps it’s possible, but I couldn’t find any clear-cut documentation or similar projects on it.

@peekay123 @ScruffR

I have no intention to make enemies here, sorry if my statement ruffled feathers. The community has been very helpful. I purchased this based on the following statement:

The shield also has an on-board accelerometer, the LIS3DH. It’s extremely low power so won’t chew up your energy budget. The accel communicates over SPI, so it takes up A2, A3, A4, and A5 as marked on the silkscreen of the shield. A configurable interrupt from the LIS3DH is connected to the Electron’s “wake” (WKP) pin, so you should be able to make a project where the Electron and GPS stay in deep sleep until it’s hit hard enough to cross a threshold you set on the accelerometer.

However, based on numerous threads such as here (others are searchable) and looking at this github issue, it appears as though waking up via accelerometer doesn’t work as reliably the document stated. If it doesn’t work reliably, then it can’t be trusted. And by not working reliably, it doesn’t just ignore further accelerometer data and fails to wake on movement, but it also fails to wake based on timing or anything other than the RESET button. (Did I read the github issue wrong? I hope so, but don’t think so.)

I’m going to keep trying to figure this out, but lots of smarter people before me apparently haven’t been able to. So I don’t have high expectations of success.

As pointed out in the other this (after move of post) thread and the initial issue description

without the timed wake you should be able to have the device wake on move.
I have not tested this, but I’d suppose the OP of the issue has since he is a Particle engineer.

BTW, have you considered any of the alternative suggestions I’ve made in the other this (after move of post) thread about the other sleep modes till silence is detected?

BTW²: Is “should” not also an expression that implies a degree of probability (and in this uncertainty)?

If a use-case doesn’t lend itself to this kind of solution (prolonged movement not allowing for silence detection) within the inevitable limitations of the availale tools it’s not the tool’s fault but due to choice of tools.
I’m not saying that there is no solution to your use-case (hence the alternative approaches suggested in the other thread) but this might be a possible outcome.
At first glance something looks as if it should work, but on close examination factors may emerge that weren’t anticipated at the time of choice of toolset.

As this discussion is actually leading away from the original topic of this thread, I’ll split off this part and move it to your own thread where you originally raised the issue.

1 Like

This does not work for the same reason as the other problems. If it sleeps w/ WKP high, it stays high until manually RESET, and no amount of jarring will cause the WKP to go low and then go high again.

Works beautifully so long as I don’t bump the device while it’s falling asleep. Otherwise, same issue. WKP stays HIGH and 10 seconds goes by and nothing happens. This actually might work. Obvious downside is no wake on movement. Will continue to test this.

This is the only solution you’ve proposed that I haven’t tried. I suppose I’ll try flashing the firmware later.

but if it’s shaken while sleeping, the WKP pin remains high.

It doesn’t.

Any recommendations on how I might implement this? I’ve tried

bool ready = accel.calibrateFilter(5000, 0);
if (ready & digitalRead(WKP) == 0 ) { <sleep_cmd> } else {accel.clearInterrupt(); break;}

So, here’s my problem. I have a device that is going to be jostled around. Even if I want it to ignore input from the accelerometer and ONLY sleep/wake based on time, it appears that I cannot do this. If there is movement from the accelerometer as it’s falling asleep, it requires a RESET to work again. You seem convinced that this is an unusual use case, but I’m starting to wonder if I have a bad unit. Any suggestions, @ScruffR or @rickkas7?

1 Like

If the use-case (at least in parts) doesn’t lend itself to the original approach you may have to reframe the problem.
e.g. the way I suggested - when movement is detected when wanting to go to deep sleep with wake-on-move, an alternative sleep mode with shorter sleep cycle can be chosen, to wake a bit later for a check whether movement has stopped. If it hasn’t do the same again if it has, reset the WKP pin and go to deep sleep with timed wake.

So even if the original approach turns out to be impossible, alternative ways may still lead to (almost) the same outcome.

Unfortunately other sleep modes seem to have the same problem :frowning:

I was browsing github and saw mention of SLEEP_DISABLE_WKP_PIN as a sleep mode. Can you (or anyone) point me in the direction of which firmware I’d find this in? All I can see is it was committed to develop branch. But that means nothing to me in terms of how to get the functionality onto my Electron.

That’s a new feature introduced with 0.8.0-rc.2
Particle Device OS Updates Thread - #57 by mdma


@jschwalbe, this might be interesting for your