New to accelerometer code, a few questions?

Hi, I have seen a couple of the Accelerometer tuts, and more or less this is what I am using as my based to get going.

I have only modified it to suit my accelerometer and add output for serial monitoring the values.

I have my accelerometer mounted on a ‘tube’ on PVC… to mimic its final ‘mounting’ orientation and use.

with some wire/cable going to my Arduino Duemilanove per the circuit outline in the sketch comments:

/*
Accelerometer: DE-ACCM3D [Buffered 3D Accelerometer]
http://www.dimensionengineering.com/DE-ACCM3D.htm

Original code:
http://www.arduino.cc/en/Tutorial/ADXL3xx
Created: 07.02.08
(by David A. Mellis)
Modified 06.13.10
(by Jerry Dugan)

The circuit:
 analog 1: z-axis
 analog 2: y-axis
 analog 3: x-axis
 analog 4: ground
 analog 5: vcc 
 
 This example code is in the public domain.

*/

// these constants describe the pins. They won't change:
const int groundpin = 18;             // analog input pin 4 -- ground
const int powerpin = 19;              // analog input pin 5 -- voltage
const int xpin = 3;                   // x-axis of the accelerometer
const int ypin = 2;                   // y-axis
const int zpin = 1;                   // z-axis (only on 3-axis models)

void setup()
{
  // initialize the serial communications:
  Serial.begin(9600);
  
  // play tone when ready
  tone(8, 350, 250);
  // Provide ground and power by using the analog inputs as normal
  // digital pins.  This makes it possible to directly connect the
  // breakout board to the Arduino.  If you use the normal 5V and
  // GND pins on the Arduino, you can remove these lines.
  pinMode(groundpin, OUTPUT);
  pinMode(powerpin, OUTPUT);
  digitalWrite(groundpin, LOW); 
  digitalWrite(powerpin, HIGH);
}

void loop()
{
  // print the sensor values:
  Serial.print("X: ");
  Serial.print(analogRead(xpin));
  // print a tab between values:
  Serial.print("\t");
  Serial.print("Y: ");
  Serial.print(analogRead(ypin));
  // print a tab between values:
  Serial.print("\t");
  Serial.print("Z: ");
  Serial.print(analogRead(zpin));  
  // print a axis value totals:
  Serial.print("\t");
  Serial.print(analogRead(xpin) + analogRead(ypin) + analogRead(zpin));
  
  unsigned int total = (analogRead(xpin) + analogRead(ypin) + analogRead(zpin));
  Serial.print("------>");
  Serial.print(total);
  if (total < 1000){ 
     tone(8, 550, 250);
  }  
  Serial.println();
  // delay before next reading:
  delay(100);
}

Im a little unsure as to the what the original author meant by this section/comments:

 // Provide ground and power by using the analog inputs as normal
  // digital pins.  This makes it possible to directly connect the
  // breakout board to the Arduino.  If you use the normal 5V and
  // GND pins on the Arduino, you can remove these lines.
  pinMode(groundpin, OUTPUT);
  pinMode(powerpin, OUTPUT);
  digitalWrite(groundpin, LOW); 
  digitalWrite(powerpin, HIGH);
}

I have:

Accelerometer PWR to Analog pin5
Accelerometer GND to Analog pin4
Accelerometer X axis to Analog pin3
Accelerometer Y axis to Analog pin2
Accelerometer Z axis to Analog pin1

my GOAL is two-fold… I want to be able to ‘track’ whenever the ‘sword’ (accelerometer) is being swung at a relatively decent speed, and then of course execute an event/function… (later I might add multi swing/force checking, but for now 1 ‘threshold’ is enough to get going)

secondly… I’d like to learn/figure out how to detect an abrupt stop like you swung and hit something

I hope I havent lost anyone… just trying to give a decent background for communication purposes. :wink:

onto my ‘results’ and the best way to handle this.

the values of any given axis is around 340-360 (when output to the serial monitor in the Arduino IDE) and of course one value/axis of the 3 will be around 470-490… which 'higher valued ‘axis’ depends on the orientation/mounting of the board.

more or less after just a plain totaling of the axis values… anything under ‘around’ 1000 verified as a swing/movement…swinging harder gave me lower a total…

I however do not feel this is the most accurate way of doing it since the orientation will not be known (think swordplay/fighting…etc)

and the orientation and way it might be held…etc… but swing in any direction needs to trigger event/function…and then Id like to take it one step closer to detecting an abrupt stop or ‘hit’ event.

Id imaging Id need to write some sort of ‘timer’ watchdog to check an sudden increase/decrease in force in ‘under’ a certain ms time frame?

ie:

value of swing is 900 something… if it that value reaches say 100 in under a certain milisecond threshold consider it a hit/abrupt stop event?

Anyone with some input chime in… all comments (positive) are appreciated.

Thanks

bump.. ;)

anyone? am I all alone here.. lol

on a side note.. are there any other 'Arduino' forums..that re more active? lots of members/traffic?

thanks

Im a little unsure as to the what the original author meant by this section/comments:

It looks like the author is suggesting that you use the analogue pin (digital would do as well) to power the accelerometer. When a pin goes high it outputs five volts. As long as you dont draw more than 40 ma, you can use this to power other 5 volt devices. You can also turn the external device off and on by making the pin low or high.

I'd like to learn/figure out how to detect an abrupt stop like you swung and hit something

You have to monitor for very high deceleration values. Experimentation will help you determine a threshold between hitting something and rapidly slowing the sword.

I want to be able to 'track' whenever the 'sword' (accelerometer) is being swung at a relatively decent speed,

