Differentiating Between LIS3DH & LIS3DSH Sensors

Contents

Which Sensor Is It?

Generic LIS3DSH breakout board
Fig 1 - Generic LIS3DSH breakout board

LIS3DH and LIS3DSH are accelerometer sensors from well known company STMicroelectronics. They might have very similiar names but these two accelerometers are very different. The driver software for one is completely incompatible with the other. The LIS3DSH is usually more expensive than the LIS3DH chip.

Online blogs report that it's not uncommon upon ordering an LIS3DSH breakout board to receive a board containing an LIS3DH sensor. This causes confusion when the user attempts to connect to it with the incorrect driver software.

Both accelerometers at first glance look very similiar as they share the same package type and identical footprint. However it's not that difficult to differentiate between the two.

Differences

The following table summarise three readily discernable differences. Each point of difference is then discussed below.

Parameter LIS3DH LIS3DSH
Package Markings C3H DSH
I2C Address 0x18 and 0x19 0x1D and 0x1E
CHIP IDs 0x33 0x3F

Package Markings

Micrograph of the LIS3DH
Micrograph of the LIS3DSH

FIG 2 - [Left] LIS3DH chip, [Right] LIS3DSH chip

The difference in roof markings on the two chips is visible under a good magnifying glass. These markings are very clear under a digital microscope.

I2C Addresses

Each accelerometer has two available I22 addresses. The address in each case depends on whether the SDO pin is connected to GND or VCC.

The MicroPython code below is specific for the BBC micro:bit. It performs an entire scan of all possible addresses on the I2C bus then attempts to match any addresses found with LIS3DH and LIS3DSH sensors.


# Micropython program for BBC micro:bit

# Performs a scan of the I2C bus.
# Reports the number of devices
# on the bus and their addresses.

# An attempt is made to match any
# I2C addresses found to LIS3Dh
# or LIS3DSH sensors.

# I2C with defaults:
# sda = pin20
# scl = pin19

from microbit import i2c, pin19, pin20

# Perform scan of I2C bus.
addr = i2c.scan()
# Get the number of devices found.
num = len(addr)

# Report number of device found
# along with their I2C addresses.
print('I2C Devices:', num)
print('Addresses:')
for i in range(num):
    address = addr[i]
    slave = 'Unknown'
    if address in (0x18, 0x19):
        slave = 'LIS3DH'
    elif address in (0x1D, 0x1E):
        slave = 'LIS3DSH'
    print(hex(address), ': ', slave)
          

One LIS3DH accelerometer breakout board and one LIS3DSH breakout board was wired to the I2C bus pins on the micro:bit. The above program returned:


I2C Devices: 2
Addresses:
0x19 :  LIS3DH
0x1e :  LIS3DSH
          

Chip IDs

Both of these accelerometers have a product ID 'burned' to non-volatile memory during manufacturer:

  • LI3DH : 0x33
  • LIS3DSH : 0x3F

The ID can be obtained by reading the register WHO_AM_I.

The following micropython program was run with the micro:bit's I2C bus wired to an LIS3DH and an LIS3DSH.


# Micropython program for BBC micro:bit

# Reads the WHO_AM_I register for IDs.
# An attempt is made to match any values
# returned to the IDs of LIS3DH and LIS3DSH
# accelerometers.

# I2C with defaults:
# sda = pin20
# scl = pin19

from microbit import i2c, pin19, pin20
WHO_AM_I = 0x0F
LIS3DH, LIS3DSH = 0x33, 0x3F

# Perform scan of I2C bus.
addr = i2c.scan()
# Get the number of devices found.
num = len(addr)

# Use these addresses to query for IDs.
for i in range(num):
    address = addr[i]
    i2c.write(address, bytes([WHO_AM_I]))
    buf = i2c.read(address, 1)
    id = buf[0]
    device = 'Unknown'
    if id == LIS3DH:
        device = 'LIS3DH'
    elif id == LIS3DSH:
        device = 'LISH3DSH'
    print('Address:', hex(address),
          '   ID:', hex(id),
          '   Device:', device)

Output:
Address: 0x19    ID: 0x33    Device: LIS3DH
Address: 0x1e    ID: 0x3f    Device: LISH3DSH