0
Offline
Newbie
Karma: 0
Posts: 13
Arduino rocks
|
 |
« on: December 07, 2010, 05:31:43 am » |
Hello people, I'm posting my first library. It's a library for the MMA7361 accelerometer. I hope this is the correct way to share libraries Since no library was available I believed posting mine would help some people. I'm always open for suggestions since this is my first library I expect it not to be perfect. available for download http://rapidshare.com/files/435429883/AcceleroMMA7361.zipheader file /************************************************************************************************** * acceleroMMA7361.h - Library for retrieving data from the MMA7361 accelerometer. Only tested * * with Duemilanove * * Following functions need improving. I asumed the output to be linear (it is nearly linear but * * not really). I also asumed the Arduino input to be scaled 0-5V * * begin variables * * -int sleepPin: number indicating to which pin the sleep port is attached. DIGITAL OUT * * -int selfTestPin: number indicating to which pin the selftest port is attached.DIGITAL OUT * * -int zeroGPin: number indicating to which pin the ZeroGpin is connected to. DIGITAL IN * * -int xPin: number indicating to which pin the x-axis pin is connected to. ANALOG IN * * -int yPin: number indicating to which pin the y-axis pin is connected to. ANALOG IN * * -int zPin: number indicating to which pin the z-axis pin is connected to. ANALOG IN * * -int offset: array indicating the G offset on the x,y and z-axis * * Functions currently present: * * -getXRaw(): Instantly returns the raw data from the X-axis analog I/O port of the Arduino as * * a double. WARNING! OFFSET HAS NO INFLUENCE * * -getYRaw(): Instantly returns the raw data from the Y-axis analog I/O port of the Arduino as * * a double. WARNING! OFFSET HAS NO INFLUENCE * * -getZRaw(): Instantly returns the raw data from the Z-axis analog I/O port of the Arduino as * * a double. WARNING! OFFSET HAS NO INFLUENCE * * -getXVolt(): Instantly returns the voltage in miliVolts from the X-axis analog I/O port of * * the Arduino as a double. WARNING! OFFSET HAS NO INFLUENCE * * -getYVolt(): Instantly returns the voltage in miliVolts from the Y-axis analog I/O port of * * the Arduino as a double. WARNING! OFFSET HAS NO INFLUENCE * * -getZVolt(): Instantly returns the voltage in miliVolts from the Z-axis analog I/O port of * * the Arduino as a double. WARNING! OFFSET HAS NO INFLUENCE * * -getXAccel(): Instantly returns the acceleration of the X-axis as a double (1G = 100.00) * * -getYAccel(): Instantly returns the acceleration of the Y-axis as a double (1G = 100.00) * * -getXAccel(): Instantly returns the acceleration of the Z-axis as a double (1G = 100.00) * ************************************************************************************************** * Revision History: * * Version 0.1: get raw values * * Version 0.2: get voltages and G forces * ************************************************************************************************** * Created by Jef Neefs: Suggestions, questions or comments please contact me * * - mail: neefsj at gmail dot com * * - skype: studioj * **************************************************************************************************/ #ifndef AcceleroMMA7361_h #define AcceleroMMA7361_h #include <WProgram.h>
class AcceleroMMA7361 { public: AcceleroMMA7361(); void begin(int sleepPin, int selfTestPin, int zeroGPin, int xPin, int yPin, int zPin, int xOffset, int yOffset, int zOffset); double getXRaw(); double getYRaw(); double getZRaw(); double getXVolt(); double getYVolt(); double getZVolt(); double getXAccel(); double getYAccel(); double getZAccel(); double getTotalVector(); private: long _mapMMA7361V(int value); long _mapMMA7361G(int value); int _sleepPin; int _selfTestPin; int _zeroGPin; int _xPin; int _yPin; int _zPin; int _xOffset; int _yOffset; int _zOffset; }; #endif
cpp file comment header as in h file is left away #include <WProgram.h> #include <AcceleroMMA7361.h>
AcceleroMMA7361::AcceleroMMA7361() { }
void AcceleroMMA7361::begin(int sleepPin, int selfTestPin, int zeroGPin, int xPin, int yPin, int zPin, int xOffset, int yOffset, int zOffset) { pinMode(sleepPin, OUTPUT); pinMode(selfTestPin, OUTPUT); pinMode(zeroGPin, INPUT); pinMode(xPin, INPUT); pinMode(yPin, INPUT); pinMode(zPin, INPUT); digitalWrite(sleepPin,HIGH); digitalWrite(selfTestPin,LOW); _sleepPin = sleepPin; _selfTestPin = selfTestPin; _zeroGPin = zeroGPin; _xPin = xPin; _yPin = yPin; _zPin = zPin; _xOffset = xOffset; _yOffset = yOffset; _zOffset = zOffset; }
double AcceleroMMA7361::getXRaw() { return analogRead(_xPin); }
double AcceleroMMA7361::getYRaw() { return analogRead(_yPin); }
double AcceleroMMA7361::getZRaw() { return analogRead(_zPin); }
double AcceleroMMA7361::getXVolt() { return _mapMMA7361V(analogRead(_xPin)); }
double AcceleroMMA7361::getYVolt() { return _mapMMA7361V(analogRead(_yPin)); }
double AcceleroMMA7361::getZVolt() { return _mapMMA7361V(analogRead(_zPin)); }
double AcceleroMMA7361::getXAccel() { return _mapMMA7361G(analogRead(_xPin))+ _xOffset; }
double AcceleroMMA7361::getYAccel() { return _mapMMA7361G(analogRead(_yPin)) + _yOffset; }
double AcceleroMMA7361::getZAccel() { return _mapMMA7361G(analogRead(_zPin)) + _zOffset; }
long AcceleroMMA7361::_mapMMA7361V(int value) { return map(value,0,1024,0,5000); }
long AcceleroMMA7361::_mapMMA7361G(int value) { return map(value,0,1024,-800,1600); }
|
|
|
|
|
Logged
|
|
|
|
|
Netherlands
Offline
Tesla Member
Karma: 90
Posts: 9401
In theory there is no difference between theory and practice, however in practice there are many...
|
 |
