Important update: Arm Announces End of Life Timeline for Mbed. This site will be archived in July 2026. Read the full announcement.
Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
MMA7455L question
Hassan,
Have you seen this? http://mbed.org/users/espresso3389/programs/mma7455l_test/60ed4
If you still have problems, post your program so that the mbed comunity can help you.
Dave.
thank you Dave for your reply :) actually, i saw this link before and i had some problems understanding it, so i'll post my code (and it seems simpler for me :D )
this is the header file
#ifndef MMA7455L_PROGRAM #define MMA7455L_PROGRAM #include "mbed.h" class MMA7455L { public: MMA7455L(PinName _sdo, PinName _sdi, PinName _sck, PinName _cs, DigitalOut& myled, DigitalOut& myled2); // constructor float get_x(); float get_y(); float get_z(); void update_acceleration(); int Who_Am_I(); void calibrate(float maxx = 1, float minx = -1, float maxy = 1, float miny = -1, float maxz = 1, float minz = -1); int get_status(); int A_x, A_y, A_z; private: DigitalOut _CS; // is stands for chip select, or it may be called also slave selet (SS) DigitalOut led1; DigitalOut led2; SPI _spi; float accelerometer_status; int status(); float _factor; float _minx, _maxx; float _miny, _maxy; float _minz, _maxz; }; #endif <</code>> and this is the source file <<code>> #include "MMA7455L.h" // making some primary definitions for primary registers #define X_OUT 0x06 #define Y_OUT 0x07 #define Z_OUT 0x08 #define STATUS 0x09 #define X_OFF_LSB 0x10 #define Y_OFF_LSB 0x12 #define Z_OFF_LSB 0x14 #define WHO_AM_I 0x0F #define OFFSET_DRIFT_X_LSB 0x10 #define OFFSET_DRIFT_X_MSB 0x11 #define OFFSET_DRIFT_Y_LSB 0x12 #define OFFSET_DRIFT_Y_MSB 0x13 #define OFFSET_DRIFT_Z_LSB 0x14 #define OFFSET_DRIFT_Z_MSB 0x15 #define MODE_CONTROL_REGISTER 0x16 // from this register we can control what range of accelerations //can be used and what mode it operates on (whether stand by, on, // power down or what ever (see data sheet page 9) #define INTERRUPT_LATCH_RESET 0x17 //this register is responsible for making an interrupt if a certain //condition was detected, like a zero g or crossing certain thershold //(see page 15 in datasheet for more clarification) #define CONTROL_1 0x18 // this register is resposible for determining what axes are entabled // in measurment #define CONTROL_2 0x19 //for motion detection (OR condition) or free fall detection (AND condition) #define LEVEL_DETECTION_THRESHOLD_LIMIT_VALUE 0x1A // here we assign the value of the threholds // see examples in page 11 in data sheet #define PULSE_DETECTION_THRESHOLD_LIMIT_VALUE 0x1B #define PULSE_DURATION_VALUE 0x1C #define LATENCY_TIME_VALUE 0x1D #define DETECTION_SOURCE_REGISTER 0x0A //mainly used to know whether some event was detected // some useful auxillary constants #define MMA7455L_READ 0x00 //to know why read = 0 and write = 1, refer to page 18, last paragraph #define MMA7455L_WRITE 0x80 #define DATA_READY 0x01 MMA7455L :: MMA7455L(PinName _sdo, PinName _sdi, PinName _sck, PinName _cs, DigitalOut& myled, DigitalOut& myled2):_spi(_sdo,_sdi,_sck), _CS(_cs), led1(myled), led2(myled2) // constructor { _CS = 1; // means no interaction between the two devices _spi.format(8,0); _spi.frequency(8000000); //configuring the acceleromter registers //configuring the mode control register and seting it to measure 8g led1 = 1; _CS = 0; _spi.write(MMA7455L_WRITE | (MODE_CONTROL_REGISTER << 1) ); _spi.write(0x01); //here we specify that the range of measurement is [0,0] //which is the defalut, we specified the mode on which //the accelerometer operates, which is measurment, no //level or pulse detection for example _CS = 1; led1 = 0; //configuring the offset values for X _CS = 0; _spi.write(MMA7455L_WRITE | X_OFF_LSB); _spi.write(0xFF); _CS = 1; //configuring the offset values for y _CS = 0; _spi.write(MMA7455L_WRITE | Y_OFF_LSB); _spi.write(0xFF); _CS = 1; //configuring the offset values for Z _CS = 0; _spi.write(MMA7455L_WRITE | Z_OFF_LSB); _spi.write(0x28); _CS = 1; // configuring the interrupt latch led1 = 1; _CS = 0; _spi.write(MMA7455L_WRITE | (INTERRUPT_LATCH_RESET << 1) ); _spi.write(0x03); _CS = 1; led1 = 0; //configuraing the control 1 register led1 = 1; _CS = 0; _spi.write(MMA7455L_WRITE | (CONTROL_1 << 1) ); // notice that we made this bitwise operation because //the accel. itself specifies that there is a R?WR //bit and 6 adress bits and the rest is not important //so we need to make it zero anyway in order not to //truncate any part of the adress _spi.write(0x00); // which is the default anyway _CS = 1; led1 = 0; //configuring the control 2 regoster led1 = 1; _CS = 0; _spi.write(MMA7455L_WRITE | (CONTROL_2 << 1) ); _spi.write(0x00); // which is the defalut anyway _CS = 1; led1 = 0; //configuring level detection threshold limit value led1 = 1; _CS = 0; _spi.write(MMA7455L_WRITE | (LEVEL_DETECTION_THRESHOLD_LIMIT_VALUE << 1) ); _spi.write(0x2F); _CS = 1; led1 = 0; //configuring pulse detection threshold limit value led1 = 1; _CS = 0; _spi.write(MMA7455L_WRITE | (PULSE_DETECTION_THRESHOLD_LIMIT_VALUE << 1) ); _spi.write(0x2F); _CS = 1; led1 = 0; //configuring pulse duration value led1 = 1; _CS = 0; _spi.write(MMA7455L_WRITE | (PULSE_DURATION_VALUE << 1) ); _spi.write(0x2F); _CS = 1; led1 = 0; //configuring latency time value led1 = 1; _CS = 0; _spi.write(MMA7455L_WRITE | (LATENCY_TIME_VALUE << 1) ); _spi.write(0x2F); _CS = 1; wait(2); led1 = 0; A_x = A_y = A_z = 20; accelerometer_status = 6; calibrate(); } void MMA7455L :: calibrate(float maxx, float minx, float maxy, float miny, float maxz, float minz) { _minx = minx; _maxx = maxx; _miny = miny; _maxy = maxy; _minz = minz; _maxz = maxz; } int MMA7455L :: status() // determines whether the data is ready to be read or not { _CS = 0; _spi.write(MMA7455L_READ | (STATUS << 1) ); int value = _spi.write(0x00); //note that we put 0x80 in order to write. notice that //for writing, we need to have a 1 in the first bit sent //or written, and also notice that accelerometer LIS302 //opposite orders for writing and reading (read = 1, write = 0) _CS = 1; return value; } float MMA7455L :: get_x() { return A_x; } float MMA7455L :: get_y() { return A_y; } float MMA7455L :: get_z() { return A_z; } int MMA7455L :: get_status() { _CS = 0; _spi.write(MMA7455L_READ | (STATUS << 1) ); accelerometer_status = _spi.write(0x00); //note that we put 0x80 in order to write. notice that //for writing, we need to have a 1 in the first bit sent //or written, and also notice that accelerometer LIS302 //opposite orders for writing and reading (read = 1, write = 0) _CS = 1; return accelerometer_status; } void MMA7455L :: update_acceleration() { led2 = 1; wait(0.03); if ((get_status() & DATA_READY)) { led2 = 0; _CS = 0; led1 = 1; //calculating acceleration in x direction _spi.write(MMA7455L_READ | (X_OUT << 1) ); led1 = 0; wait(0.05); A_x =( _spi.write(0x00))/*((_spi.write(0x00)<<8) * 3.3 / 255) / 0.207*/; //float gradient = (2.0/(_maxx-_minx)); //A_x = (gradient*(float)(A_x)/16)+((-gradient*_maxx)+1); led1 = 1; //calculating acceleration in y direction _spi.write(MMA7455L_READ | (Y_OUT << 1) ); A_y = _spi.write(0x00); wait(0.05); led1 = 0; led1 = 1; //calculating acceleration in z direction _spi.write(MMA7455L_READ | (Z_OUT << 1) ); A_z = _spi.write(0x00); _CS = 1; wait(0.05); led1 = 0; // here we make the calibration for the readings } } int MMA7455L :: Who_Am_I() { _CS = 0; _spi.write(MMA7455L_READ | (WHO_AM_I << 1) ); int value = _spi.write(0x00); _CS = 1; return value; } <</code>> and this is the main file <<code>> #include "mbed.h" #include "MMA7455L.h" DigitalOut myled(LED1); DigitalOut led2(LED2); DigitalOut led3(LED3); Serial pc(USBTX, USBRX); int main() { pc.printf("starting...\r\n"); MMA7455L acc(p5,p6,p7,p14, led2, led3); int stat = 5; pc.printf("constructor completed\r\n"); while(1) { pc.printf(" status is %d\r\n",acc.get_status() & 0x01 /*Who_Am_I()*/ ); wait(0.06); acc.update_acceleration(); pc.printf("%d %5d %5d\r\n\n\n", acc.A_x, acc.A_y, acc.A_z); } }
any help???
by the way, there is another strange behaviour i observed and forgot to tell you about ... i tried to assign some value in the offset registers for x, y, and z as a type of testing, and i understood from the data sheet that this value should be subtracted from the readings, but actually i have the same readings as if they were not set ... any explaination??? thank you in advance :)
another note is that if the accelerometer is left in a level position, the readings for x and y is in the order of 250, while the value for z is in the order of 10 ... is it normal?
Hassan,
The values you are getting are wrong if your accelerometer is flat (ie z is pointing up or down). The values you should see are x and y close to 0 and z = approx +-1g. From the data sheet there are 3 possible values dependent on what range you use, 1g will be 64, 32 or 16. To work out the G value you need to divide 9.81 or your local G value by the count/g, ie 9.81/64 = 0.15328125, which you then multiply by the returned value. Also have you setup the Mode Control Register ?
Dave.
thank you Dave very much for you reply and i really apprecite it. i think i managed to fix the problem. i eventually had values of ig in z direction when the accelerometer is flat, while having x and y reading near zero. my misstake was simply declaring the acceleration values in the class body as being int. when i tried to delcare them as "signed char", i had much better and more reasonable results, and the rest was simple, deviding by the sensetivity and subtracting the offset value (measured with accelerometer at rest and in level position). but would you please do me a favour and tell me what is the difference between asigining a byte read through SPI as "int" or "signed char" ? thank you so much in advance :)
Hassan,
Good to hear you have fixed your problem! The difference between an Int and a signed char is an int is 32 bits ands the signed char is 8 bits,(on a 32bit system). To learn more go here http://www.cplusplus.com
edit: or here http://www.cplusplus.com/doc/tutorial/variables/
A clue is the sign bit! And where it is placed.
Dave
hi everybody :) i'm working on a project, where i need to interface the MMA7455L digital acceleromter to the mbed through SPI interface... my problem is that i simply can't calibrate the readings i have, and as a matter of fact, i have pretty strange values ! i need only to operate this accelerometer on the measurement mode, and i managed to declare and define the required registers, but as i said, i have values, probably in counts, and i can't convert them back to "g" 's ! any help???