OK...
Now we know that the accelerometer mounted in Chumby is not the 2-axis ADXL322 as mentioned in the schematics (there is no BOM), but it is instead the 3-axis ADXL330.
This affects the math in the following manner (and accounts for the error we were getting before)
When we calibrate our raw readings and attach them to a physical G value, we need to keep in mind that the accelerometer indicates at most +1g or -1g... The ADXL322 had a max range of 2g... but the accelerometer installed in Chumby has a much larger range of +-3.6g...
So For the X axis, a +1g reading of 2400 is normal and a -1g reading of 1600 is normal.
2000 is for zero g (90 degrees to the axis)...
We scale these numbers to read between -1 and +1 for multiplication with a constant: ACCELERATION_DUE_TO_G = 9.80665 meters/second^2
So - For a reading of 2g, we would read 2800 or 1200 on the accelerometer output and it would be scaled to +2 or -2.
SCALED_RAW_NUM = (RAW_NUM - 2000)/400 ;
This snippet of code has a routine that runs 60 times a second, automatically... 1.6KHz is the MAX bandwidth of the part, and it was designed for a bandwidth of 100Hz... If you change it, only go down to 10mS... but anything that will change more than 3.6g's in 10mS would probably destroy Chumby, anyways...
Bruce
ps - much of this code was re-used from the iAccelerate project and reported to Chumby FLASH... as well as the accelerometer example provided by Chumby folks
ACCELERATION_DUE_TO_G = 9.80665;
AIR_DENSITY_AT_AVG_TEMP = 1.225; // kg per m^3
FEET_PER_METER = 3.2808399;
FEET_PER_MILE = 5280.0;
POUNDS_PER_GALLON_OF_GAS = 6.25;
POUNDS_PER_KG = 2.20462262;
WATTS_PER_HORSEPOWER = 745.69987158227025;
SECONDS_IN_HOUR = 3600.0;
FrontalArea = 3.7; // m^2 - Frontal Area of you
DragCoefficient = 0.02; - Change this
Weight = (185*POUNDS_PER_KG); // in KG
//Init the 4 movie clips, 1 per line
createEmptyMovieClip("red_mc", 10);
red_mc.lineStyle(1, 0xff0000);
red_mc.moveTo(320,120);
createEmptyMovieClip("green_mc", 20);
green_mc.lineStyle(1, 0x00ff00);
green_mc.moveTo(320,120);
createEmptyMovieClip("blue_mc", 30);
blue_mc.lineStyle(1, 0x0000ff);
blue_mc.moveTo(320,120);
createEmptyMovieClip("yellow_mc", 40);
yellow_mc.lineStyle(1, 0xffff00);
yellow_mc.moveTo(320,120);
//Set currx, the current place where the mc's should be
currx = 320;
//init the accelerometer
_accelerometer = ["ASnative"](5,60);
//Create the data that would normally be accelerometer data
// Timing
// If Velocity = Accel2 - Accel1 AND
// If Accel = Raw2 - Raw1
// Lets sample at 200Hz and see how it works
delay = 5; // 200Hz
then = 0; //
oldX = 0;
isnewrun = 1;
numofiterations = 0;
totaltime = 0;
currentX = 1600;
sign = -1;
sine = 180;
function GetXData () {
currentX = _accelerometer(2);
//currentX = Math.sin(sine*(Math.PI/180));
//trace ("Sine = "+sine);
//trace ("CurrentX(SIN) = "+currentX);
//currentX = (currentX * 400) + 2000;
//currentX = Math.round(currentX);
//trace ("CurrentX = "+currentX);
//sine = sine + sign;
//if (sine == -90) {
//sign = sign * -1
//}
//if (sine == 90) {
//sign = sign * -1
//}
// ADXL330 runs +-3.6G...
CurrentX = ((CurrentX - 2000)/400);
//trace ("CurrentX = "+currentX);
TracecurrentX = (((currentX * 400) + 2000)/4)-375;
//trace ("TracecurrentX = "+TracecurrentX);
//trace (currentX);
// If first time through loop - init variable
if (isnewrun == 1) {
lastSpeed = 0;
lastAcceleration = 0;
lastDistance = 0;
FirstAcceleration = currentX;
isnewrun = 0;
}
ChangeInAccel = currentX - FirstAcceleration;
gs = ChangeInAccel * ACCELERATION_DUE_TO_G;
//trace ("Gs = "+gs);
TracecurrentXAccel = (gs*14) + 115;
numofiterations +=1;
//trace ("numofiterations = "+numofiterations);
totaltime += 0.016;
//trace ("totaltime = "+totaltime);
// v=v0 + a*t
// v(n) = v(n-1)+(a(n) + a(n-1))*(tbs)/2
currentSpeed = lastSpeed + (((gs + lastAcceleration) * 0.016) / 2); //change in speed/change in time
//trace ("currentSpeed = "+currentSpeed);
TracecurrentXVelocity = (currentSpeed*4) + 114;
SpeedInMPH = (currentSpeed * FEET_PER_METER) / FEET_PER_MILE * SECONDS_IN_HOUR;
//trace ("SpeedInMPH = "+SpeedInMPH);
// d=v0*t + .5*a*t^2
// d=.5(v2+v1)*t
// d(n) = d(n-1)+(v(n)+v(n-1))*(tbs)/2
distanceTraveled = lastDistance + (((currentSpeed + lastSpeed) * 0.016) / 2);
//trace ("distanceTraveled = "+distanceTraveled);
distanceTravelledFeet = (distanceTraveled * FEET_PER_METER) / FEET_PER_MILE;
//trace ("distanceTravelledFeet = "+distanceTravelledFeet);
averageSpeed = distanceTraveled / totaltime;
//trace ("averageSpeed = "+averageSpeed);
AverageSpeedMPH = (averageSpeed * FEET_PER_METER) / FEET_PER_MILE * SECONDS_IN_HOUR
//trace ("AverageSpeedMPH = "+AverageSpeedMPH);
TracecurrentXDistance = (distanceTraveled) +150;
// F=ma (Newtons)
force = Weight * gs;
//power = force*Distance/Time (Watts)
power1 = force * currentSpeed;
//http://en.wikipedia.org/wiki/Drag_(physics)
power2 = (AIR_DENSITY_AT_AVG_TEMP *
Math.pow(currentSpeed, 3.0) *
FrontalArea *
DragCoefficient) / 2;
currentPower = (power1 + power2) / WATTS_PER_HORSEPOWER;
//trace ("currentPower = "+currentPower);
lastSpeed = currentSpeed;
lastAcceleration = gs;
lastDistance = distanceTraveled;
}
setInterval( GetXData, 16 ); //(60Hz)
//Update every frame
this.onEnterFrame = function(){
//Move the mc's over one
red_mc._x -= 1;
green_mc._x -= 1;
blue_mc._x -= 1;
yellow_mc._x -= 1;
currx++;
//Add next point
red_mc.lineTo(currx, TracecurrentX);
green_mc.lineTo(currx, TracecurrentXAccel);
//green_mc.lineTo(currx, 0);
blue_mc.lineTo(currx, TracecurrentXVelocity);
//blue_mc.lineTo(currx, 0);
yellow_mc.lineTo(currx, TracecurrentXDistance);
//yellow_mc.lineTo(currx, 0);
}