Unable to read ITG3200 (6DOF) with i2c

Hello Guys,

This is my first post here. So far learning expierence with spark core is great. I dont use webide and compile using make and flash using dfu util.

I have a imu 6DOF and trying to interface it with spark core using i2c (6dof only supports i2c). I have been trying to establish connection with gyro[itg3200](also accelometer[ADXL345]) of imu but without success.

I have come across other posts having problems with i2c,

After going through above post i replaced the spark_wiring_i2c.cpp/h with the latest one available at (satishgn)

but the new change didnt help. I pulled out only spark_wiring_i2c.cpp/h files.

I am following sparkfun link for reference, ITG-3200 Hookup Guide - SparkFun Learn

My code is somewhat like this,

          Wire.enableDMAMode(true);     /// is it really needed
          Wire.begin();
          len = itgRead(GYRO_ADDR, 0x00);   ///WHO_AM_I register

and itgRead() is as follows,

uint8_t itgRead(uint8_t address, uint8_t registerAddress)
{
  unsigned char data=0;
 
 Wire.beginTransmission(address);
  Wire.write(registerAddress);
  Wire.endTransmission();

  Wire.beginTransmission(address);
  Wire.requestFrom(address, 1);

   while (!Wire.available()) ;
  data = Wire.read();
  
  Wire.endTransmission();
  return data;
}

itgRead() and requestFrom() always give out 0. 

Let me mention that i am not connecting any resistor between spark core and imu. SDA/SCL of imu is connected directly to SDA/SCL of the core.
No good results with r without dma enabled.

Please guide me.
Thanks.

You will need Pull-up resistors for I2C to work.

Also, did you short the CLKIN jumper at the bottom?

https://www.sparkfun.com/datasheets/Sensors/IMU/6DOF-Digital-v10.pdf mentions pullup resistor across SDA/SCL pins for gyro. Are you talking about any other pullup resistors ?

Also the schematics mentions CLKIN connected to ground.

DO you think i should be doing something more?

thanks

I’m confused.

This is the product right? https://www.sparkfun.com/products/11977

or https://www.sparkfun.com/products/10121?

Try to remove this line: Wire.enableDMAMode(true);


It’s the second link… imu combo…

Removing enabledmaMode() dosnt help…

I’m not sure if it’s that straightforward to use but you probably need a library for it:

I will give it a try… thanks for the link

it seems my 6dof is not working … i will update once i get a new one (which i have ordered) and work on it.

The I2C feature is currently broken

thanks for the update … so when will the new release be made…

i am eagerly waiting…

we’re working on it! @zachary will be sharing an update soon

thanks Zach…

I am testing the recent changes (0.34) made to i2c. Good news is new changes work.

Bad news is it works 3 to 4 times out of 10. In the function endTransmission()

while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
fails.
Core is not able to catch response for tx mode. This is not an issue with master receiver mode.

As i said the above check succeeds 3 to 4 times out of 10 tries.

I cant claim the issue is with imu since it works flawlessly with the raspberry pi.

Suggestions are welcome and i shall keep you guys updated.

Did you managed to get it working 10/10 times on the Spark core before the I2C issue?

If not, it’s hard to pinpoint saying that the code changes made it work unreliably. It can but i don’t think so since i haven’t seen anyone commenting about their I2C issues after the recent firmware push.

Also, i presume you did the library porting?

Previously it never worked for me. And I have taken the new changes in its entirety.

I will double check from my side if I am doing any mistakes or not.

@sanjukul, @kennethlimcp, the Sparkfun Arduino code requires some thinking for the port. @sanjukul can you post your ported code for review?

define REQ_DATA_LEN 32 // this is the size of BUFFER_LENGTH
define I2C_SETUP 1
define I2C_START 2
static uint8_t i2c_stMch = 0xFF;

extern void Schedule_10ms(void (*f)());

void I2C_Init()
{
	Schedule_10ms(I2C_rw);

	i2c_stMch = I2C_SETUP ;
}

//this function is called every 10ms
void I2C_rw()
{
	static uint8_t len = 255;

	switch(i2c_stMch)
	{
	  case I2C_SETUP:
		  /* Set the Init parameters for i2c */
		  Wire.enableDMAMode(true);

		  Wire.begin();

		  Serial.println("SETUp");

		  i2c_stMch = I2C_START;

		  break;
	  case I2C_START:

		  Serial.println( "start");
		  len = itgRead(ACCL_ADDR, 0x00);
		  Serial.println( len);


		  if( len == 0xFF)
		  {
			 Serial.println("Error Reading");
			 i2c_stMch = 0xFF;    // come out and do nothing    
		  }

		  break;
	  default:
		  break;
	}
}

void itgWrite(uint8_t address, uint8_t registerAddress, uint8_t data)
{
	//Initiate a communication sequence with the desired i2c device
	Wire.beginTransmission(address);
	//Tell the I2C address which register we are writing to
	Wire.write(registerAddress);
	//Send the value to write to the specified register
	Wire.write(data);
	//End the communication sequence
	Wire.endTransmission();
}

uint8_t itgRead(uint8_t address, uint8_t registerAddress)
{
	//This variable will hold the contents read from the i2c device.
	unsigned char data=0;
	system_tick_t _millis;

	//Send the register address to be read.
	Wire.beginTransmission(address);
	//Send the Register Address
	Wire.write(registerAddress);
	//End the communication sequence.
	Wire.endTransmission();

	//Ask the I2C device for data
	//Wire.beginTransmission(address);
	Wire.requestFrom(address, 1);

	Serial.println( "itgRead");
	//Wait for a response from the I2C device

	_millis = millis();
	while (!Wire.available()) 
	{
		if(millis() - _millis > 2000)
		return 0xFF;
	}

	data = Wire.read();

	Serial.println( "Yes Available");
	Serial.println(data);
	//End the communication sequence.
	//Wire.endTransmission();

	//Return the data read during the operation
	return data;
}

I’ve edited your post to properly format the code. Please check out this post, so you know how to do this yourself in the future. Thanks in advance! ~Jordy

Thanks @Jordy.

@peekay123: I have posted the my code. I2C_rw() is called every 10ms. As of now i am trying to get the device id which is usually present in WHO_AM_I register (0x00) ( GYRO and ACCEL).

i will display error message if read fails.

@sanjukul, your code “looks” fine. Am I correct in assuming you can communicate with the ADXL345 without problems? Have you tried running an I2C bus scanner to see if the ITG shows up? I am looking at how the Core firmware and Arduino handle a device address to be sure they match.

WIth I2C bus scanner only ADXL345 shows up. ITG3200 does not show up. I got it confirmed with my raspberry pi too.

The combo board that i have has only accelermeter working. Gyrometer is not detected may be its gone bad.