ADXL345 sleep mode

Discussion in 'Embedded Systems and Microcontrollers' started by Skyland, Feb 23, 2015.

  1. Skyland

    Thread Starter New Member

    Jul 1, 2014
    28
    0
    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 (Text):
    1.  
    2.     #include <Wire.h>
    3.     #include <Adafruit_Sensor.h>
    4.     #include <Adafruit_ADXL345_U.h>
    5.     #include <avr/io.h>
    6.     #include <avr/power.h>
    7.  
    8.  
    9.     #define F_CPU 16000000UL
    10.  
    11.  
    12.  
    13.     int state=0; //0--active detecting; 1--sleeping
    14.     int state_count=0; //sleeping trigger between 2 states
    15.     double mag[40];
    16.     int i=0;
    17.     double acc_rate[39];
    18.     int hunt_sub=0;
    19.     int exit_marker=-10,trough_marker=-30,peak_marker=-10;
    20.     volatile int sensor_update=0, active_mode=0;//active_mode=0, inactive; 1--active;      sensor_update=0, no new data; 1--new data comes
    21.     byte buff[1] ;
    22.  
    23.  
    24.     volatile unsigned long time=0, time0=0,time_dis=0,time_array[40]={0};
    25.  
    26.     //----------------------------------------------------------------------------------------------
    27.  
    28.     //Read ADXL345 registers
    29.     void readFrom(int device, byte address, int num, byte buff[]) {
    30.     Wire.beginTransmission(device); //start transmission to device
    31.     Wire.write(address);        //sends address to read from
    32.     Wire.endTransmission(); //end transmission
    33.     Wire.beginTransmission(device); //start transmission to device (initiate again)
    34.     Wire.requestFrom(device, num);    // request 1 byte from device
    35.     int i = 0;
    36.     while(Wire.available())    //device may send less than requested (abnormal)
    37.     {
    38.     buff[i] = Wire.read(); // receive a byte
    39.     i++;
    40.     }
    41.     Wire.endTransmission(); //end transmission
    42.     }
    43.  
    44.     //Write to ADXL345 registers
    45.     void writeTo(int device, byte address, byte val) {
    46.     Wire.beginTransmission(device); //start transmission to device
    47.     Wire.write(address);        // send register address
    48.     Wire.write(val);        // send value to write
    49.     Wire.endTransmission(); //end transmission
    50.     }
    51.  
    52.  
    53.  
    54.     //----------------------------------------------------------------------------------------------
    55.  
    56.     /////////////////////////////////////////////////////////////////////////////////////////////
    57.  
    58.     //ISR function
    59.  
    60.  
    61.     void interrupt(void){
    62.    
    63.     readFrom(0x53, 0x30, 1, buff);
    64.    
    65.     if(buff & 0b00010000){
    66.       active_mode=1;//active state
    67.     }
    68.     if(buff & 0b00001000){
    69.       active_mode=0;//inactivity state
    70.     }
    71.    
    72.     if(buff & 0b10000000){
    73.     sensor_update=1;//DATA_READY each 10ms  
    74.     }
    75.    
    76.     }
    77.  
    78.  
    79.  
    80.     /* Assign a unique ID to this sensor at the same time */
    81.     Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345);
    82.  
    83.  
    84.  
    85.  
    86.  
    87.     void setup(void)
    88.     {
    89.     if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
    90.     Serial.begin(9600);
    91.     //Serial.println("Accelerometer Test"); Serial.println("");
    92.  
    93.     pinMode(4, OUTPUT);// buzzer output pin
    94.     pinMode(2, INPUT);
    95.    
    96.     /* Initialise the sensor */
    97.     if(!accel.begin())
    98.     {
    99.     /* There was a problem detecting the ADXL345 ... check your connections */
    100.     //Serial.println("Ooops, no ADXL345 detected ... Check your wiring!");
    101.     while(1);
    102.     }
    103.  
    104.     /* Set the range to whatever is appropriate for your project */
    105.     accel.setRange(ADXL345_RANGE_8_G);
    106.     accel.setDataRate(ADXL345_DATARATE_100_HZ);
    107.     // displaySetRange(ADXL345_RANGE_8_G);
    108.     // displaySetRange(ADXL345_RANGE_4_G);
    109.     // displaySetRange(ADXL345_RANGE_2_G);
    110.     /* Display some basic information on this sensor */
    111.     //displaySensorDetails();
    112.     /* Display additional settings (outside the scope of sensor_t) */
    113.     //displayDataRate();
    114.     //displayRange();
    115.     //Serial.println("");
    116.     //Create an interrupt that will trigger when a tap is detected.
    117.     writeTo(0x53, 0x2D, 59);//POWER_CTL  auto sleep, link, 1hz rate
    118.     writeTo(0x53, 0x2C, 10);//BW_RATE low power mode off rate 100Hz
    119.     writeTo(0x53, 0x2E, 0);// disable interrupt
    120.     attachInterrupt(0, interrupt, RISING);
    121.     writeTo(0x53, 0x2F, 0); //map to to INT1
    122.     writeTo(0x53, 0x2E, 152); //enable data_ready, activity, inactivity
    123.     writeTo(0x53, 0x25, 18); //THRESH_INACT  ((11/9.8)*1000)/62.5
    124.     writeTo(0x53, 0x26, 60); //TIME_INACT    one minute
    125.     writeTo(0x53, 0x24, 21); //THRESH_ACT    ((13/9.8)*1000)/62.5
    126.     writeTo(0x53, 0x27, 0); //ACT_INACT_CTL   dc coupled, use only magnitude.
    127.  
    128.     }
    129.  
    130.     void loop(void)
    131.     {
    132.     readFrom(0x53, 0x30, 1, buff);
    133.     Serial.print("buff: "); Serial.print(buff); Serial.print("  ");
    134.     sensors_event_t event;
    135.     do{ //clear DATA_READY
    136.     accel.getEvent(&event);
    137.     readFrom(0x53, 0x30, 1, buff);
    138.     }while(buff & 0b10000000);
    139.    
    140.    
    141.     if(sensor_update==1 && active_mode==1){
    142.     //When sensor_update is set to 1 in the ISR,the algorithm process the data from the accelerometer being updated every 10ms(100Hz)
    143.     //rest of algorithm is here
    144.      sensor_update=0;//reset
    145.      
    146.      
    147.      
    148.     }
    149.  
    150.     }
    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 (Text):
    1. #include <Wire.h>
    2. #include <Adafruit_Sensor.h>
    3. #include <Adafruit_ADXL345_U.h>
    4. #include <avr/io.h>
    5. #include <avr/power.h>
    6.  
    7.  
    8. #define F_CPU 16000000UL
    9.  
    10.  
    11.  
    12. int state=0; //0--active detecting; 1--sleeping
    13. int state_count=0; //sleeping trigger between 2 states
    14. double mag[40];
    15. int i=0;
    16. double acc_rate[39];
    17. int hunt_sub=0;
    18. int exit_marker=-10,trough_marker=-30,peak_marker=-10;
    19. volatile int sensor_update=0, active_mode=0;//active_mode=0, inactive; 1--active; sensor_update=0, no new data; 1--new data comes
    20. byte buff[1] ;
    21.  
    22.  
    23. volatile unsigned long time=0, time0=0,time_dis=0,time_array[40]={0};
    24.  
    25. //----------------------------------------------------------------------------------------------
    26.  
    27. //Read ADXL345 registers
    28. void readFrom(int device, byte address, int num, byte buff[]) {
    29.   Wire.beginTransmission(device); //start transmission to device
    30.   Wire.write(address);        //sends address to read from
    31.   Wire.endTransmission(); //end transmission
    32.   Wire.beginTransmission(device); //start transmission to device (initiate again)
    33.   Wire.requestFrom(device, num);    // request 1 byte from device
    34.   int i = 0;
    35.   while(Wire.available())    //device may send less than requested (abnormal)
    36.   {
    37.     buff[i] = Wire.read(); // receive a byte
    38.     i++;
    39.   }
    40.   Wire.endTransmission(); //end transmission
    41. }
    42.  
    43. //Write to ADXL345 registers
    44. void writeTo(int device, byte address, byte val) {
    45.    Wire.beginTransmission(device); //start transmission to device
    46.    Wire.write(address);        // send register address
    47.    Wire.write(val);        // send value to write
    48.    Wire.endTransmission(); //end transmission
    49. }
    50.  
    51.  
    52.  
    53. //----------------------------------------------------------------------------------------------
    54.  
    55. /////////////////////////////////////////////////////////////////////////////////////////////
    56.  
    57. //ISR function
    58.  
    59.  
    60.   void interrupt(void){
    61.    
    62.    
    63. //    
    64. //    if(buff & 0b00010000){
    65. //      active_mode=1;//active state
    66. //    }
    67. //    if(buff & 0b00001000){
    68. //      active_mode=0;//inactivity state
    69. //    }
    70. //    
    71. //    if(buff & 0b10000000){
    72. //    sensor_update=1;//DATA_READY each 10ms  
    73. //    }
    74.    
    75.   }
    76.  
    77.  
    78.  
    79. /* Assign a unique ID to this sensor at the same time */
    80. Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345);
    81.  
    82.  
    83.  
    84.  
    85.  
    86. void setup(void)
    87. {
    88.   if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
    89.   Serial.begin(9600);
    90.   //Serial.println("Accelerometer Test"); Serial.println("");
    91.  
    92.   pinMode(4, OUTPUT);// buzzer output pin
    93.   pinMode(2, INPUT);
    94.   /* Initialise the sensor */
    95.   if(!accel.begin())
    96.   {
    97.     /* There was a problem detecting the ADXL345 ... check your connections */
    98.     //Serial.println("Ooops, no ADXL345 detected ... Check your wiring!");
    99.     while(1);
    100.   }
    101.  
    102.   /* Set the range to whatever is appropriate for your project */
    103.   accel.setRange(ADXL345_RANGE_8_G);
    104.   accel.setDataRate(ADXL345_DATARATE_100_HZ);
    105.   // displaySetRange(ADXL345_RANGE_8_G);
    106.   // displaySetRange(ADXL345_RANGE_4_G);
    107.   // displaySetRange(ADXL345_RANGE_2_G);
    108.   /* Display some basic information on this sensor */
    109.   //displaySensorDetails();
    110.   /* Display additional settings (outside the scope of sensor_t) */
    111.   //displayDataRate();
    112.   //displayRange();
    113.   //Serial.println("");
    114.   //Create an interrupt that will trigger when a tap is detected.
    115.  
    116.   writeTo(0x53, 0x2D, 59);//POWER_CTL  auto sleep, link, 1hz rate
    117.   writeTo(0x53, 0x2C, 10);//BW_RATE low power mode off rate 100Hz
    118.   writeTo(0x53, 0x2E, 0);// disable interrupt
    119.   attachInterrupt(0, interrupt, RISING);
    120.   writeTo(0x53, 0x2F, 0); //map to to INT1
    121.   writeTo(0x53, 0x2E, 152); //enable data_ready, activity, inactivity
    122.  // writeTo(0x53, 0x25, 18); //THRESH_INACT  ((11/9.8)*1000)/62.5
    123.   writeTo(0x53, 0x27, 119); //ACT_INACT_CTL   dc coupled, use only magnitude.
    124.   writeTo(0x53, 0x25, 5); //THRESH_INACT  ((3.0625/9.8)*1000)/62.5
    125.   writeTo(0x53, 0x26, 1); //TIME_INACT    one minute
    126.   writeTo(0x53, 0x24, 21); //THRESH_ACT    ((12.8625/9.8)*1000)/62.5
    127.  
    128. }
    129.  
    130. void loop(void)
    131. {
    132.   if(digitalRead(2)) {
    133.  
    134.     readFrom(0x53, 0x30, 1, buff);
    135.  
    136.     //Serial.print("### ");
    137.  
    138.     //Serial.println(interruptSource, BIN);
    139.  
    140.    
    141.     if(buff[0] & 0b10000000) {
    142.  
    143.       Serial.println("### DATA_READY");
    144.  
    145.     }
    146.    
    147.  
    148.     if(buff[0] & 0b00001000) {
    149.  
    150.       Serial.println("### Inacitivity");
    151.  
    152.     }
    153.  
    154.     if(buff[0] & 0b00010000) {
    155.  
    156.       Serial.println("### activity");
    157.  
    158.       // we don't need to put the device in sleep because we set the AUTO_SLEEP bit to 1 in R_POWER_CTL
    159.  
    160.       // set the LOW_POWER bit to 1 in R_BW_RATE: with this we get worst measurements but we save power
    161.  
    162.     }
    163.  
    164.  
    165.     delay(150);
    166.  
    167.   }
    168.  
    169.   sensors_event_t event;
    170.   do{ //clear DATA_READY
    171.     accel.getEvent(&event);
    172.     readFrom(0x53, 0x30, 1, buff);
    173.     }while(buff & 0b10000000);
    174.    
    175.    
    176.   if(sensor_update==1 && active_mode==1){
    177.     //When sensor_update is set to 1 in the ISR,the algorithm process the data from the accelerometer being updated every 10ms(100Hz)
    178.     //rest of algorithm is here
    179.      sensor_update=0;//reset
    180.      
    181.      
    182.      
    183.   }
    184.  
    185. }
    186.  
     
  2. Skyland

    Thread Starter New Member

    Jul 1, 2014
    28
    0
    from the datasheet apparently reading the INT_SOURCE registers clears the Activity and Inactivity flags, in that case it would be normal to read o for them. As an alternative, I mapped the activity interrupt from INT2 of ADXL to INT1 of the arduino. active_mode=1 inside the second interrupt function, the first is for data_ready where sensor_update is set to 1. Even with this sensor_update and active_mode always reads 0. Confusing!
     
Loading...