or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

device-motion.mdenvironmental-sensors.mdindex.mdmagnetic-sensors.mdmotion-sensors.mdpedometer.md
tile.json

motion-sensors.mddocs/

Motion Sensors

Core motion sensing capabilities including accelerometer and gyroscope for measuring device acceleration and rotation. Essential for fitness apps, games, and augmented reality applications.

Capabilities

Accelerometer

Measures device acceleration in g-forces along three axes. A g-force is equal to Earth's gravitational acceleration (9.81 m/s²).

/**
 * Accelerometer sensor instance providing access to device acceleration data
 */
declare const Accelerometer: AccelerometerSensor;

interface AccelerometerSensor extends DeviceSensor<AccelerometerMeasurement> {
  /**
   * Subscribe for updates to the accelerometer
   * @param listener - Callback invoked when accelerometer update is available
   * @returns Subscription that can be removed when done
   */
  addListener(listener: Listener<AccelerometerMeasurement>): Subscription;
  
  /**
   * Returns whether the accelerometer is enabled on the device
   * @returns Promise resolving to boolean denoting availability
   */
  isAvailableAsync(): Promise<boolean>;
}

interface AccelerometerMeasurement {
  /** Value of g-forces device reported in X axis */
  x: number;
  /** Value of g-forces device reported in Y axis */
  y: number;
  /** Value of g-forces device reported in Z axis */
  z: number;
  /** Timestamp of the measurement in seconds */
  timestamp: number;
}

Usage Examples:

import { Accelerometer } from "expo-sensors";

// Check availability first
const isAvailable = await Accelerometer.isAvailableAsync();
if (!isAvailable) {
  console.log("Accelerometer not available");
  return;
}

// Subscribe to accelerometer updates
const subscription = Accelerometer.addListener(({ x, y, z, timestamp }) => {
  console.log(`Acceleration - X: ${x.toFixed(2)}g, Y: ${y.toFixed(2)}g, Z: ${z.toFixed(2)}g`);
  
  // Calculate total acceleration magnitude
  const magnitude = Math.sqrt(x * x + y * y + z * z);
  console.log(`Total acceleration: ${magnitude.toFixed(2)}g`);
});

// Set update interval to 100ms (10 Hz)
Accelerometer.setUpdateInterval(100);

// Clean up when done
subscription.remove();

Permission Handling:

// Request permissions (mainly for web platform)
const { status } = await Accelerometer.requestPermissionsAsync();
if (status !== 'granted') {
  console.log('Accelerometer permission not granted');
}

Gyroscope

Measures device rotation in radians per second around three axes.

/**
 * Gyroscope sensor instance providing access to device rotation data
 */
declare const Gyroscope: GyroscopeSensor;

interface GyroscopeSensor extends DeviceSensor<GyroscopeMeasurement> {
  /**
   * Subscribe for updates to the gyroscope
   * @param listener - Callback invoked when gyroscope update is available
   * @returns Subscription that can be removed when done
   */
  addListener(listener: Listener<GyroscopeMeasurement>): Subscription;
  
  /**
   * Returns whether the gyroscope is enabled on the device
   * @returns Promise resolving to boolean denoting availability
   */
  isAvailableAsync(): Promise<boolean>;
}

interface GyroscopeMeasurement {
  /** Value of rotation in radians per second device reported in X axis */
  x: number;
  /** Value of rotation in radians per second device reported in Y axis */
  y: number;
  /** Value of rotation in radians per second device reported in Z axis */
  z: number;
  /** Timestamp of the measurement in seconds */
  timestamp: number;
}

Usage Examples:

import { Gyroscope } from "expo-sensors";

// Monitor device rotation
const subscription = Gyroscope.addListener(({ x, y, z, timestamp }) => {
  // Convert from radians/second to degrees/second for easier understanding
  const xDegrees = x * (180 / Math.PI);
  const yDegrees = y * (180 / Math.PI);
  const zDegrees = z * (180 / Math.PI);
  
  console.log(`Rotation - X: ${xDegrees.toFixed(2)}°/s, Y: ${yDegrees.toFixed(2)}°/s, Z: ${zDegrees.toFixed(2)}°/s`);
});

// Set faster update rate for smooth rotation tracking
Gyroscope.setUpdateInterval(50); // 20 Hz

// Stop monitoring
subscription.remove();

Combining Accelerometer and Gyroscope:

import { Accelerometer, Gyroscope } from "expo-sensors";

let accelerometerData: AccelerometerMeasurement | null = null;
let gyroscopeData: GyroscopeMeasurement | null = null;

const accelSubscription = Accelerometer.addListener((data) => {
  accelerometerData = data;
  processCombinedData();
});

const gyroSubscription = Gyroscope.addListener((data) => {
  gyroscopeData = data;
  processCombinedData();
});

function processCombinedData() {
  if (accelerometerData && gyroscopeData) {
    // Process combined motion data
    const motionIntensity = Math.sqrt(
      accelerometerData.x ** 2 + accelerometerData.y ** 2 + accelerometerData.z ** 2 +
      gyroscopeData.x ** 2 + gyroscopeData.y ** 2 + gyroscopeData.z ** 2
    );
    
    console.log(`Motion intensity: ${motionIntensity.toFixed(2)}`);
  }
}

// Clean up both subscriptions
accelSubscription.remove();
gyroSubscription.remove();

Common Sensor Methods

Both Accelerometer and Gyroscope inherit from DeviceSensor and provide these common methods:

/**
 * Base functionality available to all motion sensors
 */
interface DeviceSensor<Measurement> {
  /** Returns boolean which signifies if sensor has any listeners registered */
  hasListeners(): boolean;
  
  /** Returns the registered listeners count */
  getListenerCount(): number;
  
  /** Removes all registered listeners */
  removeAllListeners(): void;
  
  /** Removes the given subscription */
  removeSubscription(subscription: Subscription): void;
  
  /** 
   * Set the sensor update interval
   * @param intervalMs - Desired interval in milliseconds between sensor updates
   */
  setUpdateInterval(intervalMs: number): void;
  
  /** Checks user's permissions for accessing sensor */
  getPermissionsAsync(): Promise<PermissionResponse>;
  
  /** Asks the user to grant permissions for accessing sensor */
  requestPermissionsAsync(): Promise<PermissionResponse>;
}

Platform Considerations

Android

  • All motion sensors supported
  • HIGH_SAMPLING_RATE_SENSORS permission required for intervals <200ms on Android 12+
  • Add to AndroidManifest.xml: <uses-permission android:name="android.permission.HIGH_SAMPLING_RATE_SENSORS"/>

iOS

  • All motion sensors supported
  • Higher precision sensors available on newer devices

Web

  • Limited support, requires HTTPS
  • User interaction needed before accessing sensors
  • iOS Safari requires manual Motion & Orientation Access enablement