使用ADXL345编程Arduino以在不活动时引发中断

时间:2014-03-27 23:34:44

标签: arduino accelerometer arduino-uno

我需要使用sparkfun分线板ADXL345来检测我的电机系统何时停止振动。我也在使用Sparkfun RedBoard(Arduino uno)。

我正在采取的措施来配置此行为:

  • 启用INACTIVITY事件
  • 将INACTIVITY事件路由到INT 1(RedBoard上的引脚2)
  • 立即提高INACTIVITY中断
  • 设置INACTIVITY的低阈值(排除设置太高)
  • INACTIVITY考虑所有轴
  • 清除中断数据寄存器

完成所有这些事情之后,我不会在从摇动设备到设置它之后收到中断。

//Add the SPI library so we can communicate with the ADXL345 sensor
#include <SPI.h>

//Assign the Chip Select signal to pin 10.
int CS=10;

//This is a list of some of the registers available on the ADXL345.
//To learn more about these and the rest of the registers on the ADXL345, read the datasheet!
char POWER_CTL = 0x2D;  //Power Control Register
char DATA_FORMAT = 0x31;
char DATAX0 = 0x32; //X-Axis Data 0
char DATAX1 = 0x33; //X-Axis Data 1
char DATAY0 = 0x34; //Y-Axis Data 0
char DATAY1 = 0x35; //Y-Axis Data 1
char DATAZ0 = 0x36; //Z-Axis Data 0
char DATAZ1 = 0x37; //Z-Axis Data 1

char THRESH_ACT               = 0x24; // Activity threshold
char THRESH_INACT             = 0x38; // Inactivity threshold to 3g
char TIME_INACT               = 0x26; // time before raising interrupt

char INT_ENABLE               = 0x2E; // Enabling the interrupt lines

char INT_MAP                  = 0x2F;
char ACT_INACT_CTL            = 0x27; // mask byte for controlling

char INT_SOURCE               = 0x30;

//This buffer will hold values read from the ADXL345 registers.
char values[10];
//These variables will be used to hold the x,y and z axis accelerometer values.
int x,y,z;

void setup(){ 
  //Initiate an SPI communication instance.
  SPI.begin();
  //Configure the SPI connection for the ADXL345.
  SPI.setDataMode(SPI_MODE3);
  //Create a serial connection to display the data on the terminal.
  Serial.begin(9600);

  //Set up the Chip Select pin to be an output from the Arduino.
  pinMode(CS, OUTPUT);
  //Before communication starts, the Chip Select pin needs to be set high.
  digitalWrite(CS, HIGH);

  // Create an interrupt that will trigger when inactivity is detected
  attachInterrupt(0, interruptHandler, RISING);

  //Put the ADXL345 into +/- 4G range by writing the value 0x01 to the DATA_FORMAT register.
  writeRegister(DATA_FORMAT, 0x01);
  //Put the ADXL345 into Measurement Mode by writing 0x08 to the POWER_CTL register.
  writeRegister(POWER_CTL, 0x08);  //Measurement mode

  // Send the inactivity && activity  to PIN 1
  // 0xF7 && 0xEF
  writeRegister(INT_MAP,0xF7 && 0xEF);

  // Set the inactivity threshold to 3g (0x38)
//  writeRegister(THRESH_INACT,0x38);
  writeRegister(THRESH_INACT,1);

  // Raise the inact interrupt immediately after going below threshold
  writeRegister(TIME_INACT,0);
  // Map INACT event (only) to PIN 1
  writeRegister(ACT_INACT_CTL, 0x0F);

  // Enab  le inactivity to generate interrupts
  writeRegister(INT_ENABLE, 0x08);

  readRegister(INT_SOURCE, 1, values); // Clear the INT_SOURCE register

  Serial.println("Waiting for interrupt!");
}

void interruptHandler(){
  // readRegister(INT_SOURCE, 1, values); // Clear the INT_SOURCE register
  Serial.println("something raise an interrupt!");
}

void loop(){
  //Reading 6 bytes of data starting at register DATAX0 will retrieve the x,y and z acceleration values from the ADXL345.
  //The results of the read operation will get stored to the values[] buffer.
  readRegister(DATAX0, 6, values);

  //The ADXL345 gives 10-bit acceleration values, but they are stored as bytes (8-bits). To get the full value, two bytes must be combined for each axis.
  //The X value is stored in values[0] and values[1].
  x = ((int)values[1]<<8)|(int)values[0];
  //The Y value is stored in values[2] and values[3].
  y = ((int)values[3]<<8)|(int)values[2];
  //The Z value is stored in values[4] and values[5].
  z = ((int)values[5]<<8)|(int)values[4];

  //Print the results to the terminal.
  Serial.print(x, DEC);
  Serial.print(',');
  Serial.print(y, DEC);
  Serial.print(',');
  Serial.println(z, DEC);      
  delay(500); 
}

//This function will write a value to a register on the ADXL345.
//Parameters:
//  char registerAddress - The register to write a value to
//  char value - The value to be written to the specified register.
void writeRegister(char registerAddress, char value){
  //Set Chip Select pin low to signal the beginning of an SPI packet.
  digitalWrite(CS, LOW);
  //Transfer the register address over SPI.
  SPI.transfer(registerAddress);
  //Transfer the desired register value over SPI.
  SPI.transfer(value);
  //Set the Chip Select pin high to signal the end of an SPI packet.
  digitalWrite(CS, HIGH);
}

//This function will read a certain number of registers starting from a specified address and store their values in a buffer.
//Parameters:
//  char registerAddress - The register addresse to start the read sequence from.
//  int numBytes - The number of registers that should be read.
//  char * values - A pointer to a buffer where the results of the operation should be stored.
void readRegister(char registerAddress, int numBytes, char * values){
  //Since we're performing a read operation, the most significant bit of the register address should be set.
  char address = 0x80 | registerAddress;
  //If we're doing a multi-byte read, bit 6 needs to be set as well.
  if(numBytes > 1)address = address | 0x40;

  //Set the Chip select pin low to start an SPI packet.
  digitalWrite(CS, LOW);
  //Transfer the starting register address that needs to be read.
  SPI.transfer(address);
  //Continue to read registers until we've read the number specified, storing the results to the input buffer.
  for(int i=0; i<numBytes; i++){
    values[i] = SPI.transfer(0x00);
  }
  //Set the Chips Select pin high to end the SPI packet.
  digitalWrite(CS, HIGH);
}

1 个答案:

答案 0 :(得分:0)

Here是一个教程,arduino库和示例草图。如果你没有经历过这样的事情,那么从别人的代码开始工作可能是值得一试的(也许你已经做过了)。

在上面的示例草图中,它们启用了代码中的中断,它们似乎并没有将它们绑定到Arduino的外部中断系统中。一旦验证了示例代码是否正常工作,就可以调用attachInterrupt()并放弃轮询方法(正如您在示例中所做的那样)。