Main Site Documentation

Adxl345 i2c


#1

My firmware version is V 4.0.3.0.

I have an ADXL345 accelerometer and I am trying to talk to it using I2C. The specs for it can be found here http://www.sparkfun.com/datasheets/Sensors/Accelerometer/ADXL345.pdf

I can’t seem to communicate with it at all. I know it works as I have a sketch for an Arudino that works just fine. Here is some code that I think should work but doesn’t.


            I2CDevice.Configuration con = new I2CDevice.Configuration(0x53, 400);
            I2CDevice i2c = new I2CDevice(con);
            I2CDevice.I2CTransaction[] xActions;

            //create transactions (we need 2 in this example)
            xActions = new I2CDevice.I2CTransaction[2];
            // create write buffer (we need one byte)
            byte[] RegisterNum = new byte[1] { 0x00 };
            xActions[0] = i2c.CreateWriteTransaction(RegisterNum);
            // create read buffer to read the register
            byte[] RegisterValue = new byte[1];
            xActions[1] = i2c.CreateReadTransaction(RegisterValue);
            // Now we access the I2C bus and timeout in one second if no responce
            int rtnVal = i2c.Execute(xActions, 1000);
            Debug.Print(RegisterValue[0].ToString());

I think this should read the device id into RegisterValue[0] but rtnVal is always 0 indicating that no communication occurred. I have the device wired up as shown on page 10 of the specs I linked in above. Any help would be greatly appreciated.

I’ll admit up front I’m pretty new to embedded development even though I’ve been programming for years so I might be doing something really stupid.

Thanks again


#2

Due to the 7bit-addressing of I2C bus you have to shift the address one bit to the right-hand side.

So in your case change 0x53 to 0xA9 and try again.

The last bit is for indicating read or write operation.


#3

Ahh ok, I did read that somewhere and because of it wrote a loop that tried to communicate on every address from 0 through 127 with no luck. I was pretty fried by that point though so I could have messed up other parts of the code without realizing it. I’ll give it another try when I get home tonight and post my results.

Thanks!


#4

I get an exception thrown on the i2c.Execute call when I use 0xA9 as the device address. The exception message is this:

An unhandled exception of type ‘System.ArgumentException’ occurred in Microsoft.SPOT.Hardware.dll

:frowning:


#5

You have “argument exception”. This is not related to the address but related to the “arguments” you are passing.

Check what you are sending to “execute”…check other examples…check the ebook :wink:


#6

Hi Chimp, I get that exact same exception for any address over 127 (0x7F) so that’s why I thought it was related to the address and not the transactions. I’m still using the same code that I first posted except I’m using an address of 169 (0xA9) now instead of 83 (0x53). It was actually copied out of the eBook originally :wink: Do you see what might be causing the “argument exception” in that code?

Thanks Again!

edit: This is what is being printed to the Output window when the exception is thrown. I realized it might be useful.

A first chance exception of type ‘System.ArgumentException’ occurred in Microsoft.SPOT.Hardware.dll
#### Exception System.ArgumentException - 0xfd000000 (1) ####
#### Microsoft.SPOT.Hardware.I2CDevice::Execute [IP: 0000] ####
#### FirstMF.Program::Accelerometer_I2C [IP: 004b] ####
#### FirstMF.Program::Main [IP: 000a] ####


#7

The I2C address is 7 bit so any number over 127 is not valid, this is normal.

I couldn’t read your code because you didn’t “C# format it” so I just ignored it :frowning:
I modified your post and it is more readable now :wink:

Looking at your code, I am not seeing any error at all…

…so I am looking at datasheet you posted and it says

[quote]An alternate I2C address of 0x53 (followed by the R/W bit) can be chosen by grounding the SDO/ALT ADDRESS pin (Pin 12)."
[/quote]

So, do you have this pin grounded?

If yes, then did you make sure you have power on the pins? Did you double check the wires? Is this a shield or you are wiring the chip?


#8

Sorry about not “C# format”, my bad. I’ll do that from now on.

I do have the SDO pin grounded. I’m not using a shield but I got it on a breakout board so the only wiring I’m really doing is hooking everything up to VCC and ground as instructed then connecting SCL to FEZ analog pin 5 and SDA to FEZ analog pin 4. I’m using 10k ohm resisters to make these connections as instructed by someone else who successfully wired this up to an Arduino. I followed what he did (http://codeyoung.blogspot.com/2009/11/adxl345-accelerometer-breakout-board.html) and it worked fine on my Arduino but I want to get it working on a FEZ 'cause FEZs are so much cooler :smiley:

I’m pretty sure the wiring is good as I’ve checked it many times (since it seems like the most obvious place for a problem) and anytime I hook it up to my Arduino I can talk to it no problem.

Since I2C address is 7bit shouldn’t 0xA9 which is 169 in decimal be invalid? In binary 0x53 is [1010011] so should I remove the LSB to get [101001] (0x29) or should I remove the MSB to get [010011] (0x13)? I’m not sure what algorithm was used to change 0x53 to 0xA9.

Thanks!


#9

No! 7-bit => max of 127

Usually, companies give you the address on how it shows on the bus (0xA9) but that is not the actual address. The address would be 0xA9>>1 which is 0x53

Are you using FEZ Domino or FEZ Mini? Your text is for FEZ Mini but your are posing in FEZ Domino board!!!

If your board is FEZ Domino then we have found the error! See this http://www.tinyclr.com/downloads/Domino/Broch_FEZ_Domino.pdf


#10

I have a FEZ Domino. I’m confused as to where a FEZ Mini comes in. Is the code I’m writing not appropriate for a FEZ Domino? I’m reading the brochure you linked me to but I’m pretty sure I’ve already read that. I’m not sure what it has to do with my problem making I2C work on my FEZ Domino.

Isn’t 0xA9>>1 = 0x54?

Thanks for all your effort so far!


#11

So I was just re-reading the specs and I saw this:

So does this mean I should have two i2c instances, one using 0xA6 and one using 0xA7? Then I would use which ever one correlates to what I’m trying to do (read or write)? That doesn’t seem to follow all the examples I’ve seen but I’m willing to try anything at this point :slight_smile:


#12

Ok good but then …

You still do not see the problem? :smiley:

Look at the FEZ Domino document and see where the I2C pins go :wink: They are Di2 and Di3 B)


