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

device-motion.mddocs/

Device Motion

Combined motion sensor providing comprehensive device orientation, acceleration, and rotation data. Ideal for applications requiring precise motion tracking and orientation awareness.

Capabilities

DeviceMotion Sensor

Provides access to comprehensive device motion data including acceleration with and without gravity, rotation rates, and device orientation.

/**
 * DeviceMotion sensor instance providing access to comprehensive motion data
 */
declare const DeviceMotion: DeviceMotionSensor;

interface DeviceMotionSensor extends DeviceSensor<DeviceMotionMeasurement> {
  /** Constant value representing standard gravitational acceleration for Earth (9.80665 m/s^2) */
  Gravity: number;
  
  /**
   * Subscribe for updates to the device motion sensor
   * @param listener - Callback invoked when device motion sensor update is available
   * @returns Subscription that can be removed when done
   */
  addListener(listener: Listener<DeviceMotionMeasurement>): Subscription;
  
  /**
   * Returns whether the device motion sensor is enabled on the device
   * @returns Promise resolving to boolean denoting availability
   */
  isAvailableAsync(): Promise<boolean>;
}

interface DeviceMotionMeasurement {
  /** Device acceleration on the three axis (without gravity). Expressed in m/s^2 */
  acceleration: null | {
    x: number;
    y: number;
    z: number;
    timestamp: number;
  };
  /** Device acceleration with the effect of gravity on the three axis. Expressed in m/s^2 */
  accelerationIncludingGravity: {
    x: number;
    y: number;
    z: number;
    timestamp: number;
  };
  /** Device's orientation in space with alpha, beta, gamma rotation values */
  rotation: {
    alpha: number; // rotation around Z axis
    beta: number;  // rotation around X axis  
    gamma: number; // rotation around Y axis
    timestamp: number;
  };
  /** Device's rate of rotation in space expressed in degrees per second */
  rotationRate: null | {
    alpha: number; // rotation in X axis
    beta: number;  // rotation in Y axis
    gamma: number; // rotation in Z axis
    timestamp: number;
  };
  /** Interval at which data is obtained from the native platform in milliseconds */
  interval: number;
  /** Device orientation based on screen rotation */
  orientation: DeviceMotionOrientation;
}

enum DeviceMotionOrientation {
  Portrait = 0,
  RightLandscape = 90,
  UpsideDown = 180,
  LeftLandscape = -90,
}

Usage Examples:

import { DeviceMotion, DeviceMotionOrientation } from "expo-sensors";

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

// Subscribe to comprehensive motion updates
const subscription = DeviceMotion.addListener((data) => {
  const { acceleration, accelerationIncludingGravity, rotation, rotationRate, orientation } = data;
  
  // Handle device orientation changes
  switch (orientation) {
    case DeviceMotionOrientation.Portrait:
      console.log("Device is in portrait mode");
      break;
    case DeviceMotionOrientation.RightLandscape:
      console.log("Device is in right landscape mode");
      break;
    case DeviceMotionOrientation.UpsideDown:
      console.log("Device is upside down");
      break;
    case DeviceMotionOrientation.LeftLandscape:
      console.log("Device is in left landscape mode");
      break;
  }
  
  // Process acceleration data (without gravity)
  if (acceleration) {
    const userAcceleration = Math.sqrt(
      acceleration.x ** 2 + acceleration.y ** 2 + acceleration.z ** 2
    );
    console.log(`User acceleration: ${userAcceleration.toFixed(3)} m/s²`);
  }
  
  // Process rotation data
  console.log(`Rotation - Alpha: ${rotation.alpha.toFixed(2)}°, Beta: ${rotation.beta.toFixed(2)}°, Gamma: ${rotation.gamma.toFixed(2)}°`);
  
  // Process rotation rate
  if (rotationRate) {
    console.log(`Rotation rate - Alpha: ${rotationRate.alpha.toFixed(2)}°/s, Beta: ${rotationRate.beta.toFixed(2)}°/s, Gamma: ${rotationRate.gamma.toFixed(2)}°/s`);
  }
});

