Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

sensors_plus

Navideck fork. This is a fork of fluttercommunity/sensors_plus that adds a Linux implementation backed by the kernel's Industrial I/O (IIO) subsystem. It is otherwise a drop-in replacement for the upstream package.

sensors_plus pub points pub package

A Flutter plugin to access the accelerometer, gyroscope, magnetometer and barometer sensors.

Platform Support

Android iOS macOS Web Linux Windows
✅ ✅ ❌ ✅* ✅* ❌

* Currently it is not possible to set sensors sampling rate on web

Linux support

On Linux the plugin reads the kernel Industrial I/O sysfs interface (/sys/bus/iio/devices). This is how laptops, 2-in-1s and tablets expose their sensors (via hid-sensor-hub), how Linux phones and handhelds expose theirs (st_lsm6dsx, inv_mpu6050, bmi160, ...), and how external I²C/SPI IMUs appear on SBCs such as a Raspberry Pi with a device tree overlay. No native code or extra system packages are required; the implementation is pure Dart and is registered automatically through Flutter's Dart plugin registrant.

Because IIO is polled rather than pushed, samples are read from sysfs on a Timer at the requested samplingPeriod.

Supported drivers

Driver family Example name Accelerometer Gyroscope Magnetometer
hid-sensor-hub accel_3d, gyro_3d, magn_3d ✅ ✅ ✅
cros-ec cros-ec-accel, cros-ec-gyro ✅ ✅ some
st_lsm6dsx lsm6ds3, lsm6dso ✅ ✅ external
inv_mpu6050 mpu6050, mpu9250 ✅ ✅ some
bmi160 bmi160 ✅ ✅ ❌
adxl345/adxl380 adxl3xx ✅ ❌ ❌
bno055 bno055 ✅ ✅ ✅

Units

Accelerometer values are in m/s², gyroscope values in rad/s, magnetometer values in µT and barometer values in hPa, matching the rest of the plugin's API. The magnetometer unit is auto-detected from the first sample (Gauss or Tesla) and can be forced:

SensorsPlatform.instance = SensorsPlusLinux(
  magnetometerUnit: MagnetometerUnit.microtesla,
);

Calibration, location and axes

Values are decoded as (raw + calibbias) * calibscale * scale, using the per-axis or channel calibbias/offset and calibscale attributes when present. When a device exposes several instances (for example a laptop with base and lid accelerometers) the base instance is preferred. Devices that provide a mount_matrix are remapped to the canonical axis orientation; pass applyMountMatrix: false to disable.

Sampling frequency and permissions

By default the plugin only reads; it never writes to sysfs. If the device exposes a writable sampling_frequency, you can ask the plugin to configure it to match the requested samplingPeriod:

SensorsPlatform.instance = SensorsPlusLinux(writeSamplingFrequency: true);

Some drivers only update their *_raw attributes while a buffer is enabled (readable through /dev/iio:deviceN, which is root-only). In that case the plugin emits a diagnostic through the debugLog callback instead of silently returning constant values:

SensorsPlatform.instance = SensorsPlusLinux(
  debugLog: (message) => debugPrint('[sensors_plus] $message'),
);

If a sensor is not present, its event stream is simply empty.

Bring-up tool

bin/iio_probe.dart dumps every IIO device, its attributes and how the plugin would interpret them. It has no Flutter dependency and runs with plain Dart:

dart run sensors_plus:iio_probe

Requirements

  • Flutter >=3.19.0
  • Dart >=3.3.0 <4.0.0
  • iOS >=12.0
  • macOS >=10.14
  • Java 17
  • Kotlin 2.2.0
  • Android Gradle Plugin >=8.12.1
  • Gradle wrapper >=8.13

Usage

Add sensors_plus as a dependency in your pubspec.yaml file.

On iOS you must also include a key called NSMotionUsageDescription in your app's Info.plist file. This key provides a message that tells the user why the app is requesting access to the device’s motion data. The plugin itself needs access to motion data to get barometer data.

Example Info.plist entry:

<key>NSMotionUsageDescription</key>
<string>This app requires access to the barometer to provide altitude information.</string>

Caution

Adding NSMotionUsageDescription is a requirement and not doing so will crash your app when it attempts to access motion data.

The plugin exposes such classes of sensor events through a set of streams:

  • UserAccelerometerEvent describes the acceleration of the device, in m/s2. If the device is still, or is moving along a straight line at constant speed, the reported acceleration is zero. If the device is moving e.g. towards north and its speed is increasing, the reported acceleration is towards north; if it is slowing down, the reported acceleration is towards south; if it is turning right, the reported acceleration is towards east. The data of this stream is obtained by filtering out the effect of gravity from AccelerometerEvent.
  • AccelerometerEvent describes the acceleration of the device, in m/s2, including the effects of gravity. Unlike UserAccelerometerEvent, this stream reports raw data from the accelerometer (physical sensor embedded in the mobile device) without any post-processing. The accelerometer is unable to distinguish between the effect of an accelerated movement of the device and the effect of the surrounding gravitational field. This means that, at the surface of Earth, even if the device is completely still, the reading of AccelerometerEvent is an acceleration of intensity 9.8 directed upwards (the opposite of the graviational acceleration). This can be used to infer information about the position of the device (horizontal/vertical/tilted). AccelerometerEvent reports zero acceleration if the device is free falling.
  • GyroscopeEvent describes the rotation of the device.
  • MagnetometerEvent describes the ambient magnetic field surrounding the device. A compass is an example usage of this data.
  • BarometerEvent describes the atmospheric pressure surrounding the device, in hPa. An altimeter is an example usage of this data. Not supported on web browsers.

These events are exposed through a BroadcastStream: accelerometerEvents, userAccelerometerEvents, gyroscopeEvents, magnetometerEvents, and barometerEvents, respectively.

Note

Some low end or old Android devices don't have all sensors available. Plugin won't crash the app, but it is highly recommended to add onError() to handle such cases gracefully.

Example

import 'package:sensors_plus/sensors_plus.dart';

accelerometerEvents.listen(
  (AccelerometerEvent event) {
    print(event);
  },
  onError: (error) {
    // Logic to handle error
    // Needed for Android in case sensor is not available
    },
  cancelOnError: true,
);
// [AccelerometerEvent (x: 0.0, y: 9.8, z: 0.0)]

userAccelerometerEvents.listen(
  (UserAccelerometerEvent event) {
    print(event);
  },
  onError: (error) {
    // Logic to handle error
    // Needed for Android in case sensor is not available
    },
  cancelOnError: true,
);
// [UserAccelerometerEvent (x: 0.0, y: 0.0, z: 0.0)]

gyroscopeEvents.listen(
  (GyroscopeEvent event) {
    print(event);
  },
  onError: (error) {
    // Logic to handle error
    // Needed for Android in case sensor is not available
    },
  cancelOnError: true,
);
// [GyroscopeEvent (x: 0.0, y: 0.0, z: 0.0)]

magnetometerEvents.listen(
  (MagnetometerEvent event) {
    print(event);
  },
  onError: (error) {
    // Logic to handle error
    // Needed for Android in case sensor is not available
    },
  cancelOnError: true,
);
// [MagnetometerEvent (x: -23.6, y: 6.2, z: -34.9)]

barometerEvents.listen(
  (BarometerEvent event) {
    print(event);
  },
  onError: (error) {
    // Logic to handle error
    // Needed for Android in case sensor is not available
    },
  cancelOnError: true,
);
// [BarometerEvent (pressure: 1000.0)]

Alternatively, every stream allows to specify the sampling rate for its sensor using one of predefined constants or using a custom value.

Note

On Android it is not guaranteed that events from sensors will arrive with specified sampling rate as it is noted in the official Android documentation (see the description for the samplingPeriodUs parameter). In reality delay varies depending on Android version, device hardware and vendor's OS customisations.

import 'package:sensors_plus/sensors_plus.dart';

magnetometerEvents(samplingPeriod: SensorInterval.normalInterval).listen(
  (MagnetometerEvent event) {
    print(event);
  },
  onError: (error) {
    // Logic to handle error
    // Needed for Android in case sensor is not available
    },
  cancelOnError: true,
);

For more detailed instruction check out the documentation linked below. Also see the example subdirectory for an example application that uses the sensor data.

Platform Restrictions and Considerations

The following lists the restrictions for the sensors on certain platforms due to limitations of the platform.

  • Magnetometer and Barometer missing for web

    The Magnetometer API is currently not supported by any modern web browsers. Check browser compatibility matrix on MDN docs for Magnetormeter API.

    The Barometer API does not exist for web platforms as can be seen at MDN docs forn Sensors API.

    Developers should consider alternative methods or inform users about the limitation when their application runs on a web platform.

Note

Plugin won't crash the app in the case of usage on these platforms, but it is highly recommended to add onError() to handle such cases gracefully.

  • Sampling periods for web

    Currently it is not possible to set sensors sampling rate on web. Calls to event streams at specied sampling periods will have the sampling period ignored.

  • Barometer sampling period limitation for iOS

    On iOS devices, barometer updates are CMAltimeter which provides updates at regular intervals that cannot be controlled by the user. Calls to barometerEventStream at specied sampling periods will have the sampling period ignored.

Learn more

About

Fork of fluttercommunity/sensors_plus adding Linux (Industrial I/O) support

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages