Unable to connect with LSM6DS3 accelerometer via i2c

Hello everyone,

Sorry for my bad english, it is not my native language.

I have a LSM6DS3 accelerometer sensor connected via I2C with arduino mega 2560. It is the first time i use i2c protocol. I followed the instructions from this site LSM6DS3 Breakout Hookup Guide - learn.sparkfun.com to connect LSM6DS3 to the arduino (VIN—>3.3V, GND—>GND, SDA—>SDA(pin20), SCL—>SCL(pin21)). Also, i downloaded sparkfun LSM6DS3 arduino library from the same site and ran this example code:

#include "SparkFunLSM6DS3.h"
#include "Wire.h"
#include "SPI.h"

LSM6DS3 myIMU; //Default constructor is I2C, addr 0x6B

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  delay(1000); //relax...
  Serial.println("Processor came out of reset.\n");
  
  //Call .begin() to configure the IMU
  myIMU.begin();
  
}


void loop()
{
  //Get all parameters
  Serial.print("\nAccelerometer:\n");
  Serial.print(" X = ");
  Serial.println(myIMU.readFloatAccelX(), 4);
  Serial.print(" Y = ");
  Serial.println(myIMU.readFloatAccelY(), 4);
  Serial.print(" Z = ");
  Serial.println(myIMU.readFloatAccelZ(), 4);

  Serial.print("\nGyroscope:\n");
  Serial.print(" X = ");
  Serial.println(myIMU.readFloatGyroX(), 4);
  Serial.print(" Y = ");
  Serial.println(myIMU.readFloatGyroY(), 4);
  Serial.print(" Z = ");
  Serial.println(myIMU.readFloatGyroZ(), 4);

  Serial.print("\nThermometer:\n");
  Serial.print(" Degrees C = ");
  Serial.println(myIMU.readTempC(), 4);
  Serial.print(" Degrees F = ");
  Serial.println(myIMU.readTempF(), 4);
  
  delay(1000);
}

But it seems like LSM6DS3 does not work properly, because the results are:

Processor came out of reset.


Accelerometer:
 X = 0.0000
 Y = 0.0000
 Z = 0.0000

Gyroscope:
 X = 0.0000
 Y = 0.0000
 Z = 0.0000

Thermometer:
 Degrees C = 25.0000
 Degrees F = 77.0000

So, i decided to search all addresses, to see if at least LSM6DS3 is detectable. The code is:

#include <Wire.h>
#include <i2cdetect.h>

void setup() {
  Wire.begin();
  Serial.begin(9600);
  Serial.println("i2cdetect example\n");
  Serial.print("Scanning address range 0x03-0x77\n\n");
}

void loop() {
  i2cdetect();  // default range from 0x03 to 0x77
  delay(2000);
}

and the results are:

i2cdetect example

Scanning address range 0x03-0x77

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

LSM6DS3 is not detectable from Arduino mega.
I’ve searched everything, i tried everything and still i can’t make this device work. I would appreciate, if someone could tell me what i’m doing wrong??

Please post a link to the exact module you are using.

If it is a 3.3V module, you MUST use a 3.3V to 5V level shifter to connect to the Mega2560.

https://www.robotics.org.za/GY-LSM6DS3

I connected LSM6DS3 VIN to 3.3V pin of arduino mega 2560.

No level shifter, no workee.

Thank you so much jremington. But, can you also explain to me why do I need a level shifter since I have supplied LMS6DS3 with 3.3V? I think that probably have a misunderstanding about what a level shifter is needed for.

If you connect 3.3V inputs to 5V outputs, or to open drain/collector outputs with pullups to 5V, the 3.3V module will malfunction and can even be destroyed.

The level shifter translates the input and output voltages as required.

If you buy modules from reputable suppliers like Pololu, the level shifters are already included, or else they carefully explain how to make the connections.

Ok, thank you again so musch! I hope I did not destroy module.

Hello again,

while i was searching how could i make a level shifter, i read in a site that i could connect directly the LSM6DS3 to an "arduino mini pro 3.3v" without the use of a level shifter. So i tried it and now i get new results from the module, but they don't change as i move the LSM6DS3. Also, module address is still not detectable from the arduino. The results are:

Accelerometer:
 X = 11.1220
 Y = 11.1220
 Z = 11.1220

Gyroscope:
 X = 1595.3699
 Y = 1595.3699
 Z = 1595.3699

Thermometer:
 Degrees C = 1449.4375
 Degrees F = 2640.9875

I thought that maybe i have destroyed the module because i connected it with Arduino Mega 2560 5V, but i used another LSM6DS3 that i have never been use before and got the same results. What is going wrong? It seems more difficult than i expected to connect this module.

Please post the code, and a complete wiring diagram for the 3.3V Arduino experiment.

Does your 3.3V Arduino have pullup resistors on the I2C lines? If not, it won't work. If you don't know, try adding two 4.7K resistors from SDA and SCL to 3.3V, and running the I2C address scanner.

