Stabilizing Accelerometer (ADXL335) to measure displacement?

eezJerome:
Does it have a voltage regulator? Normally the breakout board has one but there are also some that don't have it. I'm not so familiar with the ADXL3355 but if it has a tiny 3 pin looking black "chip" then I guess it's safe to use 5v. Otherwise use 3.3v

Ensure that enough voltage is supplied by your Arduino to the sensor; if you choose to use 3.3v straight from the Arduino, a nano sometimes won't be enough, however an uno will be good.

I'm not like one of the experts here but if I give advice it should help :slight_smile:

Cheers

Hi, thanks for your comment.
Yes, there is a 3.3v voltage regulator on board.
I double checked: http://www.hobbytronics.co.uk/adxl335-breakout
I know it's safe, but the question is if it's stable enough or not??? someone pointed out that to make my readings more accurate I should "stabilise" the power supply. But I was wondering if that's necessary if I'm powering from my computer/ usb cable/ arduino UNO?

cloudurchin:
Hi, thanks for your comment.
Yes, there is a 3.3v voltage regulator on board.

Use the 5v then. It'll be sufficient enough, since there is a voltage regulator

cloudurchin:
Hi, thanks for your comment and the video url!
Oh yes, I do know that it's about finding the area under a curve...
The issue is more like... I don't know why I need to do that and how that fits into the whole process of finding acceleration...

But I feel like I don't even need to do a double integration, because I just want to track acceleration...
All the mixed answers from everyone on the forum is frying my brain but it seems like, all I need to do is just combine the vectors??? of the 3-axises, x, y, z, and don't need any of the double integration stuff.

Like I said I'm only in Pre-Calculus but I do know that a single integration gives velocity, which is "a step down" of acceleration. Additionally, an integration of that velocity (hence double integration) gives displacement.

But since you only need acceleration dont worry too much about double integration. You're fine.

HOWEVER, you do want to find displacement right? So a double integration would be nice, and maybe you can include the vector math.

I hope the pros come and scrutinize my advice....

Cheers,

Jerome

To be honest most of the confusion is your own fault, as it's because you mixed up words. So we talk about one thing, and you about something different. Now that's been cleared up, forget that double integration stuff.

For your project you may not need calibration beyond a "zero": the thing hanging in the air. A hit will be clearly visible, do some measurements and you know what numbers are a hard hit and what constitutes a gentle push, and what a normal swing looks like. That's what you're after, isn't it?

wvmarle:
To be honest most of the confusion is your own fault, as it's because you mixed up words. So we talk about one thing, and you about something different. Now that's been cleared up, forget that double integration stuff.

Yeah you're right... I didn't even know the difference between displacement and acceleration, so stupid of me.... I'm really sorry.... should have made sure I knew all these basic maths before I posted the question.... or aimed too high... but i don't wanna give up on the whole project :cry:

For your project you may not need calibration beyond a "zero": the thing hanging in the air.

Ok - could you please expand on what you mean by calibration beyond a "zero"?? zero of what exactly?

A hit will be clearly visible, do some measurements and you know what numbers are a hard hit and what constitutes a gentle push, and what a normal swing looks like. That's what you're after, isn't it?

YES YES YES!! that is exactly what I want!! The part I'm struggling with is "doing some measurements" part. Do I need to combine the 3-axis readings somehow?

Zero movement - just gravity. That's your starting point. You don't need the exact number as long as you know the deviation.

Come to think of it, a piezo disc with stick mounted to it may do the job for you.

wvmarle:
Come to think of it, a piezo disc with stick mounted to it may do the job for you.

Good thinking!! but I can't do that because the sensor needs to be embedded into a tube made of fabric, stuffed with cushion fillings - as seen in the image attached. The cushioning will absorb the vibration.

Only little vibration is needed, so it may still work. You'll just have to try it.

Otherwise, have the Arduino just read the accelerometer on startup, and continue measuring. Use the average of the last few seconds or so as baseline, and any deviation that's for the impacts. Larger deviation is larger impact.

Of course now you have no idea in which exact direction it is, but that doesn't seem to matter much here. Nor do you know the absolute value of the acceleration (impact), but that also doesn't matter, you're not building a drone or so. It's more like: medium short time deviation: a good tug. Large short term deviation: a hit. Very large short term deviation: a baseball bat. Values all over the place for some time: it's tumbling around.

cloudurchin:
...combine the 3-axis readings somehow...

Why don't you give this a try and see if it helps your project:

srss = sqrt(xx + yy + z*z)

the magnitude of the combined acceleration vector

DaveEvans:
Why don't you give this a try and see if it helps your project:

srss = sqrt(xx + yy + z*z)

the magnitude of the combined acceleration vector

Hi DaveEvans,
Thanks so much for your comment!
I have a few questions for you;
Why do you think that equation is good to try it out? Why do I have to combine the magnitude? What does "magnitude of the combined acceleration vector" actually mean??

I've actually seen that formula on a tutorial using the adxl335, but has absolutely no clue what it is, what it is and how it works. I've tried using is but I don't know what the readings actually mean. Is it showing acceleration? Or displacement? or velocity??

It would be really really really be helpful if you could explain.

Looking forward to hearing from you...

The sensor measures up/down separately from left/right. If you just want to know if it was hit without needing the direction of the hit, then use that formula above.

^^^right.

If you want to learn more about the formula, google 3d vector math

Also, regarding whether the formula gives acceleration, velocity, or displacement:google dimensional analysis

Regarding the latter, in brief: if x, y, and z all have units of length divided by time squared (i.e., acceleration), what must be the units of "srss"?

MorganS:
The sensor measures up/down separately from left/right. If you just want to know if it was hit without needing the direction of the hit, then use that formula above.

DaveEvans:
^^^right.

If you want to learn more about the formula, google 3d vector math

Also, regarding whether the formula gives acceleration, velocity, or displacement:google dimensional analysis

Regarding the latter, in brief: if x, y, and z all have units of length divided by time squared (i.e., acceleration), what must be the units of "srss"?

Okay, thanks to you, the equation is starting to make sense to me.
I should have mentioned that I didn't need to know the direction of the hit earlier, so that my question was clearer! I'll try it out and see what happens. Thank you for your help!

Hey wvmarle,

wvmarle:
Otherwise, have the Arduino just read the accelerometer on startup, and continue measuring. Use the average of the last few seconds or so as baseline, and any deviation that's for the impacts. Larger deviation is larger impact.

YES!! This is the kind of answer I was looking for!
Use the average of the last few seconds or so as baseline, and any deviation that's for the impacts.: I have done this exact thing in the code posted in post #0 - I'll put it here again, let me know what you think? I wanted to know if what I'm doing achieves what you described there.

The bit I calculate the deviation from, not the "last few seconds" but the last reading / loop cycle:

int accelerationX = abs(averageX - lastX);
  lastX = averageX;
  return accelerationX;

^So here,
1) I'm subtracting current averaged reading (of x-axis) "averageX" from "lastX" (which was the averageX in the last reading).
2) Then I store the current "averageX" in "lastX". This "lastX" is going to be used in the next loop cycle - the newer reading of "averageX" will be subtracted from the "lastX" and so on....
Is this the same thing as what you said???

Here is the whole code:

const int ap1 = A5; 
const int ap2 = A4;
const int ap3 = A3;
const int numReadings = 30;
int inByte = 0;         // incoming serial byte

int readingsX[numReadings];      // the readings from the analog input
int readingsY[numReadings];      // the readings from the analog input
int readingsZ[numReadings];      // the readings from the analog input

int readIndexX = 0;              // the index of the current reading
int readIndexY = 0;              // the index of the current reading
int readIndexZ = 0;              // the index of the current reading
int totalX = 0;                  // the running total
int totalY = 0;                  // the running total
int totalZ = 0;                  // the running total
int averageX = 0;                // the average
int averageY = 0;                // the average
int averageZ = 0;                // the average
int lastX = 0;
int lastY = 0;
int lastZ = 0;



void setup() {
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  for (int thisReading = 0; thisReading < numReadings; thisReading++) {
    readingsX[thisReading] = 0;
    readingsY[thisReading] = 0;
    readingsZ[thisReading] = 0;
  }
}

void loop() {


  int Xval = getXval();
  int Yval = getYval();
  int Zval = getZval();
  
  Serial.print(Xval);
  Serial.print(",");
  Serial.print(Yval);
  Serial.print(",");
  Serial.print(Zval);
  Serial.print("\n");
  delay(2);

} //------End of Loop-----