The accelerometer will not measure the speed of the sword, therefore you cannot measure the speed as such. What you can measure is acceleration/deceleration events that precede the 'speed' and follows the speed, thereby defining the 'speed' event. Monitor for acceleration in a certain plane and then one could assume the sword is traveling at speed until you record deceleration in the same plane. (I realise that this is not simple as the deceleration is unlikely to be of the same magnitude as the acceleration therefore making it hard to determine if the sword has returned to the same speed as before the 'speed' event (e.g. a slash).

(yeah a reply!)...

thanks for the reply.. (was starting to think this place was dead?!)

this is really my first Arduino project more or less

(if you know anything about FTDI DIY cables and troubleshooting uploading sketches to an Arduino on breadboard..I could use some feedback, communication here as well) http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1276582755/0

so for 'detecting' the acceleration at a certain rate/speed/level should/could be done how?

you think in the main loop() function.. I should read the X-axis pin.. 'record' that initial value..

check that X-axis pin again on next cycle.. see if the new value is "xx" amount more than previous value?..and if so..then execute an 'event'..

if not..just update that variable with the new value?

something along those lines?

Thanks

Yep,

Do not put your code in the loop() as it keeps looping indefinitely. leave it blank. Instead setup up a ‘for/next’ loop inside the setup() and set it to cycle say 20000 times (I’m not sure which value so play around with this) so that you have time to pick up the sword and wave it around.

Put some comparison code in the for-loop so that for each iteration it checks whether the current reading for X exceeds the value stored in ‘Reading’. If so replace it with the X value.

At the end of the loop (after the 20,000 iterations) Serial.print() the value of ‘Reading’ so that it comes out on hyperterminal/Putty on your PC.

thanks…

Being so new… I guess Im a bit confused when you say ‘set it to cycle’?

Im usually just using the loop…

since its constantly running/executing code… not sure how I can get a continuous routine to run in the setup function?

do you mean just )sytanx is wrong Im sure…this is ActionScript 2.0)

var i = 20000;

for(i=0; i<20000; i++){
//check X value
if(i >= prevRead){
prevRead = i;
}
}
Serial.print(analogRead(xpin));

thanks…

Almost…

int prevRead = 0;

for (int i=0; i<20000; i++){
    //check X value
    int x = analogRead(xpin)
    if (x > prevRead){
         prevRead = x;
    }
}
Serial.print(prevRead);

I haven’t compiled this but you can probably get the gist of it.

DOH…

yes… that looks much better…

I was trying to get out the door to work…and wanted to hurry and post…

int prevRead = 0;

for (int i=0; i<20000; i++){
//check X value
int x = analogRead(xpin)
if (x > prevRead){
prevRead = x;
}
}
Serial.print(prevRead);

makes much more sense…

where as mine was broke after the first two lines! LOL

I’ll boot things up…and see what I get using this approach.

thanks…

well to keep things going for 'fun'..

I finally set-up the Arduino again..and started to test my Arduino..

Im sure the code could be simplified... but Im new and this is a learning curve.. of course constructive criticism on code optimization..etc

I am a 'trace/ouput' (serial.print) nut.. I do this in every language so I can debug better/faster and watch the flow of my code.

/* Accelerometer: DE-ACCM3D [Buffered 3D Accelerometer] http://www.dimensionengineering.com/DE-ACCM3D.htm

Original code: Created: 06.17.10 (by Jerry Dugan)

The circuit: analog 1: z-axis analog 2: y-axis analog 3: x-axis analog 4: ground analog 5: vcc

*/

// these constants describe the pins. They won't change: const int ledPin = 13; // LED connected to digital pin 13 const int groundpin = 18; // analog input pin 4 -- ground const int powerpin = 19; // analog input pin 5 -- voltage const int xpin = 3; // x-axis of the accelerometer const int ypin = 2; // y-axis const int zpin = 1; // z-axis (only on 3-axis models) const int pause = 100; //delay time int prevX = 0; int currX = 0; int prevAccel = 0; int currAccel = 0;

void setup(){ // initialize the serial communications: Serial.begin(9600); // initialize the digital (led) pin as an output: pinMode(ledPin, OUTPUT); // Provide ground and power by using the analog inputs as normal digital pins. // If you use the normal 5V andGND pins on the Arduino, you can remove these lines. pinMode(groundpin, OUTPUT); pinMode(powerpin, OUTPUT); digitalWrite(groundpin, LOW); digitalWrite(powerpin, HIGH);

//set boot values prevX = analogRead(xpin); prevAccel = (currX - prevX)/pause;

// play tone when ready // tone(8, 350, 250); } void loop(){ //Acceleration formula: a = (V2 - V1)/T //Acceleration: a = (currX - prevX)/pause currX = analogRead(xpin); currAccel = (currX - prevX)/pause; if (currAccel > prevAccel){ //output text/serial trigger Serial.println(""); Serial.println("--ACCELERATED--"); Serial.println(""); //visually display feedback by ' led blink' digitalWrite(ledPin, HIGH); // set the LED on } Serial.print("PX: "); Serial.print(prevX); Serial.print(" CX: "); Serial.println(currX);

//update values prevX = currX; prevAccel = currAccel; digitalWrite(ledPin, LOW); // set the LED off delay(pause); //pause 100 ms.. [10 checks per second] }

right now Im only doing 1 axis (X).. but shouldnt be too hard to add the other two in..all I need to do is total them all up and average perhaps? (basically having an acceleration 'var' for each axis?)

maybe totaling all the average.. then check against previous variable/value calculated the same way??

thoughts & feedback are appreciated..

I knwo this isnt very accurate right now.. since it will 'trigger' at ANY sign of 'acceleration' (difference between acceleration point 1 vs point 2) and there is no 'padding' or threshold to be 'above'..

Im assuming an abrupt stop (jerk I think it is referred too) would be the opposite? having the compared value(s) be LESS than previous recorded value.. in a certain time frame?