« Reply #1 on: December 07, 2010, 05:38:33 am » |
You can also make an article on the playground. Please include some basic examples how to use the lib.
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 13
Arduino rocks
|
 |
« Reply #2 on: December 07, 2010, 06:09:45 am » |
in the zip are examples as wel as a keyword.txt present.
I dont know where I should put this in the playground, there are several places where I could put it.
b.e. "Interfacing with Hardware or "Code Library and Tutorials"...
|
|
|
|
|
Logged
|
|
|
|
|
Denver
Offline
God Member
Karma: 19
Posts: 776
Inactive - PM
|
 |
« Reply #3 on: December 07, 2010, 06:19:41 pm » |
studioj, Thanks for sharing your lib. After a brief look, I'd like to make the following comments / suggestions, if I may: - Looks like you assume it will be run at 5V. 3.3V gives more accuracy. - Maybe you should have a param for the Aref voltage. - That accel has 2 sensitives - 1.5/6g. Looks like you expect 1g max. - Not sure how you calc g - (1 g = 9.80665 m/s2)
(Not to crazy about the site that hosting your zip. You should check out "Dropbox".)
I've been messing with an example for the MMA7361. If there is any interest, I can post it.
|
|
|
|
« Last Edit: December 07, 2010, 06:25:41 pm by BroHogan »
|
Logged
|
"Data is not information, information is not knowledge, knowledge is not understanding, understanding is not wisdom." ~ Clifford Stoll
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 13
Arduino rocks
|
 |
« Reply #4 on: December 08, 2010, 02:55:20 am » |
- Looks like you assume it will be run at 5V. 3.3V gives more accuracy.
I assume 3.3V working voltage BUT the axis all attached to a 0-5 analog input gate. can i change the input gate itself? otherwise 0-1023 equals 0-5V - Maybe you should have a param for the Aref voltage.
maybe yes (do you mean parameterwise change the input gates from 0-5V to 0-3.3V) i do feel i have alot parameters already - That accel has 2 sensitives - 1.5/6g. Looks like you expect 1g max. I set it to 6G sensitivity, thats not mentioned in the header comment indeed. long AcceleroMMA7361::_mapMMA7361G(int value) { return map(value,0,1024,-800,1600); } that function maps 0-5V volt to from -8G to +16G (as the output voltage of the MMA7361 will off course never reach those values) therefor 6G = 3.3V - Not sure how you calc g - (1 g = 9.80665 m/s2) I think i answered this in the above question (Not to crazy about the site that hosting your zip. You should check out "Dropbox".) I feel ok using this host I've been messing with an example for the MMA7361. If there is any interest, I can post it. Of course there is no point sharing a lib if it is not open for input Thank you for your comments I'll post version 0.3 maybe later today
|
|
|
|
« Last Edit: December 08, 2010, 08:58:06 am by studioj »
|
Logged
|
|
|
|
|
Denver
Offline
God Member
Karma: 19
Posts: 776
Inactive - PM
|
 |
« Reply #5 on: December 08, 2010, 11:47:01 am » |
@studioj As you know, the MMA7361 centers it's -/+ g output around it's working voltage (3.3V). Therefore, you loose potential accuracy when Aref is 5V. You can set the Arduino's ARef by putting the 3.3V on the ARef pin and calling analogReference(EXTERNAL); However, if you are happy with only using the 6g sensitivity, and mapping it to -8 -16g the loss of accuracy mentioned above may not be the biggest factor. If this is to be a lib for general use, you should consider supporting the +/- 1.5g range. Many applications would require the lower range. (You'd have a very fast car that could pull >1.5g!) Since I haven't tried your lib yet, I shouldn't quibble about your calc method. I assume, at rest, you read ~0g on X & Y and ~+1g on the Z axis, and moving the accel 180° displays the 1g accordingly. I know you have a bunch of parameters already. Perhaps #defines for sensitivity and Aref - not sure. Assuming that you are using the great little board from ModernDevice, you can read the jumper and automatically set the sensitivity. I'll post what I have in a bit. I'd like to simplify it some first. (I added a smoothing filter.) However, below are some formulas I used in case they are helpful. 1.5g setting: Sensitivity: 800 mV/g -1g = 850mV 0g = 1650mV 1g = 2450mV 6g setting: Sensitivity: 206 mV/g -1g = 1444mV 0g = 1650mV 1g = 1856mV mV/analogRead unit = Aref V / 1024 g = [mV/analogRead unit] * ([units] - ([Aref/2]) / [mvPerG] 0-60 Time = 26.8224 / (g * 9.81) [60MPH = 26.8224 m/s, g = 9.81 m/s/s] I know I'm being critical about what you've done, and I hope it's taken in the spirit it's offered in.
|
|
|
|
« Last Edit: December 08, 2010, 12:08:35 pm by BroHogan »
|
Logged
|
"Data is not information, information is not knowledge, knowledge is not understanding, understanding is not wisdom." ~ Clifford Stoll
|
|
|
|
Portugal
Offline
God Member
Karma: 5
Posts: 962
|
 |
« Reply #6 on: December 08, 2010, 02:18:06 pm » |
Do you really need floats for all that integer reading and calcs? Thats one huge cpu hog...
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 13
Arduino rocks
|
 |
« Reply #7 on: December 08, 2010, 03:03:35 pm » |
@ Senso and BroHogan
I was expecting comments and improvements. I'm definitly not the best programmer in the world :-) but i felt people could be helped by a library. Therefore, any help, hints or tips for improvement are happily received.
I used the sparkfun breakout board btw
|
|
|
|
|
Logged
|
|
|
|
|
Portugal
Offline
God Member
Karma: 5
Posts: 962
|
 |