int getXval(){
  
  //  X------------------------------
  // subtract the last reading:
  totalX = totalX - readingsX[readIndexX];
  
//read from the sensor:
  int x = abs(analogRead(ap1));
  int xMapped = map(x,0,10,0,1000);
  readingsX[readIndexX] = xMapped;
  
  // add the reading to the total:
  totalX = totalX + readingsX[readIndexX];
  // advance to the next position in the array:
  readIndexX = readIndexX + 1;

  // if we're at the end of the array...
  if (readIndexX >= numReadings) {
    // ...wrap around to the beginning:
    readIndexX = 0;
  }

  // calculate the average:
  averageX = totalX / numReadings;
  int accelerationX = abs(averageX - lastX);
  lastX = averageX;
  return accelerationX;
}


int getYval(){

  //  Y------------------------------
   // subtract the last reading:
  totalY = totalY- readingsY[readIndexY];
  
//read from the sensor:
  int y = abs(analogRead(ap2));
  int yMapped = map(y,0,10,0,1000);
  readingsY[readIndexY] = yMapped;
  
  // add the reading to the total:
  totalY = totalY + readingsY[readIndexY];
  // advance to the next position in the array:
  readIndexY = readIndexY + 1;

  // if we're at the end of the array...
  if (readIndexY >= numReadings) {
    // ...wrap around to the beginning:
    readIndexY = 0;
  }

  // calculate the average:
  averageY = totalY / numReadings;
  int accelerationY = abs(averageY - lastY);
  lastY = averageY;
  return accelerationY;
}


int getZval(){
  //  Z------------------------------
   // subtract the last reading:
  totalZ = totalZ - readingsZ[readIndexZ];
  
//read from the sensor:
  int z = abs(analogRead(ap3));
  int zMapped = map(z,0,10,0,1000);
  readingsZ[readIndexZ] = zMapped;
  
  // add the reading to the total:
  totalZ = totalZ + readingsZ[readIndexZ];
  // advance to the next position in the array:
  readIndexZ = readIndexZ + 1;

  // if we're at the end of the array...
  if (readIndexZ >= numReadings) {
    // ...wrap around to the beginning:
    readIndexZ = 0;
  }

  // calculate the average:
  averageZ = totalZ / numReadings;
  int accelerationZ = abs(averageZ - lastZ);
  lastZ = averageZ;
  return accelerationZ;
}

Of course now you have no idea in which exact direction it is, but that doesn't seem to matter much here. Nor do you know the absolute value of the acceleration (impact), but that also doesn't matter, you're not building a drone or so. It's more like: medium short time deviation: a good tug. Large short term deviation: a hit. Very large short term deviation: a baseball bat. Values all over the place for some time: it's tumbling around.

Yes, exactly! For my project the acceleration value doesn't have to be super accurate.

As for piezo,

Only little vibration is needed, so it may still work. You'll just have to try it.

I've tried it already actually, and with no luck... :frowning: Also there were issues around installing them in the fabric/dismantling, having a limited amount of time/space/ being a in-class project... but thanks for the suggestion!

A number of replies back you got a suggestion on how to turn the three axis into a single acceleration number. That you need to do, as you shouldn't read each axis independently. Simply rotating the device would cause constant changes in the X, Y and Z values but should have a constant number for the overall acceleration.

wvmarle:
A number of replies back you got a suggestion on how to turn the three axis into a single acceleration number. That you need to do, as you shouldn't read each axis independently. Simply rotating the device would cause constant changes in the X, Y and Z values but should have a constant number for the overall acceleration.

wvmarle,

Ooh you mean by the suggestion by DaveEvans (as seen below) ??

DaveEvans:
Why don't you give this a try and see if it helps your project:

srss = sqrt(xx + yy + z*z)

Indeed

wvmarle:
Indeed

OK! Thank you, I will try it out!

THANK YOU SO SO SO MUCH everyone who's contributed to this forum and supported me! :slight_smile:

It seems like, the verdict for my project is - to use the equation

__srss = sqrt(xx + yy + z*z) __

to find a combined acceleration of the 3-axises - x, y and z - store that in a variable, subtract from that variable a new reading of the combined acceleration.

It was also good to find out that what I was experimenting at the beginning (original code I posted in #0) still has a use!

I haven't tested out the equation yet, but how the equation fits in this whole code/project makes so much sense now.

I might report back once I test and am confident enough to explain what exactly I'm doing my code.

THANKS AGAIN EVERYONE!!

This srss value should then be stored in an array, to calculate a moving average, of say the last 8 or 16 readings (nice round number for easy calculation, a division becomes a simple bit shift if you convert that srss into an int value). How many readings you need depends on the reading interval and the duration of your impacts, and will require some trial and error.

That moving average is what you use to compare the current value against and determine whether you see an impact.