Have you ever wondered how your smart device changes the screen’s orientation or the keypad based on the way you are holding your device? The answer lies in a simple device which is called an accelerometer.

In this tutorial, we will study how accelerometers work. We will focus specifically on the LIS3DH, an ultra-low-power, high-performance three-axis linear accelerometer from Adafruit. We will also show how to interact with the IC using Python on our Raspberry Pi.

Basically, an accelerometer is a micro-electromechanical device that measures static or dynamic acceleration forces acting on a device. These forces may be the constant force of gravity or acceleration forces due to a change in motion or direction. By having an idea of the forces acting on your device, you can estimate the direction or orientation of your device.

Uses for Accelerometers on the Rpi

Here are some real-world application areas for accelerometers.

  • Vibration monitoring
  • Tilt detection
  • Tap detection
  • Free-fall detection
  • Screen orientation detection
  • Can be used to measure dynamic speed and distance

How Accelerometers Work

The simplest way to understand how accelerometers work is to visualize a mass resting on a movable platform, as shown in the diagram above. As the platform moves in the direction of motion, the mass will tend to want to resist that change in motion. This means that the mass will squeeze a pair of piezoelectric sensors, consequently producing an electric current proportional to the force applied. From this relationship, it becomes easy to calculate the force, and since the mass is a constant, we can determine the acceleration from Force = Mass * Acceleration..

This is the same concept that the LIS3DH uses to measure the acceleration along the x, y, and z axes. However, the only difference lies in the transducer. Certain variations of accelerometers rely on capacitive transducers instead of piezoelectric. Also, the principle of determining the acceleration due to gravity is the same as the concept we have just talked about. The only difference is that the force of gravity exerts a constant acceleration along the z-axis.

The LIS3DH

If you look closely at your LIS3DH breakout board, you will notice these arrows:

Directional arrows on the PCB

These arrows show us the direction of the acceleration. According to the diagram above, the acceleration along the x-axis acts in the direction of the x arrow. The same applies to the y-axis. The z-axis takes on a different sign (circle) because the force of gravity acts into the board.

How to Connect the LIS3DH to the Rpi

As you can see from the table above, there are two ways of connecting the LIS3DH accelerometer to the RPi. We can do this through I2C or SPI. For this tutorial, I am going to show you both. We are going to need the following:

  1. Raspberry Pi,
  2. LIS3DH accelerometer
  3. Jumper cables

SPI

  • RPi -> LIS3DH
  • 3V3  ->  Vin
  • GND  ->  GND
  • SCLK  ->  SCL
  • MOSI  ->  SDA
  • MISO  ->  SDO
  • GPIO23 ->  CS 
  • GPIO24 ->  INT
RPi LIS3DH SPI connection
spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
cs = digitalio.DigitalInOut(board.D23)
int1 = digitalio.DigitalInOut(board.D24)  
lis3dh = adafruit_lis3dh.LIS3DH_SPI(spi, cs, int1=int1)

I2C

  • RPi -> LIS3DH
  • 3V3  -> Vin
  • GND -> GND
  • SCL  -> SCL
  • SDA  -> SDA
  • GPIO24 -> INT
RPi LIS3DH I2C connection
i2c = busio.I2C(board.SCL, board.SDA)
int1 = digitalio.DigitalInOut(board.D24)  
lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c, int1=int1)

How to Program the LIS3DH With Python

To communicate with the LIS3DH, we will use Adafruit’s circuitPython library. To install this library, you need to run the following pip command: sudo pip3 install adafruit-circuitpython-lis3dh. With the library installed, you can begin writing a Python script as we have done before.

Sample Project

For the sample project, we will read the acceleration values from the LIS3DH via I2C in Python and display them on the terminal. So first, we connect the components as shown in the diagram above.

import time
import board
import digitalio
import busio
import adafruit_lis3dh

i2c = busio.I2C(board.SCL, board.SDA)
int1 = digitalio.DigitalInOut(board.D24)  
lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c, int1=int1)

x, y, z = lis3dh.acceleration

while True:
  print("%0.3f %0.3f %0.3f" % (x, y, z))
  time.sleep(2)

Code Descriptions

  • import time, board, digitalio, busio, adafruit_lis3dh: Importing the necessary libraries.
  • i2c = busio.I2C(board.SCL, board.SDA): Initialising the I2C interface.
  • int1 = digitalio.DigitalInOut(board.D24): Setting up an interrupt on RPi GPIO 24.
  • x, y, z = lis3dh.acceleration: Querying the LIS3DH for accelerometer values.
  • print("%0.3f %0.3f %0.3f" % (x, y, z)): printing the values with 3 decimal places.

Running the code above with the command sudo python3 will give us the following output:

accelerometer output, slightly tilting the breadboard

How to Change the I2C Address

Lastly, we will change the I2C address. But before we change the address, let us check the current address of the I2C device. We use the command: i2cdetect -y 1 and we get the following output:

According to the datasheet, if the SDO pin in I2C mode is left open, the default address is 0x18, as shown in the diagram above. To change this address to 0x19, we can connect the SDO pin to 3.3V, and we get the following: