LabVIEW Interface for Arduino Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

MMA8452 I2C issues?

I am using a MMA8452, on a sparkfun breakout PCB. I have the item working well using example C code on the arduino, but when I attempt to use the LabVIEW I2C vi's I cant seem to get it to work. I am trying to send to the WHO_AM_I register, it should return a 0x2A, its returning 0x00 0x63 0x34 0x81 0xE0 0x7E 0x64. It keeps returning the same data for any command I send it.

Any idea whats going on here?

0 Kudos
Message 1 of 7
(7,136 Views)

Hi,

I have experienced the same issue. MMA8452 does not respect pointer setting command. I.e. if I want to read data bytes on "interrupt-after-conversion-is-done" (start at addr 0x01 and read 6 bytes), MMA8452 sends out data starting at addr 0x00. Thus reading 7 bytes is needed (and that includes STATUS register located at 0x00).

(I was playing with the accelerometer using BusPirate).

It happens both in STANDBY and ACTIVE state (I suspect that being ACTIVE might cause the bug to be a feature, but I have tried that once more right now...)

So basically, you need to read all the registers from beginning...

Hope that helps.

Martin

0 Kudos
Message 2 of 7
(4,449 Views)

Hi,
I have experienced the same issue with the MMA8452Q breakout PCB from Sparkfun (https://www.sparkfun.com/products/10955)

Thanks ok1sob for your workaround, however with this it is not possible to read any registers higher than 0x06 since the sensor Auto-Increments the Address from 0x06 to 0x00. (Datasheet on page 18 (Table 11): http://www.freescale.com/files/sensors/doc/data_sheet/MMA8452Q.pdf)

However I think I have found the core of the issue:

In the afore mentioned Datasheet on page 16 (Single Byte Read) it says that:

"The Master (or MCU) transmits a repeated start condition (SR)

and then addresses the MMA8452Q ($1D) with the R/W bit set to “1” for a read from the previously selected register"

This means that after Writing which register we want to read we CAN NOT send a STOP-Condition before starting to read again, so we have to use a repeated start condition.

As described in the Bus-Specifications on Page 15 (Figure 13) (http://www.electro-tech-online.com/custompdfs/2011/06/UM10204.pdf).

In earlier versions of Arduino it was not able to accomplish this, and thus i think that when the LIFA was created this was the case.

However:

"As of Arduino 1.0.1, endTransmission() accepts a boolean argument changing its behavior for compatibility with certainI2C devices.

If true, endTransmission() sends a stop message after transmission, releasing the I2C bus.

If false, endTransmission() sends a restart message after transmission. The bus will not be released, which prevents another master device from transmitting between messages. This allows one master device to send multiple transmissions while in control. (a so called repeated start condition)

The default value is true." - http://arduino.cc/en/Reference/WireEndTransmission

So i was wondering if there already is a newer version of LIFA which has this function implemented,

or if someone is able to help me find a way to get this working, since i need this sensor to work for my Bachelor Thesis.

I hope i was able to help you understand the problem, and create a first step towards fixing this issue.

Benjamin

0 Kudos
Message 3 of 7
(4,449 Views)

To test this, you should change change line 235 to have false as the argument.  Then, run your LabVIEW code "as is" and see if it works.  If that doesn't work then you might need to create a new LIFA function that does the write and read all in a single LabVEIW call with the false condition supplied to the end transmission function.  If it does work, then you simply need to add another argument to the existing I2C write function (both in LabVIEWand the firmware) so that you can dynamically modify how the end transmission works.

0 Kudos
Message 4 of 7
(4,449 Views)

Thanks Benjamin,

I see I am blind and didn't go thoroughly through the datasheet. Shame on me ... I recall working with some other IC maybe a year ago, with the same need (in that case it didn't answer at al, so I knew something was goin wrong..)

Cheers

martin

0 Kudos
Message 5 of 7
(4,449 Views)

Thanks Nathan,

Your input made me want to see if it works, so went to Uni on a Saturday to try it.

So i checked if it works with two calls when i change the argument to false, but sadly that didnt work.
I know created a new function in LabVIEWInterface.ino which does a combined read-write on the I2C-Bus.

To do so i used the first free command code which seems to be 0x35 and inserted the following at line 557 of the Interface:

    /*********************************************************************************

    ** I2C COMBINED SEND/RECIEVE

    *********************************************************************************/           

           case 0x35:  // I2C Combined

      Wire.beginTransmission(command[3]);

      for(int i=0; i<command[2]; i++)

      {

        #if defined(ARDUINO) && ARDUINO >= 100

          Wire.write(command[i+5]);

        #else

          Wire.send(command[i+5]);

        #endif       

      }

      Wire.endTransmission(false);

                  i2cReadTimeouts = 0;

      Wire.requestFrom(command[3], command[4]);

      while(Wire.available() < command[4])

      {

        i2cReadTimeouts++;

        if(i2cReadTimeouts > 100)

        {

          return;

        }

        else

        {

          delay(1);

        }

      }

      for(int i=0; i<command[4]; i++)

      {

        #if defined(ARDUINO) && ARDUINO >= 100

          Serial.write(Wire.read());

        #else

          Serial.write(Wire.receive());

        #endif

      }

      break;

I also tried to create a LIFA-style Vi to use with it, however i did not change the Typedef. for the commands, and my artwork on the Icon is not exactly as it should be.

The VI uses a now Command Array, which includes: Command, #of Bytes to Write, Address, #of Bytes to Read and Data to Write.

For anyone that would like to use it, make sure that you have a version of the Wire.Lib that supports "Wire.endTransmission(false)" which does not create a stop condition.

I was only able to test it with the WHO_AM_I register of the MMA8452Q up till now, but im confident that all the others will work as well.

Thanks again for your help, and maybe this will help someone else in the future.

Benjamin

Download All
0 Kudos
Message 6 of 7
(4,449 Views)

Thanks for all of the replies! I had actually forgot about this post. Not longer after I posted it I had noticed in some example code I had that endTransmission(false) transmission was used as mentioned above. I searched through the library and changed the end condition to false. This did work!

0 Kudos
Message 7 of 7
(4,449 Views)