#13

OK so I think I’m understanding this a little better. 0xA6 and 0xA7 are used for write and read respectively if you right shift either of them by 1 you get 0x53 for both. SO 0x53 is the correct address to use for the device. Therefore this is the correct way to instantiate the I2C object


//create I2C object
I2CDevice.Configuration con = new I2CDevice.Configuration(0x53, 100);
I2CDevice i2c = new I2CDevice(con);

If this is true then cypher (while I appreciate his attempt to help) was just totally off his rocker when he said

If that is all true then I’m back where I started with my original post. Let me know if this is not true.

Thanks


#14

Oh crap!!! Thank you!! SOOO sorry. I’ll give that a try.

edit: Yeah that worked. Damn I feel dumb. I just assumed the I2C pins would be the same on the FEZ as they are on the Arudino. You’re all Freakin’ awesome for sticking with me.


#15

You are baned from using this forum for not reading the docs correctly!!!

I am just kidding of course! I am glad it worked for you.

By the way, the pins are the same on “USBizi”, the core chipset, but we have them connected differently on the FEZ boards for Arduino/BS2/POP…etc. compatibility reasons.


#16

Well now that I have the thing hooked up correctly things are working beautifully. If anyone else is interested here is a simple class I made for this device that could be a good starting point:


class ADXL345_I2C
    {
        //datasheet for accelerometer: http://www.sparkfun.com/datasheets/Sensors/Accelerometer/ADXL345.pdf
        //SDA signal to pin Di3, SCL signal to pin Di2
        //With SDO grounded
        //Address to write = 0xA6;
        //Address to read = 0xA7;
        //  -> I2C address = 0x53   

        ushort I2C_ADR;
        int CLOCK_SPEED;        
        I2CDevice i2c;

        public ADXL345_I2C() : this(400) { }
        public ADXL345_I2C(int ClockSpeed)
        {
            I2C_ADR = 0x53;
            CLOCK_SPEED = ClockSpeed;

            //create I2C object
            I2CDevice.Configuration config = new I2CDevice.Configuration(I2C_ADR, CLOCK_SPEED);
            i2c = new I2CDevice(config);

            //Turn device on and put in read mode
            I2CDevice.I2CTransaction[] xActions;
            xActions = new I2CDevice.I2CTransaction[3];
            xActions[0] = i2c.CreateWriteTransaction(new byte[2] { 0x2D, 0x00 });
            xActions[1] = i2c.CreateWriteTransaction(new byte[2] { 0x2D, 0x16 });
            xActions[2] = i2c.CreateWriteTransaction(new byte[2] { 0x2D, 0x08 });
            if (i2c.Execute(xActions, 1000) == 0)
                throw new Exception("Failed to communicate on I2C");         

        }

        public void Read(out int x,out int y,out int z)
        {            
            //read from device
            I2CDevice.I2CTransaction[] xActions;
            byte regAddress = 0x32;  //first axis-acceleration-data register on the ADXL345
        
            //read the acceleration data from the ADXL345
            byte[] readBuf = new byte[6];//buffer for reading 6 bytes
            xActions = new I2CDevice.I2CTransaction[2];
            xActions[0] = i2c.CreateWriteTransaction(new byte[1] { regAddress });
            xActions[1] = i2c.CreateReadTransaction(readBuf);
            if (i2c.Execute(xActions, 1000) == 0)
                throw new Exception("Failed to communicate on I2C");

            //Credit: http://codeyoung.blogspot.com/2009/11/adxl345-accelerometer-breakout-board.html
            //each axis reading comes in 10 bit resolution, ie 2 bytes.  Least Significat Byte first!!
            //thus we are converting both bytes in to one int
            x = (((int)readBuf[1]) << 8) | readBuf[0];
            y = (((int)readBuf[3]) << 8) | readBuf[2];
            z = (((int)readBuf[5]) << 8) | readBuf[4];            
        }
    }

And here is an example of it’s usage:


ADXL345_I2C Accel = new ADXL345_I2C();
            while (true)
            {
                int x,y,z;
                Accel.Read(out x, out y, out z);
                Debug.Print("x=" + x.ToString() + ", y=" + y.ToString() + ", z=" + z.ToString());
            }

FEZ is awesome!!


#17

Your class will be lost overtime between the thousands of posts. It would be really nice if you add it to the wiki (link removed)


#18

Ok I’ll do that :slight_smile:


#19

I feel stupid asking this, but I cant figure out this i2c stuff. Ive copied the example from mmadink above but intellisense cant figure out the CreateWriteTransaction method so Im probably missing a reference, but which one?
Can anyone help me?


#20

replace i2c With I2cDevice its a 4.1 thing.