Asset Tracker Accelerometer + GPS problem

Which library are you using? The official asset tracker library wake on move does not work properly. I think I fixed it in AssetTrackerRK; you can read more about it here: https://github.com/rickkas7/AssetTrackerRK

Thanks rickkas7,

Yep, I am using the AssetTrackerRK present in the Particle Library Manager. The only change I made was on System.Sleep to go into deep sleep (removed the last parameter of System.Sleep call: “SLEEP_NETWORK_STANDBY”).

Any ideas ?

Touch a wire briefly between 3V3 and WKP when it’s in the state where it won’t wake up. If it wakes up, the problem is that the accelerometer isn’t correctly signaling the processor. If it doesn’t, then something is preventing the processor from waking up. That won’t really solve the problem, but at least it will narrow it down.

Thanks! I will try to replicate the problem here and post back.

Hi rickkas7,

Touching the WKP with 3.3V does not wake up the processor when it is in this state…

Is this a hardware problem ? Do I have a faulty unit ?

Well it could be a hardware problem, but the most likely problem is a code structure or state machine issue. The most common cause is some code path that causes the Electron to immediately go back to sleep when it wakes up. It happens so fast it looks like nothing happened.

2 Likes

I have problem about using this. It wake when I hit the reset button but then it never wake. And everything is worse when I add GPS. It seem like GPS is not wake when I shake. It work even the electron still sleep.

In the latest firmware+library the wake on movement seems to work fine. At least a half dozen times or so I tested it so far.

But, does anyone know how to undo what the t.setupLowPowerWakeMode(movementThreshold) function does? It seems to put the accelerometer into a low-power mode that’s just for waking up the device so I can’t use other functions to read the current values.

What I’m doing is waking on movement, and then turning on the GPS. I want it to remain on as long as there has been recent movement.

So I have to switch the chip from the Low Power Wake Mode to normal mode (while on), and then back. But, I can’t seem to find the function that puts it back.

Hey @rickkas7, I know this is an older thread but I’m still having a problem waking up the Electron using your AssetTrackRK library.

If I don’t turn off the GPS before going to sleep (like your wake on move example does by default), then the Electron wakes up every time.

However, if I uncomment the lines in your code to turn off the GPS before sleeping, the Electron wakes up from motion once, then never again. This behavior happens every time.

Here is a code snippet of my sleep state:

case SLEEP_STATE:
    // Wait for Electron to stop moving for 2 seconds so we can recalibrate the accelerometer
    accel.calibrateFilter(2000);

    // Is this necessary?
      digitalWrite(D6, HIGH);
      pinMode(D6, INPUT);

      Serial.println("going to sleep");
      delay(500);

    // Sleep
    System.sleep(WKP, RISING, TIME_PUBLISH_BATTERY_SEC, SLEEP_NETWORK_STANDBY);

    // This delay should not be necessary, but sometimes things don't seem to work right
    // immediately coming out of sleep.
    delay(500);

    awake = ((accel.clearInterrupt() & LIS3DH::INT1_SRC_IA) != 0);

    Serial.printlnf("awake=%d", awake);

    // Restart the GPS
    pinMode(D6, OUTPUT);
    digitalWrite(D6, LOW);

    startFix = millis();
    gettingFix = true;

    state = GPS_WAIT_STATE;
    stateTime = millis();
    break;

I have tried many variations of when to turn on and off the GPS, and when to clear the accel interrupt, but I haven’t had any luck.

I am using the AssetTrackerV2 and I have tried my code on system firmware versions 0.6.0 and 0.6.4.

Have you experienced this problem as well?

Thank you for finding a reproducible fail case for this. I was able to reproduce this and fix it when the GPS is powered down (D6 set HIGH before sleep). I suspect this change will also fix the randomly not being able to wake up from sleep even when the GPS is on.

Reinitializing the LIS3DH prior to calibrating the filter seems to solve the problem. Basically this, just before accel.calibrateFilter(2000).

			LIS3DHConfig config;
			config.setLowPowerWakeMode(16);
	
			accel.setup(config);

When unable to wake up from sleep, it’s definitely the LIS3DH not generating the WKP pulse, not an issue with the Electron not waking up. I put a logic analyzer on it and WKP doesn’t change.

