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...
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!