« Reply #8 on: December 08, 2010, 03:15:19 pm » |
double AcceleroMMA7361::getXRaw() { return analogRead(_xPin); }
double AcceleroMMA7361::getYRaw() { return analogRead(_yPin); }
double AcceleroMMA7361::getZRaw() { return analogRead(_zPin); }
double AcceleroMMA7361::getXVolt() { return _mapMMA7361V(analogRead(_xPin)); }
double AcceleroMMA7361::getYVolt() { return _mapMMA7361V(analogRead(_yPin)); }
double AcceleroMMA7361::getZVolt() { return _mapMMA7361V(analogRead(_zPin)); }
double AcceleroMMA7361::getXAccel() { return _mapMMA7361G(analogRead(_xPin))+ _xOffset; }
double AcceleroMMA7361::getYAccel() { return _mapMMA7361G(analogRead(_yPin)) + _yOffset; }
double AcceleroMMA7361::getZAccel() { return _mapMMA7361G(analogRead(_zPin)) + _zOffset; }
long AcceleroMMA7361::_mapMMA7361V(int value) { return map(value,0,1024,0,5000); }
long AcceleroMMA7361::_mapMMA7361G(int value) { return map(value,0,1024,-800,1600); }
analogRead returns an int, and map return an int too, so what is the advantage using floats?
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 13
Arduino rocks
|
 |