I don’t really know if the 3.3V arduino mini pro has pull-up resistors on the I2C lines. I tried what you suggested but using 10k resistors (i don’t have 4.7k resistors) and still the module is undetectable.

Code for LSM6DS3:

#include "SparkFunLSM6DS3.h"
#include "Wire.h"
#include "SPI.h"

LSM6DS3 myIMU; //Default constructor is I2C, addr 0x6B

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  delay(1000); //relax...
  Serial.println("Processor came out of reset.\n");
  
  //Call .begin() to configure the IMU
  myIMU.begin();
  
}


void loop()
{
  //Get all parameters
  Serial.print("\nAccelerometer:\n");
  Serial.print(" X = ");
  Serial.println(myIMU.readFloatAccelX(), 4);
  Serial.print(" Y = ");
  Serial.println(myIMU.readFloatAccelY(), 4);
  Serial.print(" Z = ");
  Serial.println(myIMU.readFloatAccelZ(), 4);

  Serial.print("\nGyroscope:\n");
  Serial.print(" X = ");
  Serial.println(myIMU.readFloatGyroX(), 4);
  Serial.print(" Y = ");
  Serial.println(myIMU.readFloatGyroY(), 4);
  Serial.print(" Z = ");
  Serial.println(myIMU.readFloatGyroZ(), 4);

  Serial.print("\nThermometer:\n");
  Serial.print(" Degrees C = ");
  Serial.println(myIMU.readTempC(), 4);
  Serial.print(" Degrees F = ");
  Serial.println(myIMU.readTempF(), 4);
  
  delay(1000);
}

I also attached a .png file with the wiring diagram. SCL is connected with A5 arduino pin and SDA is connected with A4 arduino pin.

The wiring diagram is useless (as Fritzings usually are), because it does not show the wiring to your module.

Post a photo of the setup, that clearly reveals all the wiring, with the pullup resistors attached.

Did you carefully solder the connections?

I think i misunderstood your previous suggestion about the two 4.7k resistors. How exactly do i have to connect them? Connect the resistors from (SDA, SCL) to 3.3V and also connect (SDA, SCL) directly to the arduino?

According to Arduino site for Arduino Mini Pro Arduino - ArduinoBoardProMini ---> Each pin can provide or receive a maximum of 40 mA and has an internal pull-up resistor (disconnected by default) of 20-50 kOhms. Also, i read that in Wire library (or twi), the internal pullup resistors are enabled in begin(). So, i suppose that there is intrnal pullup resistors in my arduino mini pro and they are enabled as i use the Wire library.

The resistance of the internal pullup resistors is too high for I2C.

How exactly do i have to connect them?

Google is your friend. Spend some time with him and learn a bit about I2C with Arduino.

Ok, thank you my friend!! Appreciate your help!

Hello,

i’ve searched in Google about I2C communication with Arduino. So, i disabled internal pullup resistors of Arduino at A4 and A5 pins and added two 10K resistors (one from SDA and one from SCL) to 3.3V.
I ran this code:

#include "SparkFunLSM6DS3.h"
#include "Wire.h"
#include "SPI.h"

LSM6DS3 myIMU; //Default constructor is I2C, addr 0x6B

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  delay(1000); //relax...
  Serial.println("Processor came out of reset.\n");
  
  //Call .begin() to configure the IMU
  myIMU.begin();
  
}


void loop()
{
  //Get all parameters
  Serial.print("\nAccelerometer:\n");
  Serial.print(" X = ");
  Serial.println(myIMU.readFloatAccelX(), 4);
  Serial.print(" Y = ");
  Serial.println(myIMU.readFloatAccelY(), 4);
  Serial.print(" Z = ");
  Serial.println(myIMU.readFloatAccelZ(), 4);

  Serial.print("\nGyroscope:\n");
  Serial.print(" X = ");
  Serial.println(myIMU.readFloatGyroX(), 4);
  Serial.print(" Y = ");
  Serial.println(myIMU.readFloatGyroY(), 4);
  Serial.print(" Z = ");
  Serial.println(myIMU.readFloatGyroZ(), 4);

  Serial.print("\nThermometer:\n");
  Serial.print(" Degrees C = ");
  Serial.println(myIMU.readTempC(), 4);
  Serial.print(" Degrees F = ");
  Serial.println(myIMU.readTempF(), 4);
  
  delay(1000);
}

and the processing stops at myIMU.begin() command. If i remove my own pullup resistors, the code is running and gives the results that i’ve mentioned before in this post (some strange values, that don’t change as i move the LSM6DS3 sensor).

Results:

Accelerometer:
 X = 11.1220
 Y = 11.1220
 Z = 11.1220

Gyroscope:
 X = 1595.3699
 Y = 1595.3699
 Z = 1595.3699

Thermometer:
 Degrees C = 1449.4375
 Degrees F = 2640.9875

I have attached a photo of the setup.
Is this the right way to connect my own pullup resistors?
I have above a week that i have stuck in this problem and i don’t know how to solve it.