wiki:accelerometer

Version 7 (modified by Tim Harvey, 3 weeks ago) (diff)

clean up tables, reference datasheets from cached site

Accelerometer and Magnetometer

Many Gateworks board families including ventana and newport come standard with either an Accelerometer, Magnetometer, or other inertial measurement unit (IMU) on a single IC.

Supported Devices

The specific IMUs used on our boards are described by the following table:

Family Board Device Location
Newport GW64xx LIS2DE12 i2c0@0x19
GW63xx LIS2DE12 i2c0@0x19
GW62xx LIS2DE12 i2c0@0x19
Ventana GW553x LSM9DS1 i2c2@0x1c
GW54xx FXOS8700 i2c3@0x1e
GW53xx FXOS8700 i2c3@0x1e
GW522x FXOS8700 i2c3@0x1e
GW520x FXOS8700 i2c3@0x1e

Individual device information:

Device Datasheet Notes
LIS2DE12 link 3 axis
LSM9DS1 link 9 axis
FXOS8700 link 6 axis, defaults to low power standby mode and must be enabled

See examples below for more information.

Software Support

The API used to access these devices varies depending on the device and sometimes the kernel version.

Device Kernel API Kernel Driver
LIS2DE12 iio IIO_ST_ACCEL_I2C_3AXIS
LSM9DS1 iio IIO_ST_MAGN_I2C_3AXIS
FXOS8700 (3.14/4.4 kernel) input INPUT_MMA8451
FXOS8700 (4.19+ kernel) iio FXOS8700_I2C

Linux industrial I/O (newer kernels)

The modern approach to IMU devices is to use the Linux IIO subsystem. IIO aims to fill the gap between the somewhat similar hwmon and input subsystems. While the hwmon API is directed at low sample rate sensors (like fan speed control or temperature measurement) the input API is focused on human interaction input devices (keyboard, mouse, touchscreen). In some cases there is considerable overlap between these and the iio API.

Userspace applications can interact with an IIO driver via either:

  1. /sys/bus/iio/devices/iio:deviceX/ - represents a hardware sensor and groups

