(solved) I2C problem (communication stop after like 3 seconds)

Hello, i am using 3x I2C devices, motor driver , I2C gyro (ITG3200) and I2C acc (ADXL345)

I had a gyro with analog output, and when i used motor + analog gyro + ADXL345, everything worked correct!

Now i order ITG3200, and motor only work for first 3 seconds.

And i know it's because ITG3200 gyro, because i tryed to work with both, without ADXL345 and same problem happens.

Any help would be very thankfull!!

Can you create links to datasheet ? How are they connected ? What is the value of the pull-ups on I2C bus ? Schematic ?

Krodal:
Can you create links to datasheet ?
How are they connected ?
What is the value of the pull-ups on I2C bus ?
Schematic ?

Hello, thank your for reply
The schemathic is the follwing:

ITG3200 datasheet: http://invensense.com/mems/gyro/documents/PS-ITG-3200-00-01.4.pdf
ADXL345 datasheet: http://www.analog.com/static/imported-files/data_sheets/ADXL345.pdf
MD25 motor driver datasheet: http://www.robot-electronics.co.uk/htm/md25tech.htm (using I2C mode)

MD25 with ADXL345 only, they work well

But MD25+ITG3200 they dont work together, they run fine for like 2-3seconds and then ITG3200 freezes stops sending data

Thanks for all the information. As far as I can tell, there's nothing wrong with it. I got a lot of comment on this page: http://arduino.cc/playground/Main/I2CBi-directionalLevelShifter But it's good to see you try to do the right thing.

Do you use the Wire library? I hope you don't mix two I2C drivers. Do you use a library for the ITG3200 ? Perhaps there's an error in the library leaving the I2C-bus in a undesired state.

Perhaps you could add a delay in the software, after you communicate with a I2C device.

Or you could try a test: Communicate with the ADXL345 and the MD25. After that communicate with ITG3200 and the MD25.

So you have to do some test, since the problem is not obvious. It could also be a bad power supply, or a bad connection somewhere.

Krodal: Thanks for all the information. As far as I can tell, there's nothing wrong with it. I got a lot of comment on this page: http://arduino.cc/playground/Main/I2CBi-directionalLevelShifter But it's good to see you try to do the right thing.

Do you use the Wire library? I hope you don't mix two I2C drivers. Do you use a library for the ITG3200 ? Perhaps there's an error in the library leaving the I2C-bus in a undesired state.

Perhaps you could add a delay in the software, after you communicate with a I2C device.

Or you could try a test: Communicate with the ADXL345 and the MD25. After that communicate with ITG3200 and the MD25.

So you have to do some test, since the problem is not obvious. It could also be a bad power supply, or a bad connection somewhere.

Hello, yes i use wire.h library, like i said it works for like 3 seconds :D I already tryed to add the delays, same problem.

My power supplys are the following: 5V and 3,3V are provided by arduino output's

Motors are supplyed with 12V provided by a transformer.

What u mean with I2C drivers? if you are talking about address, i checked it already, and they are all different!

Ok i will do that tests right now :)

Thank you so much for trying to help me

ADXL345 + MD25 = everything works just fine

Then i remove ADXL345 and i add ITG3200

ITG3200 + MD25 = works fine for first 1-3 seconds and them freezes.

I just figured out , if i remove SDA wire from ITG3200, MD25 start working fine again, if i re-wire SDA wire to ITG3200, MD25 stop's again

With different drivers I ment for example mixing the Wire library with other libraries for i2c that use their own code.

So you use the Wire library for everything? That's good.

I assume you have the power supply at the ITG decoupled with 100nF, and have also the other capacitors for the ITG sensor. And the AD0 is connected to ground. Did you accidently connect the interrupt output, or is it shortcut to the SDA line ?

The MD25 will turn the motors off for safety, if there is no i2c communication (with the MD25) for two seconds. So it seems that the ITG3200 blocks the i2c-bus, and the MD25 turns the motors off for safety.

My best guess would be that it is a software problem in the i2c communication with the ITG3200.