There’s a new version of AssetTrackerRK 0.1.5, with this change. It also has a fix for isValid not actually being valid.

5 Likes

I tried that out and it works for me too! Thanks so much!

1 Like

Thank you both for the fix… I’m still in need of one. I’ll give it a try !
-jc

Thanks @rickkas7 - This works! Yay! (With one small exception.)

Here’s the scenario. Tap the electron to wake it up. Let it communicate with server/etc. Pause for 1500 ms then tap it again just before it goes to sleep. WKP stays high and the electron won’t wake back up again with motion, but it WILL wake via TIME_PUBLISH_BATTERY_SEC (which I’d like to set to 12ish hours).

You may say this is unlikely to happen, but this is going on a tractor. It might sit still for 2 seconds and then move again abruptly, causing the tracker to become unresponsive for 12 hours.

I took a video (WARNING: some electron frustration will be seen) to see if anyone can reproduce my findings. This is taken with an unedited 3-wakeonmove.ino from AssetTrackerRK 0.1.5 library. The blue light is tied with a jumper to WKP so blue light = WKP high.

I tried removing the delay(500); just before the sleep command, but that didn’t fix it. Also tried adding accel.clearInterrupt() just before the sleep command, but I clearly don’t know what I’m doing.

I made the following observation using the following code change:

    if( digitalRead(WKP) == LOW ) {
      Serial.println("WKP LOW");
      System.sleep(WKP, RISING, TIME_PUBLISH_BATTERY_SEC, SLEEP_NETWORK_STANDBY);
    } else {
      Serial.println("WKP HIGH");
      break;
    }

and my serial terminal says the following just before going to sleep (with WKP high):

resetting lastMovement int1_src=0x6a
recalibrating
resetting lastMovement int1_src=0x6a
recalibrating
WKP LOW

which makes me think that if the electron gets bumped AS the sleep command is being performed, it will not have a chance to reset the accel and thus WKP stays HIGH.

Not sure this can be classified as a bug, but it’s more of less behaving as it’s supposed to (bump = WKP HIGH until reset), right? If this is what’s happening, is there a workaround, since it doesn’t seem like detecting WKP works?

From my understanding, if the electron gets bumped while entering sleep mode, there isn’t much you can do about it.

However, I found that the most time consuming part of entering sleep mode is turning off the cellular modem. So my “work around” is to turn off cellular, then check the wake pin right before entering sleep mode.

Here is that part of my code:

    Cellular.off();
    delay(4000); //wait for cellular to actually turn off

    // check WKP to make sure it isn't high before sleeping
    if (digitalRead(WKP)==LOW) {
      // Sleep
      System.sleep(WKP, RISING, TIME_PUBLISH_BATTERY_SEC);

      // This delay should not be necessary, but sometimes things don't seem to work right
      // immediately coming out of sleep.
      delay(500);

      // Connect to network
      Particle.connect();

      // Clear interrupt and AND return value with the interrupt flag register
      awake = ((accel.clearInterrupt() & LIS3DH::INT1_SRC_IA) != 0);
      newMotion = 1;

      Serial.printlnf("awake=%d", awake);
    }else { //Motion caught before going to sleep

      // Connect to network
      Particle.connect();
      delay(500);

      accel.clearInterrupt();
      awake = 1;
      newMotion = 1;
    }

I find this greatly limits the time interval where the wake pin can go high without catching it.

4 Likes

That definitely does work. It makes the cell signal take about 15 sec to reconnect, but I think it’s worth the trade off to have a device that works. Thanks lots!

P.S. I’m using System.sleep(SLEEP_MODE_SOFTPOWEROFF, TIME_PUBLISH_BATTERY_SEC); as my sleep command. That might be part of why it takes longer to get cell signal back up, not sure.

@rickkas7’s solution involving resetting the accelerometer before going to sleep works for making waking up the electron, once the GPS is turned on again in the SLEEP_STATE, the accelerometer no longer generates an interrupt on the WKP pin. This is an issue if you want to detect continual movement before going back to sleep. This behavior tells me that powering on the GPS is what screws with the accelerometer.