together the data channels. Common attributes are name, dev, sampling_frequency_available, and standard attributes. See sysfs-bus-iio for details.

  • Example (GW54xx with FXOS8700)
    # cat /sys/bus/iio/devices/iio\:device0/sampling_frequency_available
    1.5625 6.25 12.5 50 100 200 400 800
    # echo 100 > /sys/bus/iio/devices/iio\:device0/sampling_frequency
    # for i in `seq 1 10`; do cat /sys/bus/iio/devices/iio\:device0/in_accel_x_raw ; done
    70
    70
    70
    70
    90
    90
    90
    90
    90
    90
    
  1. /dev/iio:deviceX - character device node interface used for buffered data transfer and for event information retrieval
  1. libiio - library for interfacing with Linux IIO devices (Ubuntu: libiio-utils iiod, OpenWrt: iio-utils iiod):
    • Example (GW54xx with FXOS8700)
      # cat "/sys/bus/iio/devices/iio:device0/in_accel_sampling_frequenc
      y"
      cat: read error: Invalid argument
      root@OpenWrt:/# iio_info 
      Library version: 0.18 (git tag: v0.18)
      Compiled with backends: local
      IIO context created with local backend.
      Backend version: 0.18 (git tag: v0.18)
      Backend description string: Linux OpenWrt 4.19.106 #0 SMP Tue Feb 25 22:49:24 2020 armv7l
      IIO context has 1 attributes:
          local,kernel: 4.19.106
      IIO context has 1 devices:
          iio:device0: fxos8700
              6 channels found:
                      accel_y:  (input)
                      5 channel-specific attributes found:
                              attr  0: raw value: -256
                              attr  1: sampling_frequency ERROR: Invalid argument (-22)
                              attr  2: sampling_frequency_available value: 1.5625 6.25 12.5 50 100 200 400 800
                              attr  3: scale value: 0.000244
                              attr  4: scale_available value: 0.000244 0.000488 0.000976
                      magn_z:  (input)
                      5 channel-specific attributes found:
                              attr  0: raw value: 0
                              attr  1: sampling_frequency ERROR: Invalid argument (-22)
                              attr  2: sampling_frequency_available value: 1.5625 6.25 12.5 50 100 200 400 800
                              attr  3: scale value: 0.000244
                              attr  4: scale_available value: 0.000001200
                      accel_z:  (input)
                      5 channel-specific attributes found:
                              attr  0: raw value: 0
                              attr  1: sampling_frequency ERROR: Invalid argument (-22)
                              attr  2: sampling_frequency_available value: 1.5625 6.25 12.5 50 100 200 400 800
                              attr  3: scale value: 0.000244
                              attr  4: scale_available value: 0.000244 0.000488 0.000976
                      magn_x:  (input)
                      5 channel-specific attributes found:
                              attr  0: raw value: -1660
                              attr  1: sampling_frequency ERROR: Invalid argument (-22)
                              attr  2: sampling_frequency_available value: 1.5625 6.25 12.5 50 100 200 400 800
                              attr  3: scale value: 0.000244
                              attr  4: scale_available value: 0.000001200
                      accel_x:  (input)
                      5 channel-specific attributes found:
                              attr  0: raw value: 82
                              attr  1: sampling_frequency ERROR: Invalid argument (-22)
                              attr  2: sampling_frequency_available value: 1.5625 6.25 12.5 50 100 200 400 800
                              attr  3: scale value: 0.000244
                              attr  4: scale_available value: 0.000244 0.000488 0.000976
                      magn_y:  (input)
                      5 channel-specific attributes found:
                              attr  0: raw value: 12800
                              attr  1: sampling_frequency ERROR: Invalid argument (-22)
                              attr  2: sampling_frequency_available value: 1.5625 6.25 12.5 50 100 200 400 800
                              attr  3: scale value: 0.000244
                              attr  4: scale_available value: 0.000001200
              1 device-specific attributes found:
                              attr  0: current_timestamp_clock value: realtime
      
      

References:

Linux input device access (older kernels)

The ​Linux input device API provides access to devices through a /dev/input/event<n> interface. Some of the older kernel's support IMU's via a linux input driver.

The /sys/class/input/input<n>/name directories will show the device name responsible for the events within that directory which correspond to matching /dev/input/event<n> entries.

Additionally there will be an api for the input device in /sys/devices/virtual/input/input<n>/ that provides you access to various controllable aspects of the input device such as the polling frequency, the min/max values, the scaling mode used and the position (orientation) of the sensor on the board. The scaling mode and position will cause the values reported to the linux input subsystem to be transformed (for normalization).

You can use the popular evtest application to show details and events from a linux input device, or write an application that accesses the device yourself.

Example usage:

> cat /sys/devices/virtual/input/input2/name # show the name of the sensor
fxos8700_m
> cat /sys/devices/virtual/input/input2/position # show the orientation of the sensor
3
> echo 1 > /sys/devices/virtual/input/input2/enable # enable the sensor (take it out of standby mode)
> evtest /dev/input/event2 # show info and values
> evtest /dev/input/event2
Input driver version is 1.0.1
Input device ID: bus 0x18 vendor 0x0 product 0x0 version 0x0
Input device name: "fxos8700_m"
Supported events:
  Event type 0 (Sync)
  Event type 3 (Absolute)
    Event code 0 (X)
      Value     69
      Min    -8192
      Max     8191
      Fuzz      32
      Flat      32
    Event code 1 (Y)
      Value    -31
      Min    -8192
      Max     8191
      Fuzz      32
      Flat      32
    Event code 2 (Z)
      Value    698
      Min    -8192
      Max     8191
      Fuzz      32
      Flat      32
