Asset Tracker; detecting movement during time interval

I have an Asset Tracker with part of the code it uses (the problematic part) listed below. While in Verification state, I want the sensor to either move on to GPS_Wait state if over the course of 5 seconds movement has been detected by the accelerometer. If not, it should enter sleep state. Whenever I try this out however the sensor will always enter sleep state regardless of anything.

case SLEEP_TRIGGER_STATE: {
Serial.println("measuring time");

  _msWait = millis();
  state = VERIFICATION_STATE;
	
  break;
case VERIFICATION_STATE: 
    if (millis() - _msWait < VERIFICATION_TIME) {
        state = GPS_WAIT_STATE;
        break;
    }
	state = SLEEP_STATE;

}
break;

case GPS_WAIT_STATE:
// Restart the GPS
//pinMode(D6, OUTPUT);
digitalWrite(D6, LOW);
startFix = millis();
gettingFix = true;

  if (gps.location.isValid()) {
  	// Got a GPS fix
  	state = PUBLISH_STATE;
  	break;
  }
  if (millis() - stateTime >= MAX_TIME_FOR_GPS_FIX_MS) {
  	Serial.println("failed to get GPS fix");
  	state = PUBLISH_STATE;
  	break;
  }
  break;

With Verification_time set at 5000, and msWait set to uint32_t. Full code is here: Particle Web IDE

EDIT: I also tried the following code, which didn't work either.

case VERIFICATION_STATE: 
  if (pos != 0 && pos != lastPos) {
  	Serial.printlnf("pos=%d", pos);
  	state = GPS_WAIT_STATE;
    }
	if (millis() - stateTime >= VERIFICATION_TIME) {
	   Serial.println("no movement detected");
	   state = SLEEP_STATE;
	   stateTime = millis();
	}
  break;

How about changing the second if block into an else if like this?

case VERIFICATION_STATE: 
	if (pos != 0 && pos != lastPos) {
		Serial.printlnf("pos=%d", pos);
		state = GPS_WAIT_STATE;
    }
    else if (millis() - stateTime >= VERIFICATION_TIME) { 
	   Serial.println("no movement detected");
	   state = SLEEP_STATE;
	   stateTime = millis();
	}
	break;

The way you had it, the state was just overwritten with SLEEP_STATE immediately

2 Likes

Here’s my latest code:

https://go.particle.io/shared_apps/596f9c938e4f26a1170002e0

Electron always goes back to sleep mode no matter what. Any help here is very much appreciated; it’s missing piece of the puzzle for me with my asset tracker.

Do you keep track of the previous state to see where the sleep state got set exactly?
Do you keep the serial log that leads up to the misbehaviour?

Posting this would help understanding the actual sequence how things do happen vs. how you’d expect them to happen.

1 Like

Played a bit with the code for a while. I totally understand things better now after keeping an eye on the serial monitor.

The sensor is taking samples every 500ms (for testing purposes) and after 20 seconds it times out and goes back to sleep. The position interrupt doesn't work for some reason; not sure why, but I will look more into it tomorrow to see if I can figure it out.

case = VERIFICATION_STATE:

if (millis() - lastPrintSample >= 500) {
lastPrintSample = millis();
if (accel.getSample(sample)) {
Serial.printlnf("%d,%d,%d", sample.x, sample.y, sample.z);
}
else {
Serial.println("accelerometer is unresponsive");
state = SLEEP_STATE;
}
break;
}
if (positionInterrupt) {
positionInterrupt = false;
uint8_t pos = accel.readPositionInterrupt();
if (pos != 0 && pos != lastPos) {
Serial.printlnf("pos=%d", pos);
lastPos = pos;
state = GPS_WAIT_STATE;
break;
}
}
if (millis() - stateTime >= VERIFICATION_TIME) {
Serial.println("verification timed out");
state = SLEEP_STATE;
break;
}
break;

I worked on it some more today…although it’s printing xyz data and now handles all the if-statements just fine, it continues to give the exact same position regardless of what happens. I tried to follow the library example as closely as possible but something’s still amiss.

https://go.particle.io/shared_apps/5970db968e4f26ac05001a12

EDIT: Nevermind. Didn’t look properly, and in addition to attaching the positionInterrupt to WKP it should also be configured with config.setPostionInterrupt(16); Problems with going back to sleep though, probably because I did attachInterrupt(WKP, positionInterruptHandler, RISING); ?

Isn't 16 a bit sensitive?

I used the default values in the example of the library. Perhaps it’s a bit sensitive but in practice it seems to work fine.
How does the sensitivity work on it anyway? There’s a few position states it can be in, and the interrupt should only be triggered if it goes from one state to the next?

@Vitesze I’m going thru the same problems as you were. Mind posting your code so I can grab it?

I’m having problems detecting if the tracker is still moving (I’d like it to stay awake if it detects motion).

Thanks!

Hi,

It has been quite a while since I used the LIS3DH accelerometer (which is on the Asset Tracker) but I remember using:

accel.calibrateFilter(5000);

in which 5000ms without movement-detection need to pass for the Electron to enter the next piece of code (e.g. Deep Sleep).

1 Like