Using two LSM9DS1 Magnetometers at the same time.

Hi,

I am attempting to use two LSM9DS1 chips at the same time, specifically their magnetometers. This is because I am using PID control to track a magnetic line.

I am having trouble trying to get them both to read at the same time using I2C. I can get them both to read; however, they both influence each others reading. I am attempting to get two independent magnetometer readings from these chips. I am using Adafruits LSM9DS1 libraries specifically to do this.

I have the VCC, GND, SCL, and SDA pins connected to an Arduino UNO and have tried to pull the SDOM pin to ground in order to make sure they both have different addresses. But I am having no luck, and there is very little information I can find to help. I usually either get just two readings from the same magnetometer, or a reading which is "subtracted" in a sense.

Anyone able to help me with this? My code is below:

// i2c Adafruit_LSM9DS1 sensorLeft = Adafruit_LSM9DS1(1); Adafruit_LSM9DS1 sensorRight = Adafruit_LSM9DS1(2);

void loop() { sensorRight.read(); sensorLeft.read();

/* Get a new sensor event */ sensors_event_t aLeft, mLeft, gLeft, tempLeft; sensors_event_t aRight, mRight, gRight, tempRight;

sensorLeft.getEvent(&aLeft, &mLeft, &gLeft, &tempLeft); sensorRight.getEvent(&aRight, &mRight, &gRight, &tempRight);

Serial.print("\tReading: "); Serial.print(mLeft.magnetic.z); Serial.println(" gauss"); Serial.print("\tReading: "); Serial.print(mRight.magnetic.z); Serial.println(" gauss");

Serial.println(); delay(200); }

they both influence each others reading.

I doubt that very much. Post some clear evidence for your assertion.

How, exactly, have you configured the sensors so that they respond to different I2C addresses?

Hi, Welcome to the forum.

Please read the first post in any forum entitled how to use this forum. http://forum.arduino.cc/index.php/topic,148850.0.html then look down to item #7 about how to post your code. It will be formatted in a scrolling window that makes it easier to read.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Have you used the I2C scanner to check your addresses?

https://playground.arduino.cc/Main/I2cScanner

Thanks.. Tom.. :)

TomGeorge:
Hi,
Welcome to the forum.

Please read the first post in any forum entitled how to use this forum.
http://forum.arduino.cc/index.php/topic,148850.0.html then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Have you used the I2C scanner to check your addresses?

https://playground.arduino.cc/Main/I2cScanner

Thanks… Tom… :slight_smile:

Hi Tom,

I just used the I2C scanner and it successfully found one magnetometer at 0x1C and the other at 0x1E. This is with the circuit where both VCC pins are connected to 5V, both GND pins connected to GND, both SCL and SDA pins are connected to A4 and A5. Then one of the SDOM pins is connected to GND as well. Looks like this for both of them:

Image is attached

This image is a different board, so my SCL and SDA pins are A4 and A5. Also different is that one of my chips had their SDOM pins to GND as mentioned above to change the address. I think the issue may lay in the Adafruit code I am using which is using the same address, I am not too sure.

I think the issue may lay in the Adafruit code I am using which is using the same address, I am not too sure.

Time to look at the documentation for that library, or the library code itself.

Hi, Please post your entire code.

Tom.. :)

TomGeorge:
Hi,
Please post your entire code.

Tom… :slight_smile:

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_LSM9DS1.h>
#include <Adafruit_Sensor.h>  // not used in this demo but required!

// i2c
Adafruit_LSM9DS1 sensorLeft = Adafruit_LSM9DS1(123456);
Adafruit_LSM9DS1 sensorRight = Adafruit_LSM9DS1(789123);


void setupSensorLeft()
{
  // 1.) Set the accelerometer range
  sensorLeft.setupAccel(sensorLeft.LSM9DS1_ACCELRANGE_2G);
  //lsm.setupAccel(lsm.LSM9DS1_ACCELRANGE_4G);
  //lsm.setupAccel(lsm.LSM9DS1_ACCELRANGE_8G);
  //lsm.setupAccel(lsm.LSM9DS1_ACCELRANGE_16G);
  
  // 2.) Set the magnetometer sensitivity
  //lsm.setupMag(lsm.LSM9DS1_MAGGAIN_4GAUSS);
  //lsm.setupMag(lsm.LSM9DS1_MAGGAIN_8GAUSS);
  //lsm.setupMag(lsm.LSM9DS1_MAGGAIN_12GAUSS);
  sensorLeft.setupMag(sensorLeft.LSM9DS1_MAGGAIN_16GAUSS);

  // 3.) Setup the gyroscope
  sensorLeft.setupGyro(sensorLeft.LSM9DS1_GYROSCALE_245DPS);
  //lsm.setupGyro(lsm.LSM9DS1_GYROSCALE_500DPS);
  //lsm.setupGyro(lsm.LSM9DS1_GYROSCALE_2000DPS);
}

