Electron won't enter Sleep mode

An easy to solve problem, but I’m not sure how to do it. When my sensor wakes up, it takes some accelerometer position readings, and then (is supposed to) go back to sleep. The issue lies with this piece of code (I suspect) where upon wake-up I use this line to detect changes in position. Afterwards the sensor refuses to go to sleep. Any ideas?

attachInterrupt(WKP, positionInterruptHandler, RISING);

case SLEEP_STATE:

  Cellular.on();
  delay(10000);
  Cellular.off();
  delay(5000);
  Serial.println("starting calibration");
  accel.calibrateFilter(5000);
  
  delay(500);
  
  Serial.println("entering sleep");
  FuelGauge().sleep();
  // 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.
  
  awake = ((accel.clearInterrupt() & LIS3DH::INT1_SRC_IA) != 0);
    
    delay(500);
    
    attachInterrupt(WKP, positionInterruptHandler, RISING);
    
    delay(5000);
    
    LIS3DHConfig config;
  config.setPositionInterrupt(16);

  bool setupSuccess = accel.setup(config);
  Serial.printlnf("accelerometer set up", setupSuccess);
    
  Serial.printlnf("entering verification mode");
    state = VERIFICATION_STATE;
    stateTime = millis();
  break;

Update:
Full code: https://go.particle.io/shared_apps/59710793fdc3111ac9000483

You may want to share the code of the ISR - and the variables altered therein - too.

https://go.particle.io/shared_apps/59710793fdc3111ac9000483

1 Like

BTW, if you are using the Particle AssetTracker Shield you could use @rickkas7’s AssetTrackerRK library

My code is largely based on his library. However, I wanted to adapt it a bit to suit my own needs; after a lot of work everything seems to work fine now except that the sensor cannot go back to sleep anymore now after it is woken up, due to

	attachInterrupt(WKP, positionInterruptHandler, RISING);

I couldn’t find any examples in Rickkas’ library where he combined a wake-on-move with a position-detection, so I’m not sure how to do this now.

In theory you can do wake on position change. However, you’ll wake on any position change, as you can’t, for example, only wake when you change from position 3 to position 4.

However, I was unable to make it work. It seems to still wake when you move it, as well. Here’s the code that should work, but doesn’t:

Is there any way, with my above code, to have the sensor wake up on movement, do a position check (both works as of now) and then go back to sleep? It’s the going to sleep part that is giving me issues now.

https://go.particle.io/shared_apps/59710793fdc3111ac9000483

EDIT: Upon further investigation, it’s not actually the sleep that’s causing issues; it’s the accelerometer calibration?

If you set the accelerometer into position interrupt mode using setPositionInterrupt, make sure you set it back to wake on move mode using setLowPowerWakeMode before you try to calibrate prior to sleep.

1 Like

I’m working on the same type of Electron GPS tracker setup and I was wondering if I could use the GPS speed as the factor to gauge whether to put the device to sleep or speed up or slow down the published rates.

Not sure if it’s a reliable method or not but just a thought for now.

Still the same issue; even though right before system.mode I declare:

  Serial.println("resetting accelerometer");
  LIS3DHConfig config;
  config.setLowPowerWakeMode(10);
  Serial.println("reset successful");

Once it starts calibrating the accelerometer, it immediately prints ‘‘resetting lastMovement int1_src=0x60’’ and then stay turned on, until it IS moved in which case it sleeps and immediately wakes up again.

https://go.particle.io/shared_apps/5972455074da053aaf000103

I might be misreading your code, but it looks like when you wake up in SLEEP_STATE, you go into ACCELEROMETER_POSITION_STATE.

That sets position mode and goes into VERIFICATION_STATE.

By the way line 145 is probably a bug:

if (positionInterrupt = false)

But in any case you either go into SLEEP_STATE directly or into GPS_WAIT_STATE, PUBLISH_STATE, then SLEEP_STATE.

You don’t go back into RESET_STATE to reset the accelerometer back into movemement detection state.

Oh I see, I thought

  LIS3DHConfig config;
  config.setLowPowerWakeMode(10);
  Serial.println("reset successful");

in the beginning of sleep_state would configure it correctly?

EDIT: Thanks, I don’t fully understand it yet, but redirecting everything to RESET_STATE first works fine. Is this because the accelerometer configuration doesn’t apply yet to statements in the same case i.e. the config must be in a case preceding the one System.sleep is in?

Correct, the states are not necessarily executed sequentially. It jumps to whatever you set the state variable to on the next loop. The first time through it executed the RESET_STATE, but it didn’t go back through that again after ACCELEROMETER_POSITION_STATE.

Ok thanks, got it! I had a hunch that’s how it worked, good to know for sure now. Then I suppose it also was a really bad idea of me to put the config.position in the same case as system.sleep.

Once you get the code working please share it if possible.

I sure will. I still have to adjust some value and clean things up a bit, but I will send my code to you once it’s done so you can have a look :).