Skip to main content
Topic: MMA7455L C Library and Arduino Example (Read 22460 times) previous topic - next topic

MMA7455L C Library and Arduino Example

Hi,

I received my MMA7455L breakout board yesterday (looong shipping time due to christmas), so I made a little library for conveniently using it.  It talks to the MMA7455L using software-SPI achieving about 1 MHz data rate on a 16 MHz Arduino.  The licensed used is CC-BY-SA.  Please find the code attached.

I have two questions:
* For calibration 0g I had to use quite large values e.g. -23 in y direction.  It this normal?
* Without calculating an average, the values for the acceleration jump around quite randomly with up to +-12 counts.  Is this also supposed to be so?

Have fun,
Markus

Re: MMA7455L C Library and Arduino Example

Reply #1
The deviation seems to be ok.  I recorded 20000 values and their distribution function is pretty much a Gaussian:

-16  1
-14  3
-13  5
-12  12
-11 . 32
-10 .. 60
 -9 ..... 125
 -8 ............ 260
 -7 .................. 385
 -6 ............................... 641
 -5 ........................................... 876
 -4 .......................................................... 1188
 -3 ............................................................................. 1567
 -2 ....................................................................................... 1765
 -1 .............................................................................................. 1898
  0 ................................................................................................... 1989
  1 ................................................................................................. 1951
  2 .......................................................................................... 1821
  3 ............................................................................. 1557
  4 ............................................................. 1244
  5 .............................................. 935
  6 ................................. 688
  7 ..................... 440
  8 .......... 237
  9 ...... 155
 10 ... 85
 11 .. 44
 12  19
 13  10
 14  4
 15  3

Re: MMA7455L C Library and Arduino Example

Reply #2
Here is an updated version of the library alone, adding a moving average filter running in the ISR.

Re: Re: MMA7455L C Library and Arduino Example

Reply #3
Hi, Markus, I also have the MMA7455L, I´m trying to wire it to the arduinoñ. Could you give me some help, Schematic or tips to achieve this. Then I´ll try your code for the testting.

Thanks A lot

Pitu

Re: Re: MMA7455L C Library and Arduino Example

Reply #4
Hi Pitu,

I am quite convinced, that the observed behavior is normal for such a sensor.  I made some tests with a BMA020, a similar sensor from BOSCH, and it shows basically the same characteristics.  So the code does not need being tested :)

However, if you want to use it to interface with your MMA7455L, you must connect it to some PORTD pins of your Arduino.  The #define lines at the beginning of the .c file tell which ones.  IIRC I used it with a Teensy, so you will probably have to use some other PORTD bits, because the Arduino has its UART on some of the used bits, so you must change them to avoid this conflict.

Have fun,
Markus

Re: Re: MMA7455L C Library and Arduino Example

Reply #5
Hi Markus,

I was working with your library today and had a few questions.

Code: [Select]
int16_t mma_read10( uint8_t address )
{
    int16_t value = 0xc000;
    MMA_PORT &= ~MMA_SS;
    swspi_shift( address << 1 );
    value = swspi_shift( 0 ) << 6; // low byte
[b][u]    swspi_shift( ( address + 1 ) << 1 );[/u][/b]
    value |= swspi_shift( 0 ) << 14; // high byte
    MMA_PORT |= MMA_SS;
    return value >> 6;
}

In this function, the address is bit-banged between the bytes. I think the registers can be read continuously, one after the other. If not, isn't a CS up and down needed before sending another address value?
Got a question? Please ask in the forum for the fastest answers.

Re: Re: MMA7455L C Library and Arduino Example

Reply #6
The datasheet is a bit sparse about this.  On page 18 is reads "CS is driven low at the start of a transmission.  CS is then driven high at the end of a transmission."  And the next paragraph reads "Read and write commands are completed in 16 clock pulses or in multiples of 8, in the case of a multiple byte read/write."

Did you test if it works when you remove the line you marked bold?

Re: Re: MMA7455L C Library and Arduino Example

Reply #7
I can't seem to get a + or - any value at all from the top byte register. If it is sequential (like I2C mode) then you should be able to read all 6 bytes of the 3 axis in a row, but when I do that I get the same value for the low byte of every register.

The H byte of each axis is supposed to latch in place when you read from the low, which infers to read it immediately. I have never gotten any value for the upper byte though when I read it sequentially (always 0). I think I should at least get bit 9 with +/- indication sometimes.

If I read L and H in two separate operations I still never get a value in the H byte. I think this is what your code tries to do, but it lacks the CS transition in between each read. I think your code would be correct like this instead:

Code: [Select]
    MMA_PORT &= ~MMA_SS;
    swspi_shift( address << 1 );
    value = swspi_shift( 0 ) << 6; // low byte
---> MMA_PORT |= MMA_SS; //CS high
--->MMA_PORT &= ~MMA_SS;//CS low again
    swspi_shift( ( address + 1 ) << 1 );
    value |= swspi_shift( 0 ) << 14; // high byte
    MMA_PORT |= MMA_SS;
    return value >> 6;

I am about to work on it a little more now, I will try the 8bit mode too and post an update. I'm working on the code for the USB POV Toy with accelerometer, but I'm having a terrible time getting it going.
Got a question? Please ask in the forum for the fastest answers.

Re: Re: MMA7455L C Library and Arduino Example

Reply #8
IIRC it worked fine when I experimented with it using a Teensy.  If time permits, I will have another look at it on the weekend.

 

Re: Re: MMA7455L C Library and Arduino Example

Reply #9
I think you used it for that cool demo with the LCD display and cube that aligns upright :) I don't want to take up your time, I'll check it out and get it going :)
Got a question? Please ask in the forum for the fastest answers.

Re: Re: MMA7455L C Library and Arduino Example

Reply #10
I did some testing and it seems that if I comment out the line which sends the second address, it does not work anymore.  So I would guess that the reading address is not auto-inclremented by the MMA7455L when trying to do consecutive reads.  If the MMA755L expects alternating address/data transfers, this would explain, why it is not necessary to set the SS pin to high and low between the two reads.  So it seems the code is ok like it is.

Ian, did you also do some testing?

Re: Re: MMA7455L C Library and Arduino Example

Reply #11
I couldn't get reliable data from 10 bit, so I went to 8bit mode instead for now. I am getting ok data, but it seems to bounce around a lot near the center of each axis. Like you, I have a big calibration value on all axis.

I needed to actually see the data to get my head around it, so I made two scripts with Processing:
http://processing.org/

One graphs the X/Y/Z values, the other is the beginning of a program to show a 3d cube like you did that reflects the data from the sensor.

This is totally hacked together and uses a dead simple protocol.  The app sends 0x01 to request a reading. uC replies with XYZ values as signed bytes.

I'm going to read up and try to duplicate your cube control as a Processing demo. If you have time and access, would you please share a code excerpt from the cube project that shows how you calculate the cube position?
Got a question? Please ask in the forum for the fastest answers.


Re: Re: MMA7455L C Library and Arduino Example

Reply #13
thank you, checking it out now.
Got a question? Please ask in the forum for the fastest answers.

Re: Re: MMA7455L C Library and Arduino Example

Reply #14
Quote from: Markus Gritsch
Of course, please find the code belonging to this video [1] attached.


Hi markus
I tested your library  I tried so much but I cant set the ofset  I tried to calibrate the 3 axis ofset value in falat posion (that x and y should around zero and z around 64 in 2g mode) but  I cant reach even close to zero I dont know why  it is my code below :


              mma_write( MMA_MCTL,  0x5) ;    //2g-spi 4w-self test on-   
              s=mma_read(  MMA_MCTL );
                mma_write( MMA_I2CAD,  MMA_I2CDIS_bit );
                mma_write( MMA_CTL1,  0xc0 );   
             
                  mma_wait_until_ready();
                x1 = mma_read10( MMA_XOUT10 ); 
                  y1= mma_read10( MMA_YOUT10 );
                    z1= mma_read10( MMA_ZOUT10);
            delay_ms(100);
          mma_calibrate_offset(x1,y1,z1); 
            delay_ms(200);
        I tried the calibrating section  in a loop for many time but never get close to zero in x an y axis they are always stay around -30 for x and -40 for y ( my mma is in flat position top to the sky and soldering pads to the earth)
THANKS