void setupSensorRight()
{
  // 1.) Set the accelerometer range
  sensorRight.setupAccel(sensorRight.LSM9DS1_ACCELRANGE_2G);
  //lsm.setupAccel(lsm.LSM9DS1_ACCELRANGE_4G);
  //lsm.setupAccel(lsm.LSM9DS1_ACCELRANGE_8G);
  //lsm.setupAccel(lsm.LSM9DS1_ACCELRANGE_16G);
  
  // 2.) Set the magnetometer sensitivity
  //lsm.setupMag(lsm.LSM9DS1_MAGGAIN_4GAUSS);
  //lsm.setupMag(lsm.LSM9DS1_MAGGAIN_8GAUSS);
  //lsm.setupMag(lsm.LSM9DS1_MAGGAIN_12GAUSS);
  sensorRight.setupMag(sensorRight.LSM9DS1_MAGGAIN_16GAUSS);

  // 3.) Setup the gyroscope
  sensorRight.setupGyro(sensorRight.LSM9DS1_GYROSCALE_245DPS);
  //lsm.setupGyro(lsm.LSM9DS1_GYROSCALE_500DPS);
  //lsm.setupGyro(lsm.LSM9DS1_GYROSCALE_2000DPS);
}


void setup() 
{
  Serial.begin(9600);

  while (!Serial) {
    delay(1); // will pause Zero, Leonardo, etc until serial console opens
  }
  
  Serial.println("LSM9DS1 data read demo");
  
  // Try to initialise and warn if we couldn't detect the chip
  if (!sensorLeft.begin())
  {
    Serial.println("Oops ... unable to initialize the LSM9DS1. Check your wiring!");
    while (1);
  }
  
  Serial.println("Found LSM9DS1 9DOF");

  // helper to just set the default scaling we want, see above!
  setupSensorLeft();
  setupSensorRight();
}

void loop() 
{
  sensorRight.read();
  sensorLeft.read();

  /* Get a new sensor event */ 
  sensors_event_t aLeft, mLeft, gLeft, tempLeft;
  sensors_event_t aRight, mRight, gRight, tempRight;

  sensorLeft.getEvent(&aLeft, &mLeft, &gLeft, &tempLeft); 
  sensorRight.getEvent(&aRight, &mRight, &gRight, &tempRight);

  Serial.print("\tReading: "); Serial.print(mLeft.magnetic.z);     Serial.println(" gauss");
  Serial.print("\tReading: "); Serial.print(mRight.magnetic.z);     Serial.println(" gauss");
  
  Serial.println();
  delay(200);
}

I have looked through the Adafruit code, but I just can’t for the life of me find the problem. I wouldn’t say I am a good enough coder to deduce the problem from the source.

Hi, Isn't the Adafruit Library for SPI, not I2C? I may be wrong!!!!!!!

Tom.. :)

TomGeorge: Hi, Isn't the Adafruit Library for SPI, not I2C? I may be wrong!!!!!!!

Tom.. :)

I believe it works for both :).

Hi, Where in the code do you assign the two I2C addresses?

0x1C and the other at 0x1E ?

Adafruit_LSM9DS1 sensorLeft = Adafruit_LSM9DS1(123456);
Adafruit_LSM9DS1 sensorRight = Adafruit_LSM9DS1(789123);

This might help.

Adafruit_LSM9DS1 sensorLeft = Adafruit_LSM9DS1(0x1C);
Adafruit_LSM9DS1 sensorRight = Adafruit_LSM9DS1(0x1E);

Tom... :)

The Adafruit library have address of the sensor hardcoded by

#define LSM9DS1_ADDRESS_ACCELGYRO          (0x6B)
#define LSM9DS1_ADDRESS_MAG                (0x1E)

defines of Adafruit_LSM9DS1.h.

To be able to use this library replace them with a variable. I think quick workaround may be replacing the #defines with

#define LSM9DS1_ADDRESS_ACCELGYRO          activeAccelGyro
#define LSM9DS1_ADDRESS_MAG                activeMag

, define byte variables activeAccelGyro and activeMag and set them to address of the sensor you want to communicate to before each communication.