ADXL345 Arduino UNO Activity Inactivity interrupt - Page 1
Forum section: electronics / general

author: Skyland
author_rank: Contributor
timestamp: February 22, 2015, 09:46:36 pm
content: 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:#include <Wire.h>#include <Adafruit_Sensor.h>#include <Adafruit_ADXL345_U.h>#include <avr/io.h>#include <avr/power.h>#define F_CPU 16000000ULint state=0; //0--active detecting; 1--sleepingint state_count=0; //sleeping trigger between 2 statesdouble mag;int i=0;double acc_rate;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 comesbyte buff ;volatile unsigned long time=0, time0=0,time_dis=0,time_array={0};//----------------------------------------------------------------------------------------------//Read ADXL345 registersvoid readFrom(int device, byte address, int num, byte buff[]) {Wire.beginTransmission(device); //start transmission to deviceWire.write(address); //sends address to read fromWire.endTransmission(); //end transmissionWire.beginTransmission(device); //start transmission to device (initiate again)Wire.requestFrom(device, num); // request 1 byte from deviceint i = 0;while(Wire.available()) //device may send less than requested (abnormal){buff = Wire.read(); // receive a bytei++;}Wire.endTransmission(); //end transmission}//Write to ADXL345 registersvoid writeTo(int device, byte address, byte val) {Wire.beginTransmission(device); //start transmission to deviceWire.write(address); // send register addressWire.write(val); // send value to writeWire.endTransmission(); //end transmission}//----------------------------------------------------------------------------------------------///////////////////////////////////////////////////////////////////////////////////////////////ISR functionvoid 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 pinpinMode(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 ratewriteTo(0x53, 0x2C, 10);//BW_RATE low power mode off rate 100HzwriteTo(0x53, 0x2E, 0);// disable interruptattachInterrupt(0, interrupt, RISING);writeTo(0x53, 0x2F, 0); //map to to INT1writeTo(0x53, 0x2E, 152); //enable data_ready, activity, inactivitywriteTo(0x53, 0x25, 18); //THRESH_INACT ((11/9.8)*1000)/62.5writeTo(0x53, 0x26, 60); //TIME_INACT one minutewriteTo(0x53, 0x24, 21); //THRESH_ACT ((13/9.8)*1000)/62.5writeTo(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_READYaccel.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 heresensor_update=0;//reset}}

author: Skyland
author_rank: Contributor
timestamp: February 23, 2015, 09:07:14 pm
content: 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:#include <Wire.h>#include <Adafruit_Sensor.h>#include <Adafruit_ADXL345_U.h>#include <avr/io.h>#include <avr/power.h>#define F_CPU 16000000ULint state=0; //0--active detecting; 1--sleepingint state_count=0; //sleeping trigger between 2 statesdouble mag;int i=0;double acc_rate;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 comesbyte buff ;volatile unsigned long time=0, time0=0,time_dis=0,time_array={0};//----------------------------------------------------------------------------------------------//Read ADXL345 registersvoid readFrom(int device, byte address, int num, byte buff[]) {Wire.beginTransmission(device); //start transmission to deviceWire.write(address); //sends address to read fromWire.endTransmission(); //end transmissionWire.beginTransmission(device); //start transmission to device (initiate again)Wire.requestFrom(device, num); // request 1 byte from deviceint i = 0;while(Wire.available()) //device may send less than requested (abnormal){buff = Wire.read(); // receive a bytei++;}Wire.endTransmission(); //end transmission}//Write to ADXL345 registersvoid writeTo(int device, byte address, byte val) {Wire.beginTransmission(device); //start transmission to deviceWire.write(address); // send register addressWire.write(val); // send value to writeWire.endTransmission(); //end transmission}//----------------------------------------------------------------------------------------------///////////////////////////////////////////////////////////////////////////////////////////////ISR functionvoid 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 pinpinMode(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 ratewriteTo(0x53, 0x2C, 10);//BW_RATE low power mode off rate 100HzwriteTo(0x53, 0x2E, 0);// disable interruptattachInterrupt(0, interrupt, RISING);writeTo(0x53, 0x2F, 0); //map to to INT1writeTo(0x53, 0x2E, 152); //enable data_ready, activity, inactivity// writeTo(0x53, 0x25, 18); //THRESH_INACT ((11/9.8)*1000)/62.5writeTo(0x53, 0x27, 119); //ACT_INACT_CTL dc coupled, use only magnitude.writeTo(0x53, 0x25, 5); //THRESH_INACT ((3.0625/9.8)*1000)/62.5writeTo(0x53, 0x26, 1); //TIME_INACT one minutewriteTo(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 & 0b10000000) {Serial.println("### DATA_READY");}if(buff & 0b00001000) {Serial.println("### Inacitivity");}if(buff & 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_READYaccel.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 heresensor_update=0;//reset}}