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.
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.
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 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] ####
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 (Live Fast - Code Young: ADXL345 accelerometer breakout board + Arduino and Processing) and it worked fine on my Arduino but I want to get it working on a FEZ 'cause FEZs are so much cooler
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.
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!!!
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.
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
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.
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.
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.
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());
}
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?