ADXL345 I can see Interrupts but I cant use pins

Hi everyone, ı am trying to use ADXL345. I want to detect inactivity, activity and if new data available.
here is my full code:

#include <Wire.h>  // Wire library - used for I2C communication
#define DEVICE 0x53    // ADXL345 device address
#define ADXL345_READ_ERROR 1 // problem reading accel
#define ADXL345_ERROR 0 // indicates error is predent
#define BW_RATE 0x2C
#define POWER_CTL 0x2D
#define THRESH_ACT 0x24    //-> activty threshold
#define THRESH_INACT 0x25  // -> inactivty threshold 
#define TIME_INACT 0x26
#define ACT_INACTL_CTL 0x27
#define INT_ENABLE 0x2E
#define INT_MAP 0x2F
#define INT_SOURCE 0x30
#define DATA_FORMAT 0x31 // Data format control (2g,4g,8g,16g)
#define data 0x32
bool status;           // set when error occurs

byte buff[6];
float X_out, Y_out, Z_out;  // Outputs
byte nom[1];
byte error_code;       // Initial state
boolean sa = false;
volatile int sensor_update = 0, active_mode = 0;
void setup() {
  Serial.begin(115200); // Initiate serial communication for printing the results on the Serial monitor
  while (!Serial);
  writeTo(POWER_CTL, 0x08);
  writeTo(BW_RATE,0x18);
  writeTo(DATA_FORMAT, 0x01);
  setActivityAxes(ACT_INACTL_CTL, 0xFF);
  setActivityThreshold(5);
  setInActivityThreshold(5);
  setTimeInactivity(10);
writeTo(INT_MAP, 0x67);
  writeTo(INT_ENABLE, 0x98);
  writeTo(POWER_CTL, 0x38);
  delay(10);
}

void loop() {
  readFromAct(INT_SOURCE, 1, nom);
}

void setTimeInactivity(int timeInactivity) {
  timeInactivity = constrain(timeInactivity, 0, 255);
  byte _b = byte (timeInactivity);
  writeTo(TIME_INACT, _b);
}

void setInActivityThreshold(int inActivityThreshold) {
  inActivityThreshold = min(max(inActivityThreshold, 0), 255);
  byte _b = byte (inActivityThreshold);
  writeTo(THRESH_INACT, _b);
}

void setActivityAxes(byte address, byte val)
{
  writeTo(address, val);
}

void setActivityThreshold(int activityThreshold) {
  activityThreshold = min(max(activityThreshold, 0), 255);
  byte _b = byte (activityThreshold);
  writeTo(THRESH_ACT, _b);
}

void readFromAct(byte address, int num, byte _buff[]) {
  Wire.beginTransmission(DEVICE); // start transmission to device
  Wire.write(address);             // writes address to read from
  Wire.endTransmission();         // end transmission

  Wire.beginTransmission(DEVICE); // start transmission to device
  Wire.requestFrom(DEVICE, num);    // request 6 bytes from device

  int i = 0;
  while (Wire.available())        // device may send less than requested (abnormal)
  {
    _buff[i] = Wire.read();       // receive a byte
    i++;
  }
  if (i != num) {
    status = ADXL345_ERROR;
    error_code = ADXL345_READ_ERROR;
  }
  
  if (_buff[0] & (1 << 4))
  {
    Serial.println("activty detected") ;
  }
  Wire.endTransmission();         // end transmission

  if (_buff[0] & (1 << 3))
  {
    Serial.println(" Inactivty Detected , No activty detected") ;

  }
  if ((_buff[0] & (1 << 7) && _buff[0] & (1 << 1)))
  {
    Serial.println(_buff[0]);
    readFrom(data, 6, buff);
  }
}

void readFrom(byte address, int num, byte _buff[]) {
  Wire.beginTransmission(DEVICE); // start transmission to device
  Wire.write(address);             // writes address to read from
  Wire.endTransmission();         // end transmission

  Wire.beginTransmission(DEVICE); // start transmission to device
  Wire.requestFrom(DEVICE, num);    // request 6 bytes from device

  int i = 0;
  while (Wire.available())        // device may send less than requested (abnormal)
  {
    _buff[i] = Wire.read();       // receive a byte
    i++;
  }
  if (i != num) {
    status = ADXL345_ERROR;
    error_code = ADXL345_READ_ERROR;
  }
  X_out = ((_buff[1] << 8) | _buff[0]);
  Y_out = ((_buff[3] << 8) | _buff[2]);
  Z_out = ((_buff[5] << 8) | _buff[4]);
  Serial.print(X_out);
  Serial.print(", ");
  Serial.print(Y_out);
  Serial.print(", ");
  Serial.print(Z_out);
  Serial.println("");
}

void writeTo(byte address, byte val) {
  Wire.beginTransmission(DEVICE); // start transmission to device
  Wire.write(address);             // send register address
  Wire.write(val);                 // send value to write
  Wire.endTransmission();         // end transmission
}

}

while this code, I can detect inactivity, activity and if new data useable. If inactivity detected, it use auto sleep too.
I detect these with this lines.

if (_buff[0] & (1 << 4))
  {
    Serial.println("activty detected") ;
  }
  Wire.endTransmission();         // end transmission

  if (_buff[0] & (1 << 3))
  {
    Serial.println(" Inactivty Detected , No activty detected") ;

  }
  if ((_buff[0] & (1 << 7) && _buff[0] & (1 << 1)))
  {
    Serial.println(_buff[0]);
    readFrom(data, 6, buff);
  }

So I want to use interrupt. ADXL345 has 2 interrupt INT1 and INT2.

0x2F—INT_MAP Any bits set to 0 in this register send their respective interrupts to the INT1 pin.
So I use it like this. writeTo(INT_MAP, 0x67);

0x2E—INT_ENABLE Setting bits in this register to a value of 1 enables their respective functions to generate interrupts, whereas a value of 0 prevents the functions from generating interrupts.
So I use it like this. writeTo(INT_ENABLE, 0x98);

When I connect int1 pin to arduino's pin2, adxl345 is just not working.

I added this line on setup :

void setup()
{
.
.
.
.

  attachInterrupt(digitalPinToInterrupt(int2Pin), inactivityISR, RISING);
.
.
.

}

here is my new loop

void inactivityISR(void) {
   Serial.println("hi");
    sensor_update = 1; //DATA_READY each 20ms
}

void loop()
{
if(sensor_update==1){
     readFrom(data, 6, buff);
     sensor_update=0;//reset
    }
}

I just couldn't get this work with interrupt. Why it is not working ? I have been trying to get this thing work a lot but I couldn't success.

Why not use the ADX345 library that is supported in the IDE?

Serial is not allowed inside ISRs since interrupts are turned off. You should not have them there.

Why use a 2 byte variable? It only stores 0 or 1. Make it a byte and then you don't have to worry about accessing it outside your ISR (like in loop). The way you have it now, in loop(), you would need to disable interrupts, copy sensor_update to a temporary variable, and then re-enable interrupts since a UNO can not atomically access a 16 bit variable.

I want to learn how register communication works, so I read the datasheet and write it.

I wrote byte sensor_update = 0; this but again the code is not working.

Did the datasheet specify that the interrupt pin needs an external pull-up to work? Often times, pins like that will only pull low or float high so you need to enable the pull-up in the Uno, or supply an external one. Check the datasheet.

You can also examine the library to see how someone else implemented a working example and compare that to what you wrote. That would also qualify as learning.

Only says "Both interrupt pins are push-pull, low impedance pins with output specifications shown in Table 13. The default configura- tion of the interrupt pins is active high. ".
Screen Shot 2023-03-24 at 07.50.15
I look sparkfun's example. they use like this:

void setup()
{
//attachInterrupt(digitalPinToInterrupt(interruptPin), ADXL_ISR, RISING);   // Attach Interrupt
}
void loop(){
  
  // Accelerometer Readings
  int x,y,z;   
  adxl.readAccel(&x, &y, &z);         // Read the accelerometer values and store them in variables declared above x,y,z

  // Output Results to Serial
  /* UNCOMMENT TO VIEW X Y Z ACCELEROMETER VALUES */  
  //Serial.print(x);
  //Serial.print(", ");
  //Serial.print(y);
  //Serial.print(", ");
  //Serial.println(z); 
  
  ADXL_ISR();
  // You may also choose to avoid using interrupts and simply run the functions within ADXL_ISR(); 
  //  and place it within the loop instead.  
  // This may come in handy when it doesn't matter when the action occurs. 

}

/********************* ISR *********************/
/* Look for Interrupts and Triggered Action    */
void ADXL_ISR() {
  
  // getInterruptSource clears all triggered actions after returning value
  // Do not call again until you need to recheck for triggered actions
  byte interrupts = adxl.getInterruptSource();
  
  // Free Fall Detection
  if(adxl.triggered(interrupts, ADXL345_FREE_FALL)){
    Serial.println("*** FREE FALL ***");
    //add code here to do when free fall is sensed
  } 
  
  // Inactivity
  if(adxl.triggered(interrupts, ADXL345_INACTIVITY)){
    Serial.println("*** INACTIVITY ***");
     //add code here to do when inactivity is sensed
  }
  
  // Activity
  if(adxl.triggered(interrupts, ADXL345_ACTIVITY)){
    Serial.println("*** ACTIVITY ***"); 
     //add code here to do when activity is sensed
  }
  
  // Double Tap Detection
  if(adxl.triggered(interrupts, ADXL345_DOUBLE_TAP)){
    Serial.println("*** DOUBLE TAP ***");
     //add code here to do when a 2X tap is sensed
  }
  
  // Tap Detection
  if(adxl.triggered(interrupts, ADXL345_SINGLE_TAP)){
    Serial.println("*** TAP ***");
     //add code here to do when a tap is sensed
  } 
}

so that means they pins are driving HIGH and driven LOW so you don't need any pull-up resistors.

And does it work?

it is not working. If I use this example githublink it works. When I try to use interrupt, it is not working. This code how I try to use interrupt:

/*  ********************************************* 
 *  SparkFun_ADXL345_Example
 *  Triple Axis Accelerometer Breakout - ADXL345 
 *  Hook Up Guide Example 
 *  
 *  Utilizing Sparkfun's ADXL345 Library
 *  Bildr ADXL345 source file modified to support 
 *  both I2C and SPI Communication
 *  
 *  E.Robert @ SparkFun Electronics
 *  Created: Jul 13, 2016
 *  Updated: Sep 06, 2016
 *  
 *  Development Environment Specifics:
 *  Arduino 1.6.11
 *  
 *  Hardware Specifications:
 *  SparkFun ADXL345
 *  Arduino Uno
 *  *********************************************/

#include <SparkFun_ADXL345.h>         // SparkFun ADXL345 Library

/*********** COMMUNICATION SELECTION ***********/
/*    Comment Out The One You Are Not Using    */
ADXL345 adxl = ADXL345(10);           // USE FOR SPI COMMUNICATION, ADXL345(CS_PIN);
//ADXL345 adxl = ADXL345();             // USE FOR I2C COMMUNICATION

/****************** INTERRUPT ******************/
/*      Uncomment If Attaching Interrupt       */
//int interruptPin = 2;                 // Setup pin 2 to be the interrupt pin (for most Arduino Boards)