« Reply #9 on: December 09, 2010, 12:19:46 pm » |
I can only modify my last post. Anyhow here is a small update already. I'm planning to add the 1,5G sensitivity via a setSensitivity() function, later this year.
Revision History Version 0.1: get raw values Version 0.2: get voltages and G forces Version 0.3: removed begin parameters offset, added public function setOffSets(int,int,int) added a private variable _offSets[3] containing the offset on each axis changed the long and double return values of private and public functions to int
new header file /************************************************************************************************** * acceleroMMA7361.h - Library for retrieving data from the MMA7361 accelerometer. Only tested * * with Duemilanove * * Following functions need improving. I asumed the output to be linear (it is nearly linear but * * not really). I also asumed the Arduino input to be scaled 0-5V * * I also 'hard pinned' the G-Selector pin to 6G mode (HIGH) so nothing can be found here about * * 1.5G sensitivity this will be fixed in later versions * * begin variables * * -int sleepPin: number indicating to which pin the sleep port is attached. DIGITAL OUT * * -int selfTestPin: number indicating to which pin the selftest port is attached.DIGITAL OUT * * -int zeroGPin: number indicating to which pin the ZeroGpin is connected to. DIGITAL IN * * -int xPin: number indicating to which pin the x-axis pin is connected to. ANALOG IN * * -int yPin: number indicating to which pin the y-axis pin is connected to. ANALOG IN * * -int zPin: number indicating to which pin the z-axis pin is connected to. ANALOG IN * * * * Functions currently present: * * -getXRaw(): Instantly returns the raw data from the X-axis analog I/O port of the Arduino as * * a int. WARNING! OFFSET HAS NO INFLUENCE * * -getYRaw(): Instantly returns the raw data from the Y-axis analog I/O port of the Arduino as * * a int. WARNING! OFFSET HAS NO INFLUENCE * * -getZRaw(): Instantly returns the raw data from the Z-axis analog I/O port of the Arduino as * * a int. WARNING! OFFSET HAS NO INFLUENCE * * -getXVolt(): Instantly returns the voltage in miliVolts from the X-axis analog I/O port of * * the Arduino as a int. WARNING! OFFSET HAS NO INFLUENCE * * -getYVolt(): Instantly returns the voltage in miliVolts from the Y-axis analog I/O port of * * the Arduino as a int. WARNING! OFFSET HAS NO INFLUENCE * * -getZVolt(): Instantly returns the voltage in miliVolts from the Z-axis analog I/O port of * * the Arduino as a int. WARNING! OFFSET HAS NO INFLUENCE * * -getXAccel(): Instantly returns the acceleration of the X-axis as a int (1G = 100.00) * * -getYAccel(): Instantly returns the acceleration of the Y-axis as a int (1G = 100.00) * * -getXAccel(): Instantly returns the acceleration of the Z-axis as a int (1G = 100.00) * * -setOffSets( int offSetX, int offSetY, int offSetZ): * ************************************************************************************************** * Revision History: * * Version 0.1: get raw values * * Version 0.2: get voltages and G forces * * Version 0.3: removed begin parameters offset, added public function setOffSets(int,int,int) * * added a private variable _offSets[3] containing the offset on each axis * * changed the long and double return values of private and public functions to int * ************************************************************************************************** * Created by Jef Neefs: Suggestions, questions or comments please contact me * * -mail: neefsj at gmail dot com * * -skype: studioj * **************************************************************************************************/ #ifndef AcceleroMMA7361_h #define AcceleroMMA7361_h #include <WProgram.h>
class AcceleroMMA7361 { public: AcceleroMMA7361(); void begin(int sleepPin, int selfTestPin, int zeroGPin, int xPin, int yPin, int zPin); int getXRaw(); int getYRaw(); int getZRaw(); int getXVolt(); int getYVolt(); int getZVolt(); int getXAccel(); int getYAccel(); int getZAccel(); int getTotalVector(); void setOffSets(int xOffSet, int yOffSet, int zOffSet); private: int _mapMMA7361V(int value); int _mapMMA7361G(int value); int _sleepPin; int _selfTestPin; int _zeroGPin; int _xPin; int _yPin; int _zPin; int _offSets[3]; }; #endif
cpp #include <WProgram.h> #include <AcceleroMMA7361.h>
AcceleroMMA7361::AcceleroMMA7361() { }
void AcceleroMMA7361::begin(int sleepPin, int selfTestPin, int zeroGPin, int xPin, int yPin, int zPin) { pinMode(sleepPin, OUTPUT); pinMode(selfTestPin, OUTPUT); pinMode(zeroGPin, INPUT); pinMode(xPin, INPUT); pinMode(yPin, INPUT); pinMode(zPin, INPUT); digitalWrite(sleepPin,HIGH); digitalWrite(selfTestPin,LOW); _sleepPin = sleepPin; _selfTestPin = selfTestPin; _zeroGPin = zeroGPin; _xPin = xPin; _yPin = yPin; _zPin = zPin; setOffSets(0,0,0); }
void AcceleroMMA7361::setOffSets(int xOffSet, int yOffSet, int zOffSet) { _offSets[0]= xOffSet; _offSets[1]= yOffSet; _offSets[2]= zOffSet; }
int AcceleroMMA7361::getXRaw() { return analogRead(_xPin); }
int AcceleroMMA7361::getYRaw() { return analogRead(_yPin); }
int AcceleroMMA7361::getZRaw() { return analogRead(_zPin); }
int AcceleroMMA7361::getXVolt() { return _mapMMA7361V(analogRead(_xPin)); }
int AcceleroMMA7361::getYVolt() { return _mapMMA7361V(analogRead(_yPin)); }
int AcceleroMMA7361::getZVolt() { return _mapMMA7361V(analogRead(_zPin)); }
int AcceleroMMA7361::getXAccel() { return _mapMMA7361G(analogRead(_xPin))+ _offSets[0]; }
int AcceleroMMA7361::getYAccel() { return _mapMMA7361G(analogRead(_yPin)) + _offSets[1]; }
int AcceleroMMA7361::getZAccel() { return _mapMMA7361G(analogRead(_zPin)) + _offSets[2]; }
int AcceleroMMA7361::_mapMMA7361V(int value) { return map(value,0,1024,0,5000); }
int AcceleroMMA7361::_mapMMA7361G(int value) { return map(value,0,1024,-800,1600); } download library http://rapidshare.com/files/435911796/AcceleroMMA7361v0_3.zipBroHogan you had some code to share?
|
|
|
|
|
Logged
|
|
|
|
|
Denver
Offline
God Member
Karma: 19
Posts: 776
Inactive - PM
|
 |
