Accelerometer not working after turning off GPS

I’m building a GPS tracker with the Electron and want to save energy by turning off the GPS when the device is not moving for a certain period. However, the accelerometer sometimes stops working (returns a movement of zero) after turning off the GPS. I tried to re-initialize it but I can’t bring it back to a working state.

I encountered this problem with the Asset Tracker library and found a topic about a similar problem where @Dick suggested to try out fancy-asset-tracker. That didn’t work either in my case. Here is a small example firmware (headers and initialization code are copied from fancy-asset-tracker):

#include "Adafruit_LIS3DH.h"
#include "Adafruit_GPS.h"
#include <math.h>

Adafruit_GPS gps(&Serial1);
Adafruit_LIS3DH accel(A2, A5, A4, A3);
    
void setup() {
  // Init accelerometer
  accel.begin(LIS3DH_DEFAULT_ADDRESS);
  accel.setDataRate(LIS3DH_DATARATE_LOWPOWER_5KHZ);
  accel.setRange(LIS3DH_RANGE_4_G);
  
  // Enable GPS
  pinMode(D6, OUTPUT);
  digitalWrite(D6, LOW);
  
  gps.begin(9600);
  Serial1.begin(9600);
  
  gps.sendCommand("$PMTK101*32");
  delay(250);
  gps.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
  delay(250);
  gps.sendCommand(PGCMD_NOANTENNA);
  delay(250);
  
  // Debug output
  Serial.begin(9600);
}

bool gpsOn = 1;
unsigned long lastMoved;

void loop() {
  unsigned long now = millis();
  
  // Update GPS
  char c = gps.read();
  
  if (gps.newNMEAreceived()) {
    gps.parse(gps.lastNMEA());
  }
  
  accel.read();
  int acc = sqrt(accel.x * accel.x + accel.y * accel.y + accel.z * accel.z);
  
  // Enable GPS when the device is moving, disable after 10 s without movement
  if (acc > 9000) {
    lastMoved = now;
    
    if (! gpsOn) {
      Serial.println("Activating GPS");
      gpsOn = 1;
      
      digitalWrite(D6, LOW);
    }
  }
  
  if (lastMoved != 0 && (now - lastMoved > 10000)) {
    if (gpsOn) {
      Serial.println("Deactivating GPS");
      gpsOn = 0;
      
      digitalWrite(D6, HIGH);
    }
  }
}

Unfortunately, the problem doesn’t always occur. The program might work for many GPS on/off iterations and then fail. Here is some example output:

<Start, shake device>
<Wait for 10 s>
Deactivating GPS
<Shake device>
Activating GPS
<Wait for 10 s>
Deactivating GPS
<Shake device>
<Nothing happens, GPS not activating, accel.read() => 0> 

Am I doing something wrong in the firmware? Do you know a working setup that combines GPS and accelerometer?

Are you purposely using soft SPI on the hardware SPI pins?
What port of the LIS3DH lib are you using? Have you got a link?

Sorry, I don’t know what that means (didn’t do any hardware development before). :grinning: It’s the same code that is used in Particle’s own Asset Tracker library. The Adafruit includes are copied from here: https://github.com/dmiddlecamp/fancy-asset-tracker/tree/master/gps-library.

I’ll have a look at that lib.

But the SW vs. HW SPI is because you use the four parameter overload rather than the one parameter version Adafruit_LIS3DH accel(A2); which would use the same pins but with less bit-banging from your code and rather leaving that to the µC’s hardware interface.
I wouldn’t see a reason why the SW SPI was chosen in Particles own samples I’ll maybe give the contriubutor a ping on GitHub

I see it’s @Dave’s work of art, so we can ping him direct :wink:

2 Likes

I’ve noticed an issue in one of my fancy examples where the accel interrupt stops working after a time, I’m not sure why yet. :confused:

I tried the example above with Adafruit_LIS3DH accel(A2); but then the firmware isn’t working at all (it doesn’t get to the loop). :worried: The LED is breathing cyan but I can’t put the Electron into listening mode anymore without going to safe mode first.

That is odd.