ADXL345 interrupt problems

I’m trying to wake up an electron board from sleep using an ADXL345 accelerometer. I can correctly write to the accelerometer using I2C, as well as read from it, but I can’t make the interrupt pin fire to wake up the WXP pin on the Electron Particle.
Here’s the datasheet I’m looking at:
https://www.analog.com/media/en/technical-documentation/data-sheets/ADXL345.pdf
and here’s the library I’m using:
https://github.com/particle-iot/spark-lib-adxl345

// This #include statement was automatically added by the Particle IDE.
#include <adxl345.h>

SYSTEM_MODE(SEMI_AUTOMATIC);

#define ACCELADDRESS 0x53

ADXL345 accel;
unsigned long firstAvailable = 0;
int couunter;

void setup() {
  // put your setup code here, to run once:
  delay(4000);
  
  Serial.begin(9600);
  Serial.println("setup called");
  Serial.println("wakeonmove 6/5/2019");
  
  Wire.begin();
  
  accel.powerOn();
    
    write_register(ACCELADDRESS, 0x24, 0x10);
    write_register(ACCELADDRESS, 0x25, 0x10);
    write_register(ACCELADDRESS, 0x26, 0x0A);
    write_register(ACCELADDRESS, 0x27, 0x77);
    write_register(ACCELADDRESS, 0x2D, 0x30);    //accelerometer auto-sleep
    write_register(ACCELADDRESS, 0x2F, 0x10);
    write_register(ACCELADDRESS, 0x2E, 0x10);
    
    
    Serial.println(read_register(ACCELADDRESS, 0x24));
    Serial.println(read_register(ACCELADDRESS, 0x25));
    Serial.println(read_register(ACCELADDRESS, 0x26));
    Serial.println(read_register(ACCELADDRESS, 0x27));
    Serial.println(read_register(ACCELADDRESS, 0x2D));    //accelerometer auto-sleep
    Serial.println(read_register(ACCELADDRESS, 0x2F));
    Serial.println(read_register(ACCELADDRESS, 0x2E));
    
    
    Serial.println("SETUP COMPLETE"); Serial.println();
 }

void loop() {
  //bool wifiReady = WiFi.ready();
  bool cloudReady = Particle.connected();

  //Serial.printlnf("wifi=%s cloud=%s counter=%d", (wifiReady ? "on" : "off"), (cloudReady ? "on" : "off"), counter++);

  if (true) {
    if (firstAvailable == 0) {
      firstAvailable = millis();
    }
    if (millis() - firstAvailable > 30000) {
      // After we've been up for 30 seconds, go to sleep

      Serial.println("calling System.sleep(WKP, RISING, 30)");

      // This delay is here so the serial print above goes out before going to sleep
      delay(1);

      System.sleep(WKP, RISING, 30);
        
      read_register(ACCELADDRESS, 0x30);
      // In this mode, setup() is not called again. Sometimes, but not always, the Serial port does
      // not restore properly. This solves the problem.
      Serial.begin(9600);
      delay(1000);

      // In this mode,after the sleep period is done, execution continues where we left off,
      // with variables intact.
      Serial.println("returned from sleep");

      // Important! If you don't reset this, you'll immediately go back to sleep, since variables
      // are preserved.
      firstAvailable = 0;
    }
  }
  else {
    firstAvailable = 0;
  }

  delay(1000);
}


byte read_register(int I2CAddress, byte address)
{
  //Send a request
  //Start talking to the device at the specified address
  Wire.beginTransmission(I2CAddress);
  //Send a bit asking for requested register address
  Wire.write(address);
  //Complete Transmission
  Wire.endTransmission(false);
  //Read the register from the device
  //Request 1 Byte from the specified address
  Wire.requestFrom(I2CAddress, 1);
  //wait for response
  while(Wire.available() == 0);
  // Get the temp and read it into a variable
  byte data = Wire.read();
  return data;
}

// Writes a single byte (data) into address
void write_register(int I2CAddress, unsigned char address, unsigned char data)
{
  //Send a request
  //Start talking to the device at the specified address
  Wire.beginTransmission(I2CAddress);
  //Send a bit asking for requested register address
  Wire.write(address);
  Wire.write(data);
  //Complete Transmission
  Wire.endTransmission(false);
}

Reading from the registers shows me the same things I write to them, and, in a different code, when I read from the interrupt source(0x30) and print it to screen, it shows that the Activity interrupt is working on the ADXL345. The problem is that the WXP pin never fires and never wakes up the board.

I don’t know what’s going on, so any help would be appreciated. Thanks!

1 Like

I actually found the problem. The data sheet said that the interrupt bit (0x2F) needed to be set to 1 to be set to INT2, when it really needs to be set to 0 to go through the second interrupt pin. I just needed to change what I was writing to the interrupt map register (0x2F) from 0x10 to 0x00.

If anyone is using the ADXL345 accelerometer and is having similar problems, another issue I found is that you can’t have the accelerometer running the autosleep function if you intend to use it to wake up the Particle from sleep. It will never wake up on move in that case.

1 Like