Due I2C fail LSM303 [Solved]

I’ve had problems getting a LSM accelerometer running on my Due, I think I’ve found solutions and questions.

I’m running a Due, with an Adafruit data logger shield (with clock), and an Adafruit LSM303DLHC accelerometer/mag. I’m using the SCL1 and SDA1 port.

There is a range of examples and libraries for the various LSM303 variants. I used the Adafruit LSM303DLH_Mag which had the correct I2C address, and worked the best.

I had to use Wire1 because I’m using the SCL1 port, same as the clock on the logger shield, I added this in the header.h file as well.

#include <Wire.h>
#define Wire Wire1 // used for Due if using SCL1 and SDA1

Then I had to adjust the pull-up resistor value using a dual 10k pot, not sure of the ideal value as I still want more sensors.

But the real mystery was that it wouldn’t do a cold start (after unplugging), just the infuriating “Ooops, no LSM303 detected”. I finally solved it by watching the I2C scanner output.

 /* Initialise the sensor */
  if(!mag.begin())
  {
    /* There was a problem detecting the LSM303 ... check your connections */
    Serial.println("Ooops, no LSM303 detected ... Check your wiring!");
    while(1); // Get rid of this! If the LSM is not detected first time it will hang!
  }

The I2C scanner showed that the first scan, after a cold start, would only show the PCF8523 clock, the second scan would show the clock and the two addresses for the Accel/Mag. So the while(1) in the above code would cause it to hang after the first failed try to begin the device. I deleted the while(1) line, and it works, it shows one failed begin loop.

Is this likely to be the Due, the LSM303 or the SCL1 port?. This piece of code is in all the examples for variants of the LSM303. It seems strange, why would you want the script to hang doing nothing, rather that repeatedly trying to start the device?

After starting the I2C (what you call a "cold" start?), an I2C bus reset may help to begin with a correct situation. Search in the DUE sub forum for this bus reset function (adapt it for SCL1/SDA1):