« Reply #10 on: December 10, 2010, 06:02:17 pm » |
@studioj This example has a few small issues, but maybe it will give you some ideas. At least it has a close output to the actual g forces. /* MMA7361 Accelerometer Test BroHogan 12/10/10 * CAUTION! input pins (Sleep, G-Select, Self-Test) are 3.3V max for HIGH * Z should read 1g at rest. The 0g-Detect pin goes high when ALL THREE axes are at 0g. * X & Y Bandwidth: 400Hz (Z=300Hz) Output Impedance: 32K * 1.5g setting: Sensitivity: 800 mV/g -1g = 850mV 0g = 1650mV 1g = 2450mV * 6g setting: Sensitivity: 206 mV/g -1g = 1444mV 0g = 1650mV 1g = 1856mV * mV/analogRead unit = Aref V(3.3) / 1024.0 * g = [mV/analogRead unit] * ([units] - ([Aref/2]) / [mvPerG] * deg. = asin (mVout - 1650mv) / 800mV) (double asin (double x) ) in radians * 0-60 Time = 26.8224 / (g * 9.81) [60MPH = 26.8224 m/s, g = 9.81 m/s/s] * Added digitalSmooth by Paul Badger 2007 - big improvement! * (see www.arduino.cc/playground/Main/DigitalSmooth) * SETUP: * Best to use the 3.3V pin on the (Moderndevices) MMA7361 for ARef * TODO: * >1g && <-1g angle calc gets wonky (fixed). */
#include "WProgram.h" // needed for IDE to understand a "byte"!
#define X_PIN 2 // X Axis input (analog pin #) #define Y_PIN 1 // Y Axis input (analog pin #) #define Z_PIN 3 // Z Axis input (analog pin #) #define GSEL_PIN 14 // pin on accel for range jmpr - LOW = 1.5 g range #define ZERO_G_PIN 9 // HIGH when X,Y,Z = 0 G #define SLEEP_PIN 4 // CAUTION 3.3V input pin - LOW to enable Sleep Mode
#define AREF_V 5000 //3280 // Aref voltage in mV BEST TO THE 3.2V ON THE ACCEL #define LOW_RANGE 800 // Sensitivity for 1.5 g range in mV/g #define HIGH_RANGE 206 // Sensitivity for 6 g range in mV/g #define SAMPLES 13 // SAMPLES should be an odd number, no smaller than 3
int xSmoothArray [SAMPLES]; // array for holding X values for smoothing int ySmoothArray [SAMPLES]; // array for holding Y values for smoothing int zSmoothArray [SAMPLES]; // array for holding Z values for smoothing int xOffset, yOffset, zOffset; // used to hold calculated offsets
int Acc_X, Acc_Y, Acc_Z; // raw accel output float Acc_Xg, Acc_Yg, Acc_Zg; // accel output expressed in mg's float Xdeg, Ydeg, Zdeg; // angle expressed in degrees float mVperUnit; // calculated mV / analogRead unit float mvPerG; // Sensitivity for current range in mV/g float zeroTo60; // seconds for 0-60MPH acceleration equivalent boolean lowRange = true; // 1.5 g max if true - else 6g range
void setup(){ Serial.begin(9600); pinMode(ZERO_G_PIN,INPUT); // HIGH when X,Y,Z = 0 G pinMode(GSEL_PIN,INPUT); // LOW = 1.5 g range //analogReference(EXTERNAL); // set if Aref pin wired to 3.3V source mVperUnit = AREF_V / 1024.0; // calc mV / analogRead unit
Serial.println("Lay flat for calibration!"); CalAccel(); // calc offsets delay (1000); }
void loop(){ //lowRange = !digitalRead(GSEL_PIN); // read pin on accel for range jmpr - If LOW set flag true lowRange = true; // USE THIS IF NOT READING JMPR ON ACCEL if (lowRange)mvPerG = LOW_RANGE; // Set the mV/g based on the current range else mvPerG = HIGH_RANGE;
Read_Accel(); // read the X,Y,Z values from the MMA7361 Disp_Vals(); // display X,Y,Z g values delay(3000); }
void Read_Accel(){ //digitalSmooth(Acc_X,xSmoothArray,true); // reset running average for (int i=0; i< SAMPLES +2; i++){ // make a series of samples for smoothing Acc_X = analogRead(X_PIN) - xOffset; // read the X Axis and apply offset Acc_X = digitalSmooth(Acc_X,xSmoothArray,false); // smooth X axis Acc_Y = analogRead(Y_PIN) - yOffset; // read the Y Axis and apply offset Acc_Y = digitalSmooth(Acc_Y,ySmoothArray,false); // smooth Y axis Acc_Z = analogRead(Z_PIN) - zOffset; // read the Z Axis and apply offset Acc_Z = digitalSmooth(Acc_Z,zSmoothArray,false); // smooth Z axis delay(5); // need this delay for 200Hz max sample rate } // now calc g's and angle . . . if (Acc_X >= 512) Acc_Xg = mVperUnit * (Acc_X - 512) / mvPerG; else Acc_Xg = ((512 - Acc_X) * (mVperUnit) / mvPerG) * -1; if (Acc_Xg >= -1.0 && Acc_Xg <= 1.0) Xdeg = asin(Acc_Xg) * (180.0/PI); else Xdeg = 0; zeroTo60 = 26.8224 / (Acc_Xg * 9.81);
if (Acc_Y >= 512) Acc_Yg = mVperUnit * (Acc_Y - 512) / mvPerG; else Acc_Yg = ((512 - Acc_Y) * (mVperUnit) / mvPerG) * -1; if (Acc_Yg >= -1.0 && Acc_Yg <= 1.0) Ydeg = asin(Acc_Yg) * (180.0/PI); else Ydeg = 0;
if (Acc_Z >= 512) Acc_Zg = mVperUnit * (Acc_Z - 512) / mvPerG; else Acc_Zg = ((512 - Acc_Z) * (mVperUnit) / mvPerG) * -1; Acc_Zg += 1.0; // add 1 g back into axis if (Acc_Zg >= -1.0 && Acc_Zg <= 1.0) Zdeg = asin(Acc_Zg) * (180.0/PI); else Zdeg = 0; }
void Disp_Vals(){ Serial.print("milli G's"); Serial.print("\tX:"); Serial.print(Acc_Xg * 1000,DEC); Serial.print("\tY:"); Serial.print(Acc_Yg * 1000,DEC); Serial.print("\tZ:"); Serial.println(Acc_Zg * 1000,DEC);
Serial.print("Degrees "); Serial.print("\tX:"); Serial.print(Xdeg,DEC); Serial.print("\tY:"); Serial.print(Ydeg,DEC); Serial.print("\tZ:"); Serial.println(Zdeg,DEC); Serial.println("");
if (zeroTo60 > 1 && zeroTo60 < 50){ // only use for zeroTo60 to eliminate noise // Serial.print("Sec 0-60: "); // Serial.println(zeroTo60,DEC); // zeroTo60 or Xdeg } }
int digitalSmooth(int rawIn, int *sensSmoothArray, bool Reset){ // modified from: www.arduino.cc/playground/Main/DigitalSmooth int j, k, temp, top, bottom; long total; static int i; static int sorted[SAMPLES]; boolean done;
if (Reset) { // added to reset running as an option for (j=0; j<SAMPLES; j++){ sensSmoothArray[j] = 0; sorted[j] = 0; } i = 0; return 0; }
i = (i + 1) % SAMPLES; // increment counter and roll over if necc. - % (modulo operator) rolls over variable sensSmoothArray[i] = rawIn; // input new data into the oldest slot
for (j=0; j<SAMPLES; j++){ // transfer data array into anther array for sorting and averaging sorted[j] = sensSmoothArray[j]; }
done = 0; // flag to know when we're done sorting while(done != 1){ // simple swap sort, sorts numbers from lowest to highest done = 1; for (j = 0; j < (SAMPLES - 1); j++){ if (sorted[j] > sorted[j + 1]){ // numbers are out of order - swap temp = sorted[j + 1]; sorted [j+1] = sorted[j] ; sorted [j] = temp; done = 0; } } }
// throw out top and bottom 15% of samples - limit to throw out at least one from top and bottom bottom = max(((SAMPLES * 15) / 100), 1); top = min((((SAMPLES * 85) / 100) + 1 ), (SAMPLES - 1)); // the + 1 is to make up for asymmetry caused by integer rounding k = 0; total = 0; for ( j = bottom; j< top; j++){ total += sorted[j]; // total remaining indices k++; } return total / k; // divide by number of samples }
void CalAccel(){ // make 30 iterations, average, and save offset //otherwise you get an overflow. But 60 iterations should be fine xOffset=0; yOffset=0; zOffset=0; for (int i=1; i <= 30; i++){ xOffset += analogRead(X_PIN); yOffset += analogRead(Y_PIN); zOffset += analogRead(Z_PIN); delay(5); // need delay for 200Hz sample rate } xOffset /=30; // get average xOffset -= 512; // 0g = 512 raw yOffset /=30; yOffset -= 512; zOffset /=30; // this also removes the 1g static accel zOffset -= 512; // added back later }
|
|
|
|
« Last Edit: December 11, 2010, 01:11:29 am by BroHogan »
|
Logged
|
"Data is not information, information is not knowledge, knowledge is not understanding, understanding is not wisdom." ~ Clifford Stoll
|
|
|
|
Barcelona
Offline
Newbie
Karma: 0
Posts: 23
Arduino hurts my brain... but i like it
|
 |
« Reply #11 on: December 21, 2010, 09:42:05 am » |
cool....
i'm just waiting for this acelerometer, it will be a big help for me!
can someone confirm me if i can directly put 3,3V on the SL pin to get it waked up every time? i'm a little short with I/O in my future project. i read it need a resistor, but is it only to limit the maxy current by security or I MUST PUT IT IF I DON'T WANT TO FRY THE BOARD???
regards
|
|
|
|
|
Logged
|
|
|
|
|
Denver
Offline
God Member
Karma: 19
Posts: 776
Inactive - PM
|
 |
« Reply #12 on: December 21, 2010, 11:57:31 am » |
lebenj, If you are referring to the comment in my example above, you need to know that I am using a MMA7361 board sold by Moderndevices. This breakout board has a 3.3V regulator on it so it can be used as input with a 5V system ( via analogRead w/ ARef @ 3.3V).
If you run your board in a similar way, you have to be careful about setting lines HIGH - since the accel will get 5V when it's running at 3.3V. In that case, you will need a voltage divider or level shifter before the accel.
If you are running your Arduino at 3.3V, then there will be no problem.
I hesitate to give more concrete advice since I don't know what board you are using and how you plan to power it. Assuming you have the Sparkfun version and are going to use the 3.3V from the Arduino, then you definitely need some kind of level shift if you want to set SL HIGH.
|
|
|
|
|
Logged
|
"Data is not information, information is not knowledge, knowledge is not understanding, understanding is not wisdom." ~ Clifford Stoll
|
|
|
|
Barcelona
Offline
Newbie
Karma: 0
Posts: 23
Arduino hurts my brain... but i like it
|
 |
« Reply #13 on: December 21, 2010, 06:37:22 pm » |
thanks BroHogan,
I'm using sparkfun stuff.... pro mini 328p 3,3V and MMA7361 board. i was in doubt about taking the main board in 5V or 3,3, because in my project i have a 5V regulated, so it was possible to use any board. i finally choose the 3,3v because the MMA board i choose was not equipped with the 3,3v regulator...
so normally to keep the MMA waked up i can just put the 3,3V directly on the SL pin, no?
regards
|
|
|
|
|
Logged
|
|
|
|
|
Denver
Offline
God Member
Karma: 19
Posts: 776
Inactive - PM
|
 |
« Reply #14 on: December 21, 2010, 07:15:56 pm » |
lebenj,
If you have a 3.3V "Arduino" than you are safe in controlling the sleep pin directly. However, if you simply want "to keep the MMA waked up", you can just add a pullup resistor (~2K) between the SL pin and +3.3V. That way you save a pin - although you can't make it sleep when you want.
|
|
|
|
|
Logged
|
"Data is not information, information is not knowledge, knowledge is not understanding, understanding is not wisdom." ~ Clifford Stoll
|
|
|
|
|