Dangerous Prototypes

Other projects => Past projects => Breakout boards => Topic started by: Markus Gritsch on January 12, 2011, 12:40:11 pm

Title: MMA7455L C Library and Arduino Example
Post by: Markus Gritsch on January 12, 2011, 12:40:11 pm
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
Title: Re: MMA7455L C Library and Arduino Example
Post by: Markus Gritsch on January 12, 2011, 03:25:44 pm
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
Title: Re: MMA7455L C Library and Arduino Example
Post by: Markus Gritsch on January 17, 2011, 04:23:43 pm
Here is an updated version of the library alone, adding a moving average filter running in the ISR.
Title: Re: Re: MMA7455L C Library and Arduino Example
Post by: Pitu on March 16, 2011, 05:23:59 pm
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
Title: Re: Re: MMA7455L C Library and Arduino Example
Post by: Markus Gritsch on March 16, 2011, 09:10:35 pm
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
Title: Re: Re: MMA7455L C Library and Arduino Example
Post by: ian on September 29, 2011, 03:33:57 pm
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?
Title: Re: Re: MMA7455L C Library and Arduino Example
Post by: Markus Gritsch on September 30, 2011, 01:09:43 pm
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?
Title: Re: Re: MMA7455L C Library and Arduino Example
Post by: ian on September 30, 2011, 01:55:36 pm
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.
Title: Re: Re: MMA7455L C Library and Arduino Example
Post by: Markus Gritsch on September 30, 2011, 02:07:32 pm
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.
Title: Re: Re: MMA7455L C Library and Arduino Example
Post by: ian on September 30, 2011, 02:33:28 pm
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 :)
Title: Re: Re: MMA7455L C Library and Arduino Example
Post by: Markus Gritsch on October 02, 2011, 09:12:45 pm
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?
Title: Re: Re: MMA7455L C Library and Arduino Example
Post by: ian on October 04, 2011, 12:23:54 pm
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/ (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?
Title: Re: Re: MMA7455L C Library and Arduino Example
Post by: Markus Gritsch on October 04, 2011, 12:51:43 pm
Of course, please find the code belonging to this video [1] attached.

[1] http://www.youtube.com/watch?v=Ez3JnTUxack (http://www.youtube.com/watch?v=Ez3JnTUxack)
Title: Re: Re: MMA7455L C Library and Arduino Example
Post by: ian on October 04, 2011, 01:36:10 pm
thank you, checking it out now.
Title: Re: Re: MMA7455L C Library and Arduino Example
Post by: samisin on January 19, 2012, 02:23:59 pm
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
Title: Re: Re: MMA7455L C Library and Arduino Example
Post by: Markus Gritsch on January 19, 2012, 02:38:00 pm
Yes, IIRC, I also tried some automatic calibration routine, but had the same problems as you for which reasons whatsoever.  In the end I decided to hardcode my offset values in a static call to mma_calibrate_offset() as can be seen in the example file MMA7455L.pde.
Title: Re: MMA7455L C Library and Arduino Example
Post by: errolt on January 23, 2012, 02:43:09 pm
The calibration routine is incomplete.

The XYZ values should not just be written to those addresses.

This is what should happen, if I remember correctly...


Also note:
The value for Z should be offset to 64, not 0, so use (Z-64) as the value for Z.
I can't remember if the XYZ reading should be negated before being added to the old offset value.