RIOT-OS / RIOT

RIOT - The friendly OS for IoT
https://riot-os.org
GNU Lesser General Public License v2.1
4.94k stars 1.99k forks source link

Add driver for LSM6DS3 6-Axis Accelerometer&Gyroscope #17053

Open donsez opened 3 years ago

donsez commented 3 years ago

Description

Add driver for ST LSM6DS3 6-Axis Accelerometer&Gyroscope

This device is popular and available as a Grove module. Its I2C address is 0x6A.

Useful links

LSM6DSL is probably very similar to the LSM6DS3.

The driver LSM6DSL is already implemented by RIOT (drivers/lsm6dsl). Its I2C address is 0x6B.

trail-coffee commented 1 year ago

hey, I got it talking in test/driver_lsm6dsl by setting LSM6DSL_WHO_AM_I = 0x69.

if you're just looking to test. I'm using an arduino-nano-33-iot. will work on a more proper implementation later today.

Edit: what's the proper way to implement super similar drivers? should i just copy everything from the lsm6dsl and make a bunch of changes or should i try to use includes to re-use lsm6dsl code?

Edit2: also I had to set the address... 0x6A

trail-coffee commented 1 year ago

@donsez support is here working with saul, test code, and arduino-nano-33-iot. Still has some features from LSM6DSL that I need to cull though.

trail-coffee/RIOT@de8e7b5058296c0b781368410501f5540b4d61f3

gschorcht commented 1 year ago

what's the proper way to implement super similar drivers? should i just copy everything from the lsm6dsl and make a bunch of changes or should i try to use includes to re-use lsm6dsl code?

If the sensors are so similar that they can be handled with one driver and little specific code, the correct way is to use a common driver. The driver and all identifiers are named with x for the variants, for example lsm6dsx and LSM6DSX_* for the sensors LSM6DSL and LSM6DS3. The variants are then defined as pseudo modules lsm6dsl and lsm6ds3 that are used to select the corresponding driver variant. In the source code, MODULE_LSM6DSL and MODULE_LSM6DS3 can then be used for specific code. RIOT has numerous examples of such drivers, for example l3gxxxx or ina2xx.

I am a bit confused, according to the datasheets both LSM6DSL and LSM6DS3 use 0x6A as WHO_AM_I register value that is also used by the driver. LSM6DSL seems to be just the ultra-low power variant of LSM6DS3 with higher accuracy.

That you had to change the I2C address is clear. Both sensors allow 0x6a and 0x6b as I2C address, the driver uses 0x6b as default. The reason for this is that the [ST X-NUCLEO-IKS01A2 expansion board] (https://www.st.com/en/ecosystems/x-nucleo-iks01a2.html#cad-resources), for which the lsm6dsl driver was initially written, uses 0x6b for the sensor by default.

trail-coffee commented 1 year ago

@gschorcht thx, I’ll take a look at l3gxxxx or ina2xx.

I am a bit confused, according to the datasheets both LSM6DSL and LSM6DS3 use 0x6A as WHO_AM_I register value that is also used by the driver. LSM6DSL seems to be just the ultra-low power variant of LSM6DS3 with higher accuracy.

If I pull the datasheet from Arduino (I’m testing on a nano 33 iot), their site has 0x69.

But if I look at their library, they have

int LSM6DS3Class::begin()
{
  if (_spi != NULL) {
    pinMode(_csPin, OUTPUT);
    digitalWrite(_csPin, HIGH);
    _spi->begin();
  } else {
    _wire->begin();
  }

  if (!(readRegister(LSM6DS3_WHO_AM_I_REG) == 0x6C || readRegister(LSM6DS3_WHO_AM_I_REG) == 0x69)) {
    end();
    return 0;
  }

where 0 is a failure. Not sure if 0=failure is an Arduino thing, but you can take a look at their example:


  if (!IMU.begin()) {
    Serial.println("Failed to initialize IMU!");

    while (1);
  }

Any idea why they allow 0x6C or 0x69? In my industry (automation), a little company like Arduino could get custom versions from suppliers, but I would doubt it in silicon.

gschorcht commented 1 year ago

If I pull the datasheet from Arduino (I’m testing on a nano 33 iot), their site has 0x69.

This is really strange. If I pull the datasheet from Digikey I also the 0x69 as ID. But if I search on the ST web site, the only active product is the LSM6DS3TR-C for which the ID is definitely 0x6a. The SparkFun Library also checks for 0x69 as ID. But why the hell did they change the ID for a newer revision of the same sensor :thinking: I guess the driver should just check for all possible IDs for this sensor.

BTW, the LSM6DS3 is declared as obsolete at DigiKey and can't be ordered anymore when it becomes out of stock.

Any idea why they allow 0x6C or 0x69?

The ID of the LSM6DSOX is 0x6c. It's probably just another variant and the driver also works with this variant.

trail-coffee commented 1 year ago

Sounds like I've got some reading to do. Maybe I'll pick up a shield version of an LSM that's still made.