Testing ... (interrupt to exit)
Event: time 1418930877.756913, type 3 (Absolute), code 0 (X), value 69
Event: time 1418930877.756913, type 3 (Absolute), code 1 (Y), value -62
Event: time 1418930877.756913, type 3 (Absolute), code 2 (Z), value 698
Event: time 1418930877.756913, -------------- Report Sync ------------
Event: time 1418930877.996939, type 3 (Absolute), code 1 (Y), value -59
Event: time 1418930877.996939, type 3 (Absolute), code 2 (Z), value 670
Event: time 1418930877.996939, -------------- Report Sync ------------
Event: time 1418930878.116877, type 3 (Absolute), code 1 (Y), value -58
Event: time 1418930878.116877, -------------- Report Sync ------------
Event: time 1418930878.236933, type 3 (Absolute), code 1 (Y), value -64
Event: time 1418930878.236933, -------------- Report Sync ------------
Event: time 1418930878.356942, type 3 (Absolute), code 1 (Y), value -66
Event: time 1418930878.356942, -------------- Report Sync ------------
Event: time 1418930878.476883, type 3 (Absolute), code 2 (Z), value 659
Event: time 1418930878.476883, -------------- Report Sync ------------
Event: time 1418930878.716929, type 3 (Absolute), code 0 (X), value 91
Event: time 1418930878.716929, -------------- Report Sync ------------
Event: time 1418930879.076878, type 3 (Absolute), code 2 (Z), value 652
Event: time 1418930879.076878, -------------- Report Sync ------------

References:

Android support via the Android sensor HAL

The Android BSP will register an accelerometer and a magnetometer sensor with the OS and therefore can be used with apps conforming the the Android sensor API.

References:

Direct i2c Access

This section provides examples for some typical methods of communicating with the IMUs on the i2c bus. The FXOS8700 information will be used but can be adjusted to match the address of the device present on your board. Refer to the linked datasheets to see more detailed register information.

The FXOS8700 device is on the third (0 based) i2c bus at a slave address of 0x1e. Therefore you can access it directly without the need of a driver if necessary by knowing the register set from the datasheet.

Example script:

#!/bin/sh

# set to active mode
i2cset -f -y 2 0x1e 0x2a 1
# enable both accelerometer and magnetometer
i2cset -f -y 2 0x1e 0x5b 3

while [ 1 ]; do
  # accelerometer vector
  a_x=$(( $( i2cget -f -y 2 0x1e 0x01 ) << 8 | $( i2cget -f -y 2 0x1e 0x02 ) ))
  a_y=$(( $( i2cget -f -y 2 0x1e 0x03 ) << 8 | $( i2cget -f -y 2 0x1e 0x04 ) ))
  a_z=$(( $( i2cget -f -y 2 0x1e 0x05 ) << 8 | $( i2cget -f -y 2 0x1e 0x06 ) ))

  # magnetometer vector
  m_x=$(( $( i2cget -f -y 2 0x1e 0x33 ) << 8 | $( i2cget -f -y 2 0x1e 0x34 ) ))
  m_y=$(( $( i2cget -f -y 2 0x1e 0x35 ) << 8 | $( i2cget -f -y 2 0x1e 0x36 ) ))
  m_z=$(( $( i2cget -f -y 2 0x1e 0x37 ) << 8 | $( i2cget -f -y 2 0x1e 0x38 ) ))

  echo "$a_x/$a_y/$a_z $m_x/$m_y/$m_z"
done

Running:

> ./test
16312/768/1824 65476/65467/690
16240/704/2000 65469/65480/687
16280/688/1912 65498/65467/683
16304/688/1976 65482/65468/697
16288/720/1944 65463/65475/704
16312/656/1944 65477/65461/684
16312/688/2000 65477/65455/680
16240/592/1840 65486/65479/667
16336/672/1944 65483/65467/693
16336/672/1856 65469/65462/668
16352/736/1944 65491/65469/716
16272/672/1944 65489/65472/687