// Set update interval
DeviceMotion.setUpdateInterval(100); // 10 Hz

// Clean up
subscription.remove();

Gravity Constant

Access to Earth's gravitational acceleration constant.

The Gravity constant is accessible as a property of the DeviceMotion instance: DeviceMotion.Gravity

Usage Example:

import { DeviceMotion } from "expo-sensors";

console.log(`Earth's gravity: ${DeviceMotion.Gravity} m/s²`); // 9.80665

// Calculate user acceleration magnitude relative to gravity
const subscription = DeviceMotion.addListener((data) => {
  if (data.acceleration) {
    const userAccelMagnitude = Math.sqrt(
      data.acceleration.x ** 2 + 
      data.acceleration.y ** 2 + 
      data.acceleration.z ** 2
    );
    
    // Express as multiples of gravity
    const gForces = userAccelMagnitude / DeviceMotion.Gravity;
    console.log(`User acceleration: ${gForces.toFixed(2)}g`);
  }
});

Motion Analysis Examples

Shake Detection:

import { DeviceMotion } from "expo-sensors";

let shakeThreshold = 2.5; // g-forces
let lastShakeTime = 0;
let shakeTimeout = 1000; // ms between shakes

const subscription = DeviceMotion.addListener((data) => {
  if (data.acceleration) {
    const { x, y, z } = data.acceleration;
    const acceleration = Math.sqrt(x * x + y * y + z * z) / DeviceMotion.Gravity;
    
    const currentTime = Date.now();
    if (acceleration > shakeThreshold && (currentTime - lastShakeTime) > shakeTimeout) {
      console.log("Device shaken!");
      lastShakeTime = currentTime;
      // Handle shake event
    }
  }
});

Orientation Tracking:

import { DeviceMotion, DeviceMotionOrientation } from "expo-sensors";

let currentOrientation = DeviceMotionOrientation.Portrait;

const subscription = DeviceMotion.addListener((data) => {
  if (data.orientation !== currentOrientation) {
    const oldOrientation = currentOrientation;
    currentOrientation = data.orientation;
    
    console.log(`Orientation changed from ${oldOrientation} to ${currentOrientation}`);
    
    // Handle orientation change in your app
    handleOrientationChange(currentOrientation);
  }
});

function handleOrientationChange(orientation: DeviceMotionOrientation) {
  switch (orientation) {
    case DeviceMotionOrientation.Portrait:
      // Adjust UI for portrait
      break;
    case DeviceMotionOrientation.RightLandscape:
    case DeviceMotionOrientation.LeftLandscape:
      // Adjust UI for landscape
      break;
    case DeviceMotionOrientation.UpsideDown:
      // Handle upside down if needed
      break;
  }
}

Tilt Detection:

import { DeviceMotion } from "expo-sensors";

const subscription = DeviceMotion.addListener((data) => {
  const { rotation } = data;
  
  // Calculate tilt angles
  const tiltX = rotation.beta;  // Forward/backward tilt
  const tiltY = rotation.gamma; // Left/right tilt
  
  // Detect significant tilt (>30 degrees)
  const significantTiltThreshold = 30;
  
  if (Math.abs(tiltX) > significantTiltThreshold) {
    console.log(`Significant forward/backward tilt: ${tiltX.toFixed(1)}°`);
  }
  
  if (Math.abs(tiltY) > significantTiltThreshold) {
    console.log(`Significant left/right tilt: ${tiltY.toFixed(1)}°`);
  }
});

Platform Considerations

Android

  • Full DeviceMotion support
  • Some Android devices may not provide separate acceleration data (will be null)
  • Orientation values follow device's default orientation

iOS

  • Full DeviceMotion support with high precision
  • NSMotionUsageDescription required in Info.plist
  • Separate acceleration data typically available

Web

  • Limited support, requires HTTPS
  • DeviceMotion API requires user interaction before access
  • Some measurements may be null or have reduced precision