Version 5 (modified by 5 years ago) ( diff ) | ,
---|
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 |
---|---|---|
Newport | GW64XX | LIS2DE12 |
GW63XX | LIS2DE12 | |
GW62XX | LIS2DE12 | |
GW61XX | - | |
Ventana | GW553X | LSM9DS1 |
GW54XX | FXOS8700 | |
GW53XX | FXOS8700 | |
GW522X | FXOS8700 | |
GW520X | FXOS8700 | |
GW51XX | - |
Individual device information:
Device | Datasheet | Address | Notes |
---|---|---|---|
LIS2DE12 | link | I2C bus 0, addr 0x19 | 3 axis |
LSM9DS1 | link | I2C bus 1, addr 0x6A & 0x1C | 9 axis |
FXOS8700 | link | I2C bus 2, addr 0x1E | 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 |
---|---|
LIS2DE12 | iio |
LSM9DS1 | iio |
FXOS8700 | input (3.14/4.4 kernel) / iio (4.19+ kernels) |
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:
/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/in_accel_sampling_frequenc y_available 1.5625 6.25 12.5 50 100 200 400 800 # echo 100 > /sys/bus/iio/devices/iio\:device0/in_accel_sampling_f requency # 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
/dev/iio:deviceX
- character device node interface used for buffered data transfer and for event information retrieval
- 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
- Example (GW54xx with FXOS8700)
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