Go Down

Topic: ADXL345 Arduino UNO Activity Inactivity interrupt (Read 156 times) previous topic - next topic

Skyland

I have DATA_READY, Activity and Inactivity interrupts mapped from INT1 to INT0 on the arduino. DATA_READY works fine, the problem is Activity and Inactivity are always set to 0 in the INT_SOURCE register. I have set up the threshold for activity and inactivity and the time of inactivity. I would like the algorithm to run when DATA_READY and Activity interrupts are 1 and do nothing when Inactivity is 1 (activity is 0). When Activity is 0 the accelerometer should go automatically in sleep mode and wakes up if activity is detected.

Code: [Select]

    #include <Wire.h>
    #include <Adafruit_Sensor.h>
    #include <Adafruit_ADXL345_U.h>
    #include <avr/io.h>
    #include <avr/power.h>


    #define F_CPU 16000000UL



    int state=0; //0--active detecting; 1--sleeping
    int state_count=0; //sleeping trigger between 2 states
    double mag[40];
    int i=0;
    double acc_rate[39];
    int hunt_sub=0;
    int exit_marker=-10,trough_marker=-30,peak_marker=-10;
    volatile int sensor_update=0, active_mode=0;//active_mode=0, inactive; 1--active;      sensor_update=0, no new data; 1--new data comes
    byte buff[1] ;


    volatile unsigned long time=0, time0=0,time_dis=0,time_array[40]={0};

    //----------------------------------------------------------------------------------------------

    //Read ADXL345 registers
    void readFrom(int device, byte address, int num, byte buff[]) {
    Wire.beginTransmission(device); //start transmission to device
    Wire.write(address);        //sends address to read from
    Wire.endTransmission(); //end transmission
 
    Wire.beginTransmission(device); //start transmission to device (initiate again)
    Wire.requestFrom(device, num);    // request 1 byte from device
 
    int i = 0;
    while(Wire.available())    //device may send less than requested (abnormal)
    {
    buff[i] = Wire.read(); // receive a byte
    i++;
    }
    Wire.endTransmission(); //end transmission
    }

    //Write to ADXL345 registers
    void writeTo(int device, 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
    }



    //----------------------------------------------------------------------------------------------

    /////////////////////////////////////////////////////////////////////////////////////////////

    //ISR function
 


    void interrupt(void){
   
    readFrom(0x53, 0x30, 1, buff);
   
    if(buff & 0b00010000){
      active_mode=1;//active state
    }
    if(buff & 0b00001000){
      active_mode=0;//inactivity state
    }
   
    if(buff & 0b10000000){
    sensor_update=1;//DATA_READY each 10ms 
    }
   
    }
 



    /* Assign a unique ID to this sensor at the same time */
    Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345);





    void setup(void)
    {
    if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
    Serial.begin(9600);
    //Serial.println("Accelerometer Test"); Serial.println("");

    pinMode(4, OUTPUT);// buzzer output pin
    pinMode(2, INPUT);
   
    /* Initialise the sensor */
    if(!accel.begin())
    {
    /* There was a problem detecting the ADXL345 ... check your connections */
    //Serial.println("Ooops, no ADXL345 detected ... Check your wiring!");
    while(1);
    }

    /* Set the range to whatever is appropriate for your project */
    accel.setRange(ADXL345_RANGE_8_G);
    accel.setDataRate(ADXL345_DATARATE_100_HZ);
    // displaySetRange(ADXL345_RANGE_8_G);
    // displaySetRange(ADXL345_RANGE_4_G);
    // displaySetRange(ADXL345_RANGE_2_G);
 
    /* Display some basic information on this sensor */
    //displaySensorDetails();
 
    /* Display additional settings (outside the scope of sensor_t) */
    //displayDataRate();
    //displayRange();
    //Serial.println("");
 
    //Create an interrupt that will trigger when a tap is detected.
 
    writeTo(0x53, 0x2D, 59);//POWER_CTL  auto sleep, link, 1hz rate
    writeTo(0x53, 0x2C, 10);//BW_RATE low power mode off rate 100Hz
    writeTo(0x53, 0x2E, 0);// disable interrupt
 
    attachInterrupt(0, interrupt, RISING);
 
    writeTo(0x53, 0x2F, 0); //map to to INT1
    writeTo(0x53, 0x2E, 152); //enable data_ready, activity, inactivity
    writeTo(0x53, 0x25, 18); //THRESH_INACT  ((11/9.8)*1000)/62.5
    writeTo(0x53, 0x26, 60); //TIME_INACT    one minute
    writeTo(0x53, 0x24, 21); //THRESH_ACT    ((13/9.8)*1000)/62.5
    writeTo(0x53, 0x27, 0); //ACT_INACT_CTL   dc coupled, use only magnitude.
 

    }

    void loop(void)
    {
 
    readFrom(0x53, 0x30, 1, buff);
    Serial.print("buff: "); Serial.print(buff); Serial.print("  ");
 
    sensors_event_t event;
    do{ //clear DATA_READY
    accel.getEvent(&event);
    readFrom(0x53, 0x30, 1, buff);
    }while(buff & 0b10000000);
   
   
 
 
    if(sensor_update==1 && active_mode==1){
    //When sensor_update is set to 1 in the ISR,the algorithm process the data from the accelerometer being updated every 10ms(100Hz)
    //rest of algorithm is here
     sensor_update=0;//reset
     
     
     
    }
 

    }

Skyland



Edit:

I have modified the program to check in the loop whether the different flags are set and only the DATA_READY is. Activity and Inactivity are never set.

Code: [Select]

    #include <Wire.h>
    #include <Adafruit_Sensor.h>
    #include <Adafruit_ADXL345_U.h>
    #include <avr/io.h>
    #include <avr/power.h>


    #define F_CPU 16000000UL



    int state=0; //0--active detecting; 1--sleeping
    int state_count=0; //sleeping trigger between 2 states
    double mag[40];
    int i=0;
    double acc_rate[39];
    int hunt_sub=0;
    int exit_marker=-10,trough_marker=-30,peak_marker=-10;
    volatile int sensor_update=0, active_mode=0;//active_mode=0, inactive; 1--active;     sensor_update=0, no new data; 1--new data comes
    byte buff[1] ;


    volatile unsigned long time=0, time0=0,time_dis=0,time_array[40]={0};

    //----------------------------------------------------------------------------------------------

    //Read ADXL345 registers
    void readFrom(int device, byte address, int num, byte buff[]) {
    Wire.beginTransmission(device); //start transmission to device
    Wire.write(address);        //sends address to read from
    Wire.endTransmission(); //end transmission
 
    Wire.beginTransmission(device); //start transmission to device (initiate again)
    Wire.requestFrom(device, num);    // request 1 byte from device
 
    int i = 0;
    while(Wire.available())    //device may send less than requested (abnormal)
    {
    buff[i] = Wire.read(); // receive a byte
    i++;
    }
    Wire.endTransmission(); //end transmission
    }

    //Write to ADXL345 registers
    void writeTo(int device, 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
    }



    //----------------------------------------------------------------------------------------------

    /////////////////////////////////////////////////////////////////////////////////////////////

    //ISR function
 


    void interrupt(void){
   
   
    //   
    //    if(buff & 0b00010000){
    //      active_mode=1;//active state
    //    }
    //    if(buff & 0b00001000){
    //      active_mode=0;//inactivity state
    //    }
    //   
    //    if(buff & 0b10000000){
    //    sensor_update=1;//DATA_READY each 10ms 
    //    }
   
    }
 



    /* Assign a unique ID to this sensor at the same time */
    Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345);





    void setup(void)
    {
    if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
    Serial.begin(9600);
    //Serial.println("Accelerometer Test"); Serial.println("");

    pinMode(4, OUTPUT);// buzzer output pin
    pinMode(2, INPUT);
 
    /* Initialise the sensor */
    if(!accel.begin())
    {
    /* There was a problem detecting the ADXL345 ... check your connections */
    //Serial.println("Ooops, no ADXL345 detected ... Check your wiring!");
    while(1);
    }

    /* Set the range to whatever is appropriate for your project */
    accel.setRange(ADXL345_RANGE_8_G);
    accel.setDataRate(ADXL345_DATARATE_100_HZ);
 
    //Create an interrupt that will trigger when a tap is detected.
 

      writeTo(0x53, 0x2D, 59);//POWER_CTL  auto sleep, link, 1hz rate
      writeTo(0x53, 0x2C, 10);//BW_RATE low power mode off rate 100Hz
      writeTo(0x53, 0x2E, 0);// disable interrupt
 
      attachInterrupt(0, interrupt, RISING);
 
      writeTo(0x53, 0x2F, 0); //map to to INT1
      writeTo(0x53, 0x2E, 152); //enable data_ready, activity, inactivity
      // writeTo(0x53, 0x25, 18); //THRESH_INACT  ((11/9.8)*1000)/62.5
      writeTo(0x53, 0x27, 119); //ACT_INACT_CTL   dc coupled, use only magnitude.
      writeTo(0x53, 0x25, 5); //THRESH_INACT  ((3.0625/9.8)*1000)/62.5
      writeTo(0x53, 0x26, 1); //TIME_INACT    one minute
      writeTo(0x53, 0x24, 21); //THRESH_ACT    ((12.8625/9.8)*1000)/62.5

      }

      void loop(void)
      {
 
      if(digitalRead(2)) {

      readFrom(0x53, 0x30, 1, buff);

      //Serial.print("### ");
 
      //Serial.println(interruptSource, BIN);
 
   
      if(buff[0] & 0b10000000) {

      Serial.println("### DATA_READY");

      }
   

      if(buff[0] & 0b00001000) {

      Serial.println("### Inacitivity");

      }

      if(buff[0] & 0b00010000) {

      Serial.println("### activity");

      // we don't need to put the device in sleep because we set the AUTO_SLEEP bit to 1 in R_POWER_CTL

      // set the LOW_POWER bit to 1 in R_BW_RATE: with this we get worst measurements but we save power

    }


    delay(150);

    }

 
    sensors_event_t event;
    do{ //clear DATA_READY
    accel.getEvent(&event);
    readFrom(0x53, 0x30, 1, buff);
    }while(buff & 0b10000000);
   
   
 
 
    if(sensor_update==1 && active_mode==1){
    //When sensor_update is set to 1 in the ISR,the algorithm process the data from the accelerometer being updated every 10ms(100Hz)
    //rest of algorithm is here
     sensor_update=0;//reset
     
     
     
    }
 

    }

Go Up