Need help reading the MinIMU Magnetometer through I2C

So I’ve got this MinIMU9 and reading it with the Arduino code you guys provided works like a charm. Now I need to make it work on something else besides an Arduino so I’ve ported the code to uPascal, but I don’t seem to be able to make it work with my code.

Using my code, the L3G4200D Readings are ok, but if I try to read anything from the LSM303 I get nothing. I even tried only reading the WHO_AM_I registry and most of the times it returns 0x00, but once in a while, it will send me the right value witch is 0x3C. So are the two IC’s I2C protocols different in any meaningful way?

Now, another question, this is only in order to satisfy my curiositiy. I can change the LSM303 magnetometer’s I2C adress to pretty much anything I want to by modifying the appropriate registry. What happens if I change the address and forget what I’ve changed it to? Can It be recovered by some means or you’re out of luck?

Also, I can read the gyro, but if I try rading any register from the compass, the gyro will only return values of -1. I followed the procedure for reading the mag.

Here’s the code:

function Compass_readMagReg(reg:integer):byte;
var val:byte;
begin
     Soft_I2C_Start();
     Soft_I2C_Write(MAG_ADDRESS);
     Soft_I2C_Write(reg);
     Soft_I2C_Start();
     Soft_I2C_Write(MAG_ADDRESS or 1);
     val:=Soft_I2C_read(1);
     Soft_I2C_Stop();
     result:=val;
end;

Hello,

I am sorry to hear you are having trouble with your MinIMU-9. A reading of -1 means the I2C data line was high the entire time, and if that happens consistently, it is usually a good sign that the device is not actually communicating. I am not familiar with uPascal and I do not know how your I2C functions are implemented, so it is unlikely that I will be able to give you much specific advice, but one thing to check is that you are choosing an appropriate I2C frequency that is not too fast for the LSM303. Beyond that, an oscilloscope or logic analyzer would be useful for checking whether the I2C lines are behaving as expected (and comparing the behavior on the Arduino).

I am not aware of a way to change the LSM303 magnetometer’s slave address by writing a register. Where does the datasheet mention that?

- Kevin

Yes, when I read from the magnetometer and the Gyro, the readings from the gyro are consistently -1 and the magnetometer is just plain not giving relevant values. When I read from the Gyro alone, I SOMETIMES read -1 on all the axes. And then it goes back to reading relevant values, just like that. When I read from the Gyro and an accelerometer register, I read the Gyro ok, but the Acc registers are always $FF. I just probed my board and the connections are all ok. When I tried reading the Mag WHO_AM_I register I most of the times got $00. But once in a while, like once every 50 reads or something I got the right address. Sometimes I get other irrelevant values. It seems like it isn’t reading data consistently.

The uPas I2C library works at 20kHz. As far as I’ve seen in the datasheet, both the circuits on the board work at frequencies between 0 - 100 kHz for slow I2C and 0 - 400 kHz for fast I2C. So that should be fine. I’m stumped. I’m going tomorrow over at my college and i think I’ll be able to test things under an osciloscope over there.

Concerning the LSM303 magnetometer’s slave address, apparently I was wrong. I was checking out the datasheet and wrongly assumed you can change the WHO_AM_I register, but apparently it’s a read only register. So my bad.

I think the oscilloscope is your best bet for figuring out what is going on. However, if you also post the complete code you are using, I could try to look it over. It would be helpful if you could simplify it to the bare minimum that you expect to work but does not. Again, I can’t promise I will be able to help, given my unfamiliarity with uPascal, but at least I might be able to see if there are any problems with (for example) the way you are calling Compass_readMagReg() or how you have defined MAG_ADDRESS.

- Kevin

Perhaps the “soft” I2C implementation doesn’t release the data line or clock line in time for the device to return the acknowledge signal, and/or acknowledge back from the master properly?
Perhaps there is jitter in the execution of the “soft” I2C implementation that throws off the chip? What is the target platform that you run the uPascal on? Are there interrupts/timers that could get in the way? (If it’s on PC type hardware, the answer is definitely “yes”!)
Have you tried turning off interrupts while inside the Compass_readMagReg function?

I think I nailed it.
First of all, I started using the TWI interface that my AVR uC comes with (was pretty stupid not to use it in the first place, doing all that SoftI2C).
Then I noticed I was sending a acknowledge signal after each read. The I2C requires a NACK to be sent at the end of the read. The Gyro seemed to not have a problem with that, but the Magnetometer just hanged. Now it’s working, but I didn’t try reading the actual value registers yet, I’m getting at right now.

I’m glad to hear you’re making progress. Thanks for the update.

- Kevin