Saltar al contenido

Primeros pasos con el acelerómetro

Esta guía lo guiará a través de la integración del complemento Acelerómetro Capacitor en su aplicación.

Instale el complemento usando npm:

Terminal window
npm install @capgo/capacitor-accelerometer
npx cap sync

No se requiere configuración adicional. El acelerómetro siempre está disponible.

No se requiere configuración adicional. El acelerómetro siempre está disponible.

El complemento utiliza DeviceMotion API. Requiere HTTPS en producción.

import { Accelerometer } from '@capgo/capacitor-accelerometer';
const startAccelerometer = async () => {
await Accelerometer.start({
interval: 100 // Update interval in milliseconds
});
console.log('Accelerometer started');
};
Accelerometer.addListener('accelerationChange', (data) => {
console.log('X:', data.x);
console.log('Y:', data.y);
console.log('Z:', data.z);
console.log('Timestamp:', data.timestamp);
});
const getCurrentAcceleration = async () => {
const reading = await Accelerometer.getCurrentAcceleration();
console.log('Current acceleration:', reading);
};
const stopAccelerometer = async () => {
await Accelerometer.stop();
console.log('Accelerometer stopped');
};

Aquí hay un ejemplo completo con detección de sacudidas:

import { Accelerometer } from '@capgo/capacitor-accelerometer';
class AccelerometerService {
private listener: any;
private lastX = 0;
private lastY = 0;
private lastZ = 0;
private shakeThreshold = 15;
async initialize() {
await Accelerometer.start({ interval: 100 });
this.listener = Accelerometer.addListener('accelerationChange', (data) => {
this.handleAcceleration(data);
});
}
handleAcceleration(data: any) {
// Calculate delta
const deltaX = Math.abs(data.x - this.lastX);
const deltaY = Math.abs(data.y - this.lastY);
const deltaZ = Math.abs(data.z - this.lastZ);
// Check for shake
if (deltaX > this.shakeThreshold ||
deltaY > this.shakeThreshold ||
deltaZ > this.shakeThreshold) {
this.onShake();
}
// Update last values
this.lastX = data.x;
this.lastY = data.y;
this.lastZ = data.z;
// Update UI
this.updateDisplay(data);
}
onShake() {
console.log('Device shaken!');
// Trigger shake action
}
updateDisplay(data: any) {
console.log(`X: ${data.x.toFixed(2)} m/s²`);
console.log(`Y: ${data.y.toFixed(2)} m/s²`);
console.log(`Z: ${data.z.toFixed(2)} m/s²`);
// Calculate magnitude
const magnitude = Math.sqrt(
data.x * data.x +
data.y * data.y +
data.z * data.z
);
console.log(`Magnitude: ${magnitude.toFixed(2)} m/s²`);
}
async cleanup() {
if (this.listener) {
this.listener.remove();
}
await Accelerometer.stop();
}
}
// Usage
const accelService = new AccelerometerService();
accelService.initialize();
// Cleanup when done
// accelService.cleanup();
  • Eje X: de izquierda (-) a derecha (+)
  • Eje Y: de abajo (-) a arriba (+)
  • Eje Z: De atrás (-) a Frente (+)
  • El dispositivo en reposo muestra ~9,8 m/s² en un eje (gravedad)
  • El dispositivo en movimiento muestra aceleración además de gravedad.
  • Medido en metros por segundo al cuadrado (m/s²)
  • Gravedad = 9,8 m/s²
class ShakeDetector {
private lastUpdate = 0;
private lastX = 0;
private lastY = 0;
private lastZ = 0;
detectShake(x: number, y: number, z: number): boolean {
const currentTime = Date.now();
if (currentTime - this.lastUpdate > 100) {
const deltaX = Math.abs(x - this.lastX);
const deltaY = Math.abs(y - this.lastY);
const deltaZ = Math.abs(z - this.lastZ);
this.lastUpdate = currentTime;
this.lastX = x;
this.lastY = y;
this.lastZ = z;
return deltaX + deltaY + deltaZ > 15;
}
return false;
}
}
class TiltDetector {
getTiltAngles(x: number, y: number, z: number) {
const roll = Math.atan2(y, z) * (180 / Math.PI);
const pitch = Math.atan2(-x, Math.sqrt(y * y + z * z)) * (180 / Math.PI);
return { roll, pitch };
}
isDeviceFlat(z: number): boolean {
return Math.abs(z - 9.8) < 1.0;
}
isDeviceUpright(y: number): boolean {
return Math.abs(y - 9.8) < 2.0;
}
}
class StepCounter {
private steps = 0;
private lastMagnitude = 0;
private threshold = 11;
processAcceleration(x: number, y: number, z: number) {
const magnitude = Math.sqrt(x * x + y * y + z * z);
if (magnitude > this.threshold &&
this.lastMagnitude < this.threshold) {
this.steps++;
console.log('Steps:', this.steps);
}
this.lastMagnitude = magnitude;
}
}
  1. Elija intervalos adecuados: equilibre la capacidad de respuesta y la duración de la batería

    • Juegos: 16-50 ms
    • Condición física: 100-200 ms
    • Generales: 200-500 ms
  2. Eliminar oyentes: limpie siempre cuando haya terminado

  3. Filtrar ruido: utilice promedios móviles para obtener datos más fluidos

  4. Considere la batería: el sondeo de alta frecuencia agota la batería

  5. Prueba en dispositivos reales: los simuladores no proporcionan datos precisos

class AccelerometerDebouncer {
private timeout: any;
debounce(callback: Function, delay: number) {
return (...args: any[]) => {
clearTimeout(this.timeout);
this.timeout = setTimeout(() => callback(...args), delay);
};
}
}
class AccelerometerFilter {
private alpha = 0.8;
private filteredX = 0;
private filteredY = 0;
private filteredZ = 0;
filter(x: number, y: number, z: number) {
this.filteredX = this.alpha * x + (1 - this.alpha) * this.filteredX;
this.filteredY = this.alpha * y + (1 - this.alpha) * this.filteredY;
this.filteredZ = this.alpha * z + (1 - this.alpha) * this.filteredZ;
return {
x: this.filteredX,
y: this.filteredY,
z: this.filteredZ
};
}
}