1

I want to monitor the vibration from a motor running at 9.5Hz at 565rpm. I am using Arduino Uno and the ADXL345 as my condition monitoring equipment. How do I set the sampling frequency? I want to sample at at least 5x more than the operating frequency which is 50Hz, which will give a interval of 0.02 sec. However, to collect 2500 readings, I would need to take around 300 sec which is 0.12sec per reading different from the preset value at 0.02 sec.

Is my code wrong somewhere? Or what can I do to speed up the process?

#include <Wire.h>
#define DEVICE (0x53)    //ADXL345 device address
#define TO_READ (6)        //num of bytes we are going to read each time    (two bytes for each axis)
#define THRESH_ACT  (0x24)
#define THRESH_INACT  (0x25)
#include <SPI.h>
#include <SD.h>
File myFile;

// Declare Variable
byte runComplete; //setting the number of iteration
int i; //delare i for count
byte buff[TO_READ];//6 bytes buffer for saving data read from the device
float x, y, z; //Acceleration variable
float x1, y1, z1; //Acceleration variable

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
}

void readFrom(int device, byte address, int num, byte buff[]) { //reads num bytes starting from address register on device in to buff array
  Wire.beginTransmission(device); //start transmission to device
  Wire.write(address);        //sends address to read from
  Wire.endTransmission(); //end transmission
  int n = Wire.requestFrom(device, num);    // request 6 bytes from device
  if( n == num)
  {     
      Wire.readBytes(buff, n);
  }
    }
void regAddress()
{
    int regAddress = 0x32;    //first axis-acceleration-data register on the ADXL345
    readFrom(DEVICE, regAddress, TO_READ, buff); //read the acceleration data from the ADXL345

     //each axis reading comes in 10 bit resolution, ie 2 bytes.  Least Significat Byte first!!
     //thus we are converting both bytes in to one int
    x = (((int)buff[1]) << 8) | buff[0];  
    y = (((int)buff[3])<< 8) | buff[2];
    z = (((int)buff[5]) << 8) | buff[4];

    x1 = (x/256);
    y1 = (y/256);
    z1 = (z/256);

 Serial.println(" ");
    Serial.print("X: ");Serial.print(x1); Serial.println(" mm/s2");
    Serial.print("Y: ");Serial.print(y1); Serial.println(" mm/s2");
    Serial.print("Z: ");Serial.print(z1); Serial.println(" mm/s2");
    Serial.println(" ");

    myFile = SD.open("x30.txt", FILE_WRITE); // if the file opened okay, write to it:
    if (myFile) {
      Serial.print("Writing to X.txt...");
      myFile.println(x1);
      myFile.close();// close the file:
      Serial.println("done.");
    } else {
      Serial.println(F("error opening x.txt")) ;// if the file didn't open, print an error:
    }

    myFile = SD.open("y30.txt", FILE_WRITE); // if the file opened okay, write to it:
    if (myFile) {
      Serial.print("Writing to Y.txt...");
      myFile.println(y1);
      myFile.close();// close the file:
      Serial.println("done.");
    } else {
      Serial.println(F("error opening Y.txt")) ; // if the file didn't open, print an error:
    }
      myFile = SD.open("z30.txt", FILE_WRITE);// if the file opened okay, write to it:
    if (myFile) {
      Serial.print("Writing to Z.txt...");
      myFile.println(z1);
      myFile.close();// close the file:
      Serial.println("done.");
      Serial.println("");
    } else {
      Serial.println(F("error opening Z.txt")); // if the file didn't open, print an error:
      Serial.println("");
    }   
       }

void setup()
{
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output
  writeTo(DEVICE, 0x2D, 0);   //Turning on the ADXL345
  writeTo(DEVICE, 0x2D, 16);  //Turning on the ADXL345
  writeTo(DEVICE, 0x2D, 8);   //Turning on the ADXL345
  writeTo(DEVICE, 0x31, 8);
  Serial.println("Initializing Accelerometer...");
  Serial.print("Initializing SD card...");
  Serial.println("");
  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    Serial.println("");
    return;
  }
  delay(2000);
}

 void loop() {
   if (runComplete == 0){
  for (i=0; i<2501; i=i+1){
 Serial.print("Number of iteration(seconds) = "); Serial.print(i);
 Serial.println("");
 regAddress();
     delay(200);
   }
  runComplete = 1;
  }
}
  • Hint: Try measuring the time to perform regAddress(). Looks like that is in the range of 0.1 second?? – Mikael Patel Mar 29 '16 at 8:10
  • 1
    Hint: Improve regAddress() by first removing all the Serial.print() statements. – Mikael Patel Mar 29 '16 at 14:31
  • 1
    Hint: Use a single data log file. Write all three values to this file. Keep it open during the data collect. – Mikael Patel Mar 29 '16 at 14:32
  • After speeding up regAddress(), instead of delay(), use an if (millis() -previousMillis >20){previousMillis=millis();... } to control the rate. – Dave X Mar 29 '16 at 17:09
  • Record the raw data, then after the sampling is done, re-read the data and report or recode the data in whatever format you need. – Dave X Mar 29 '16 at 17:11
1

0.02 seconds means 20 ms, not 200. Your delay time is too long. Try using millis or micros instead of delay for average deviation. Using delay will accumulate lags caused by process time. Try to sacrifice memory to log the data first (using for() & data array), and then write to serial later.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.