/******************** SETUP ********************/
/*          Configure ADXL345 Settings         */
void setup(){
  
  Serial.begin(9600);                 // Start the serial terminal
  Serial.println("SparkFun ADXL345 Accelerometer Hook Up Guide Example");
  Serial.println();
  
  adxl.powerOn();                     // Power on the ADXL345

  adxl.setRangeSetting(16);           // Give the range settings
                                      // Accepted values are 2g, 4g, 8g or 16g
                                      // Higher Values = Wider Measurement Range
                                      // Lower Values = Greater Sensitivity

  adxl.setSpiBit(0);                  // Configure the device to be in 4 wire SPI mode when set to '0' or 3 wire SPI mode when set to 1
                                      // Default: Set to 1
                                      // SPI pins on the ATMega328: 11, 12 and 13 as reference in SPI Library 
   
  adxl.setActivityXYZ(1, 0, 0);       // Set to activate movement detection in the axes "adxl.setActivityXYZ(X, Y, Z);" (1 == ON, 0 == OFF)
  adxl.setActivityThreshold(75);      // 62.5mg per increment   // Set activity   // Inactivity thresholds (0-255)
 
  adxl.setInactivityXYZ(1, 0, 0);     // Set to detect inactivity in all the axes "adxl.setInactivityXYZ(X, Y, Z);" (1 == ON, 0 == OFF)
  adxl.setInactivityThreshold(75);    // 62.5mg per increment   // Set inactivity // Inactivity thresholds (0-255)
  adxl.setTimeInactivity(10);         // How many seconds of no activity is inactive?

  adxl.setTapDetectionOnXYZ(0, 0, 1); // Detect taps in the directions turned ON "adxl.setTapDetectionOnX(X, Y, Z);" (1 == ON, 0 == OFF)
 
  // Set values for what is considered a TAP and what is a DOUBLE TAP (0-255)
  adxl.setTapThreshold(50);           // 62.5 mg per increment
  adxl.setTapDuration(15);            // 625 μs per increment
  adxl.setDoubleTapLatency(80);       // 1.25 ms per increment
  adxl.setDoubleTapWindow(200);       // 1.25 ms per increment
 
  // Set values for what is considered FREE FALL (0-255)
  adxl.setFreeFallThreshold(7);       // (5 - 9) recommended - 62.5mg per increment
  adxl.setFreeFallDuration(30);       // (20 - 70) recommended - 5ms per increment
 
  // Setting all interupts to take place on INT1 pin
  //adxl.setImportantInterruptMapping(1, 1, 1, 1, 1);     // Sets "adxl.setEveryInterruptMapping(single tap, double tap, free fall, activity, inactivity);" 
                                                        // Accepts only 1 or 2 values for pins INT1 and INT2. This chooses the pin on the ADXL345 to use for Interrupts.
                                                        // This library may have a problem using INT2 pin. Default to INT1 pin.
  
  // Turn on Interrupts for each mode (1 == ON, 0 == OFF)
  adxl.InactivityINT(1);
  adxl.ActivityINT(1);
  adxl.FreeFallINT(1);
  adxl.doubleTapINT(1);
  adxl.singleTapINT(1);
  
//attachInterrupt(digitalPinToInterrupt(interruptPin), ADXL_ISR, RISING);   // Attach Interrupt

}

/****************** MAIN CODE ******************/
/*     Accelerometer Readings and Interrupt    */
void loop(){
  
  // Accelerometer Readings
  int x,y,z;   
  adxl.readAccel(&x, &y, &z);         // Read the accelerometer values and store them in variables declared above x,y,z

  // Output Results to Serial
  /* UNCOMMENT TO VIEW X Y Z ACCELEROMETER VALUES */  
  //Serial.print(x);
  //Serial.print(", ");
  //Serial.print(y);
  //Serial.print(", ");
  //Serial.println(z); 
  
  ADXL_ISR();
  // You may also choose to avoid using interrupts and simply run the functions within ADXL_ISR(); 
  //  and place it within the loop instead.  
  // This may come in handy when it doesn't matter when the action occurs. 

}

/********************* ISR *********************/
/* Look for Interrupts and Triggered Action    */
void ADXL_ISR() {
  
  // getInterruptSource clears all triggered actions after returning value
  // Do not call again until you need to recheck for triggered actions
  byte interrupts = adxl.getInterruptSource();
  
  // Free Fall Detection
  if(adxl.triggered(interrupts, ADXL345_FREE_FALL)){
    Serial.println("*** FREE FALL ***");
    //add code here to do when free fall is sensed
  } 
  
  // Inactivity
  if(adxl.triggered(interrupts, ADXL345_INACTIVITY)){
    Serial.println("*** INACTIVITY ***");
     //add code here to do when inactivity is sensed
  }
  
  // Activity
  if(adxl.triggered(interrupts, ADXL345_ACTIVITY)){
    Serial.println("*** ACTIVITY ***"); 
     //add code here to do when activity is sensed
  }
  
  // Double Tap Detection
  if(adxl.triggered(interrupts, ADXL345_DOUBLE_TAP)){
    Serial.println("*** DOUBLE TAP ***");
     //add code here to do when a 2X tap is sensed
  }
  
  // Tap Detection
  if(adxl.triggered(interrupts, ADXL345_SINGLE_TAP)){
    Serial.println("*** TAP ***");
     //add code here to do when a tap is sensed
  } 
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.