Further, the accelerometer cannot be reset immediately after powering on the GPS or it won’t work right for some reason.

An alternate solution to the one proposed by Rick is instead of resetting the accelerometer before sleeping in the WakeOnMove example, is to instead go to the online wait state after waking up. This provides enough of a delay before going to the reset state where the accelerometer is reset. Doing so will allow the WKP interrupt to be set/reset many times before going back to sleep state.

1 Like

I was having this problem for a while but didn’t know where to start to troubleshoot it. Turning off cellular before going to sleep fixed it, thanks.

Now question regarding accel calibration, should I do it when I’m sure WKP is low (inside the if)? or leave it before? Reason I’m asking is because if it turns out it’s still moving, is it a good time to calibrate it?
Thanks.

I check WKP before and after calibrating to make sure there was no movement. If there is movement, I skip going to sleep. This seems to work well. I haven’t had any issues yet.

3 Likes

I believe I’ve tried all of these suggestions to prevent the sleep with motion issue from occurring, however I’ve noticed two things:

  1. I can still get it to go to sleep and not wake up via WKP. As the device falls asleep, the status light goes from light blue > green > dark blue. If I apply motion it just before the dark blue light goes out, it will get stuck.
  2. If I use a sleep mode other than SLEEP_NETWORK_STANDBY, and it has motion applied to it while going to sleep, it will not wake up with WKP for a timer. It fully crashes until a reset is applied.

Here is my sleep code:

        case SLEEP_STATE:
        digitalWrite(D6, HIGH);
		{
			LIS3DHConfig config;
			config.setLowPowerWakeMode(WKP_THRESHOLD);
			accel.setup(config);
		}
		accel.calibrateFilter(2000);
        Cellular.off();
        delay(4000);
        if (digitalRead(WKP)==LOW) {
            //THIS CAUSES FATAL CRASHES
      		//System.sleep(SLEEP_MODE_SOFTPOWEROFF, TIME_PUBLISH_BATTERY_SEC);
      		//THIS CAUSES FATAL CRASHES
      		//System.sleep(SLEEP_MODE_DEEP, TIME_PUBLISH_BATTERY_SEC);
      		//THIS DOESNT SEEM TO ACTUALLY GO TO SLEEP
      		//System.sleep(TIME_PUBLISH_BATTERY_SEC);
      		//THIS WORKS OK, BUT STILL CAN BE STUCK IF MOTION IS TIMED CORRECTLY.  IT AT LEAST ALLOWS TO WAKE BACK UP ON THE TIMER.
      		System.sleep(WKP, RISING, TIME_PUBLISH_BATTERY_SEC, SLEEP_NETWORK_STANDBY);
      		delay(500);
      		Particle.connect();
      		awake = ((accel.clearInterrupt() & LIS3DH::INT1_SRC_IA) != 0);
      		Serial.printlnf("awake=%d", awake);
    	}else {
  			Serial.println("MOTION CAUGHT BEFORE SLEEP");
    		delay(500);
     		Particle.connect();
     		delay(500);
      		awake = ((accel.clearInterrupt() & LIS3DH::INT1_SRC_IA) != 0);
    	}  
        digitalWrite(D6, LOW);
        startFix = millis();
        gettingFix = true;
        Serial.println("ONLINE_WAIT_STATE");
        state = ONLINE_WAIT_STATE;
        stateTime = millis();
        break;

I can still get it to go to sleep and not wake up via WKP. As the device falls asleep, the status light goes from light blue > green > dark blue. If I apply motion it just before the dark blue light goes out, it will get stuck.

If you apply motion in this time, the WKP pin is set before the Electron actually goes to sleep, so it can't generate an interrupt to wake it up. I haven't figured out a solution to this beyond using some external component to check for this condition. At least it will wake up after the specified amount of time and reset everything.

If I use a sleep mode other than SLEEP_NETWORK_STANDBY, and it has motion applied to it while going to sleep, it will not wake up with WKP for a timer. It fully crashes until a reset is applied.

There is a bug involving SLEEP_MODE_DEEP and SLEEP_NETWORK_STANDBY that locks up the Electron if the WKP pin is high when sleeping. As far as I know, this has not been resolved. My workout was to just not use these sleep methods :grinning: