Go Down

Topic: FFT analysis for ADXL345 (Read 334 times) previous topic - next topic

reva23

Hello All,

I want to use ADXL345 to measure spindle vibration. so far I interfaced Arduino & ADXL345 with I2C communication. I loaded available adafruit code to the arduino and tested the sensor. It seems to be working fine.

This is the code:

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_ADXL345_U.h>

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

void displaySensorDetails(void)
{
  sensor_t sensor;
  accel.getSensor(&sensor);
  Serial.println("------------------------------------");
  Serial.print  ("Sensor:       "); Serial.println(sensor.name);
  Serial.print  ("Driver Ver:   "); Serial.println(sensor.version);
  Serial.print  ("Unique ID:    "); Serial.println(sensor.sensor_id);
  Serial.print  ("Max Value:    "); Serial.print(sensor.max_value); Serial.println(" m/s^2");
  Serial.print  ("Min Value:    "); Serial.print(sensor.min_value); Serial.println(" m/s^2");
  Serial.print  ("Resolution:   "); Serial.print(sensor.resolution); Serial.println(" m/s^2"); 
  Serial.println("------------------------------------");
  Serial.println("");
  delay(500);
}

void displayDataRate(void)
{
  Serial.print  ("Data Rate:    ");
 
  switch(accel.getDataRate())
  {
    case ADXL345_DATARATE_3200_HZ:
      Serial.print  ("3200 ");
      break;
    case ADXL345_DATARATE_1600_HZ:
      Serial.print  ("1600 ");
      break;
    case ADXL345_DATARATE_800_HZ:
      Serial.print  ("800 ");
      break;
    case ADXL345_DATARATE_400_HZ:
      Serial.print  ("400 ");
      break;
    case ADXL345_DATARATE_200_HZ:
      Serial.print  ("200 ");
      break;
    case ADXL345_DATARATE_100_HZ:
      Serial.print  ("100 ");
      break;
    case ADXL345_DATARATE_50_HZ:
      Serial.print  ("50 ");
      break;
    case ADXL345_DATARATE_25_HZ:
      Serial.print  ("25 ");
      break;
    case ADXL345_DATARATE_12_5_HZ:
      Serial.print  ("12.5 ");
      break;
    case ADXL345_DATARATE_6_25HZ:
      Serial.print  ("6.25 ");
      break;
    case ADXL345_DATARATE_3_13_HZ:
      Serial.print  ("3.13 ");
      break;
    case ADXL345_DATARATE_1_56_HZ:
      Serial.print  ("1.56 ");
      break;
    case ADXL345_DATARATE_0_78_HZ:
      Serial.print  ("0.78 ");
      break;
    case ADXL345_DATARATE_0_39_HZ:
      Serial.print  ("0.39 ");
      break;
    case ADXL345_DATARATE_0_20_HZ:
      Serial.print  ("0.20 ");
      break;
    case ADXL345_DATARATE_0_10_HZ:
      Serial.print  ("0.10 ");
      break;
    default:
      Serial.print  ("???? ");
      break;
  } 
  Serial.println(" Hz"); 
}

void displayRange(void)
{
  Serial.print  ("Range:         +/- ");
 
  switch(accel.getRange())
  {
    case ADXL345_RANGE_16_G:
      Serial.print  ("16 ");
      break;
    case ADXL345_RANGE_8_G:
      Serial.print  ("8 ");
      break;
    case ADXL345_RANGE_4_G:
      Serial.print  ("4 ");
      break;
    case ADXL345_RANGE_2_G:
      Serial.print  ("2 ");
      break;
    default:
      Serial.print  ("?? ");
      break;
  } 
  Serial.println(" g"); 
}

void setup(void)
{
#ifndef ESP8266
  while (!Serial); // for Leonardo/Micro/Zero
#endif
  Serial.begin(9600);
  Serial.println("Accelerometer Test"); Serial.println("");
 
  /* 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_16_G);
  // accel.setRange(ADXL345_RANGE_8_G);
  // accel.setRange(ADXL345_RANGE_4_G);
  // accel.setRange(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("");
}

void loop(void)
{
  /* Get a new sensor event */
  sensors_event_t event;
  accel.getEvent(&event);
 
  /* Display the results (acceleration is measured in m/s^2) */
  Serial.print("X: "); Serial.print(event.acceleration.x); Serial.print("  ");
  Serial.print("Y: "); Serial.print(event.acceleration.y); Serial.print("  ");
  Serial.print("Z: "); Serial.print(event.acceleration.z); Serial.print("  ");Serial.println("m/s^2 ");
  delay(500);
}

As I move or vibrate the sensor, the output changes. Is there anyway to apply FFT to sensor output. I searched related to this but no luck. Pls help me out for applying FFT.

Thanks in advance. :)  :)  :)

jremington

Please edit your post to add code tags, as described in "How to use this forum".

harithota20

Hello Reva23,

Code: [Select]
#include <SPI.h>
#include <ESP8266WiFi.h>

//ADXL345
#define BW_RATE 0x2C //Data rate and power mode control
#define POWER_CTL 0x2D //Power Control Register
#define DATA_FORMAT 0x31 //Data format control
#define DATAX0 0x32 //X-Axis Data 0


//Nodemcu pin D5 GPIO 14 -----> pin SCL ADXL345
//Nodemcu pin D6 GPIO 12 -----> pin SDO ADXL345
//Nodemcu pin D7 GPIO 13 -----> pin SDA ADXL345
//Nodemcu pin D8 GPIO 15 -----> pin CS ADXL345
//Nodemcu pin 3.3 -----> pin VCC ADXL345
//Nodemcu pin GND -----> pin GND ADXL345

#define SS 15 //(IO15 -> IO5)

char values[10];
int16_t x, y, z;
float xg, yg, zg;

void setup() {
SPI.begin();
SPI.setDataMode(SPI_MODE2);
SPI.setBitOrder(MSBFIRST);
SPI.setFrequency(1000000);
//SPI.setClockDivider(SPI_CLOCK_DIV16);


Serial.begin(250000);

// SS Hight
pinMode(SS, OUTPUT);
digitalWrite(SS, HIGH);

// ADXL345
writeRegister(DATA_FORMAT, 0x03); // ±16g 10bit
writeRegister(POWER_CTL, 0x08); //
writeRegister(BW_RATE, 0x0F); //
}

void loop() {
// DATAX0
readRegister(DATAX0, 6, values);

// 2Byte
x = ((int16_t)values[1] << 8) | (int16_t)values[0];
y = ((int16_t)values[3] << 8) | (int16_t)values[2];
z = ((int16_t)values[5] << 8) | (int16_t)values[4];

// 0.03125 = (16*2)/(2^10)
xg = x * 0.03125;
yg = y * 0.03125;
zg = (z * 0.03125) - 1;



//
Serial.print(xg);
Serial.print("\t");
Serial.print(yg);
Serial.print("\t");
Serial.println(zg);
}

void writeRegister(char registerAddress, char value) {
// SPI
digitalWrite(SS, LOW);
//
SPI.transfer(registerAddress);
//
SPI.transfer(value);
// SPI
digitalWrite(SS, HIGH);
}

void readRegister(char registerAddress, int16_t numBytes, char * values) {
//
char address = 0x80 | registerAddress;
//
if (numBytes > 1)address = address | 0x40;
// SPI
digitalWrite(SS, LOW);
//
SPI.transfer(address);
//
for (int16_t i = 0; i < numBytes; i++) {
values[i] = SPI.transfer(0x00);
}
// SPI CS HIGH
digitalWrite(SS, HIGH);
}


Upload this code, you will get 3 columns of serial data in serial monitor.
Apply FFT to the required channel before pushing to serial...

Go Up