I found libraries for the ITG3200 here: - http://code.google.com/p/itg-3200driver/ - http://awesomecopter.nl/?tag=itg-3200 - http://www.varesano.net/blog/fabio/my-first-6-dof-imu-sensors-fusion-implementation-adxl345-itg3200-arduino-and-processing Or did you write your own code ?

Hello,

I had a similar problem when I made my IMU with the ADXL345, ITG3200 and the LSM303. Randomly I had peaks in my gyro and some times it freezes.
I solve this problem with this library:

I think that you can solve the problem with this library, because your problem could be caused by the Wire library in the function: twi_readFrom
This loop use to cause the problem:

while(TWI_READY != twi_state){
continue;
}

I hope this helps you!

Hey , thanks for replys.

@Krodal: I use wire.h and i writed my own code, but i followed some examples like the last link you put, thank you for the links! i will take a eye

@rgpadin i will try to change my code do i2c.h library and see what happen :D

THanks for all help guys

Rdpgadin , i changed to i2c.h library, same problem :confused:

Theres my code:

#include <I2C.h>
#define MD25ADDRESS 0x58
#define SPEED1 0x00

double gyroZero;
double gyroTotal;

double rate;
double angle;

float dt;

int STD_LOOP_TIME = 9;
int lastLoopTime = STD_LOOP_TIME;
int lastLoopUsefulTime =STD_LOOP_TIME;
unsigned long loopStartTime = 0;

void setup(){
Serial.begin(9600);
I2c.begin();
I2c.write(0x69,0x16,0x1A);
I2c.write(0x69,0x15,0x09);
delay(10);
calibrarGyro();
delay(20);
motorMode(3);
}

void loop(){
dt = (float)(lastLoopTime)/1000.0;
rate = getGyroRate() * dt;
angle = angle + rate;

Serial.println(angle);
drive_motor(20);

lastLoopUsefulTime = millis() - loopStartTime;
if(lastLoopUsefulTime < STD_LOOP_TIME)
delay(STD_LOOP_TIME-lastLoopUsefulTime);
lastLoopTime = millis() - loopStartTime;
loopStartTime = millis();
}

int i2cRead(){
int data=0;
I2c.read(0x69,0x1F,1);
data = I2c.receive()<<8;
I2c.read(0x69,0x20,1);
data |= I2c.receive();

return data;

}

void calibrarGyro(){
for(int i=0;i<200;i++)
gyroTotal += i2cRead();

gyroZero = gyroTotal / 200;

}

double getGyroRate(){
double gyroRate=0;

gyroRate = ((double)(i2cRead() - gyroZero))/16.1;
return gyroRate;

}

void motorMode(int valor){
I2c.write(MD25ADDRESS,15,valor);
}

void drive_motor(double drive){
I2c.write(MD25ADDRESS,SPEED1,drive);

}

Serial.println(angle);
drive_motor(20);

This part, motors move with value 20, and angle is printed at same time, after 3 seconds, motors stop and serial stop printing angle too

And other thing i noticed, my MD25 board, have a green led, this led is High when I2C communication is processing.

I see if i dont move gyro, they dont freeze in 3 seconds, it can happen 30sec or 40sec later, if i start rotating gyro , the green led goes “LOW” and communication stops

I recommend you use the Serial.Print to debug the program, try to get the exact place where your code is freezed. I solve my problem with this. I suspect that the problem is from the Wire library...

If anyone got same problem as me.

I found the solution, and it was nothing about I2C libraries, or software, it was about power supply.

Just power everything from same supply and use regulators(dont use arduino supply).

THanks for all help, Chaud

The problem with ITG3200 is very complicated and I doubt there is no easy and universal way out.
I achieved some success experimenting with it but never get 100% stable code with fast response, you have to choose a priority - fast response or stability.
When the I2C communication bit is lost, ITG3200 hangs and the code needs time to get it working again. this way your code never hangs long time but signal from ITG delaying during errors. When I modified my code this way, I realized that signal is lost very often and communication is very bad, therefore I decided to migrate to another device (same gyro+accell, even +compas and even cheaper). With other device I’ve never met the same problem.