Акселерометърът в мобилните устройства е MEMS сензор, който измерва линейно ускорение по три оси за определяне на ориентацията и движението на устройството. Според Google Android Sensors Guide (2025), акселерометърът е най-използваният сензор в мобилните приложения. MEMS технологията позволява поставянето на сензора в чип с размер 1 мм, който консумира по-малко от 1 mW енергия.
Основни точки
Акселерометърът е микроелектромеханичен (MEMS) сензор, който измерва проекцията на ускорението върху три взаимно перпендикулярни оси: X (хоризонтална, насочена надясно), Y (вертикална, насочена нагоре) и Z (перпендикулярна на равнината на екрана). В състояние на покой акселерометърът показва стойност 9.8 m/s² по оста Z — това е гравитационното ускорение, насочено към центъра на Земята. На базата на тази стойност системата определя ориентацията на устройството: ако стойността по Z е близка до 0, а по Y до -9.8 m/s², устройството е завъртяно хоризонтално. Обхватът на измерване на акселерометъра обикновено е ±2g, ±4g, ±8g или ±16g в зависимост от модела на чипа.
Съвременните акселерометри се характеризират с няколко ключови параметъра: чувствителност (от 0.001 m/s²), честота на дискретизация (до 1000 Hz), обхват на измерване и ниво на шум. Във флагманските устройства се инсталират сензори STMicroelectronics LSM6DSO или Bosch BMI270 с честота до 1600 Hz и консумация под 0.5 mW в активен режим. Колкото по-висока е честотата на дискретизация, толкова по-детайлен сигнал получава приложението — за игри са необходими 200-400 Hz, за броене на стъпки са достатъчни 10-50 Hz. Шумът на сензора влияе върху точността на измерване и обикновено се компенсира от нискочестотен филтър на ниво операционна система.
MEMS акселерометърът вътре представлява микроскопична структура от силиций: подвижна маса (proof mass) е окачена на еластични греди (cantilevers) между неподвижни електроди. При ускорение масата се премества, променяйки капацитета между подвижните и неподвижните елементи — тази промяна се измерва и преобразува в електрически сигнал. Веригата със затворена обратна връзка (closed-loop) задържа масата в централно положение чрез електростатична сила, което осигурява линейност на измерването в целия обхват. В отворените системи (open-loop) масата се движи свободно и изчисленията са по-прости, но точността е по-ниска. Според данни на STMicroelectronics (2025), closed-loop акселерометрите осигуряват точност до 0.001g при температурен дрейф под 0.1 mg/°C.
Трите оси на акселерометъра съответстват на трите измерения на пространството: X (наклон наляво-надясно), Y (нагоре-надолу) и Z (напред-назад спрямо екрана). Когато устройството лежи на масата с екрана нагоре, векторът на гравитационното ускорение е насочен по оста Z надолу със стойност 9.8 m/s². При накланяне на устройството проекциите на гравитацията се преразпределят между осите — на базата на тези проекции може да се изчисли ъгълът на наклон с точност до 0.1 градуса. За определяне на движение без влиянието на гравитацията се използва високочестотен филтър (high-pass filter), който отделя динамичния компонент на ускорението (собствено движение на устройството) от статичния (гравитационна сила).
На Android достъпът до акселерометъра се осъществява чрез класа SensorManager и интерфейса SensorEventListener. Приложението получава системната услуга SENSOR_SERVICE, изисква сензор TYPE_ACCELEROMETER и регистрира слушател с посочване на честотата на обновяване. Системата извиква onSensorChanged при всяко ново измерване с масив от стойности: values[0] = X, values[1] = Y, values[2] = Z. По-долу е даден пълен пример за четене на данни от акселерометъра на Kotlin.
val sensorManager = getSystemService(SENSOR_SERVICE) as SensorManager
val accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
val sensorEventListener = object : SensorEventListener {
override fun onSensorChanged(event: SensorEvent) {
val x = event.values[0]
val y = event.values[1]
val z = event.values[2]
// Изчисляване на ъгъла на наклон
val pitch = Math.atan2(
x.toDouble(),
Math.sqrt(y.toDouble() * y + z.toDouble() * z)
)
// Обновяване на интерфейса с нов ъгъл
textViewAngle.text = "Наклон: ${Math.toDegrees(pitch)}°"
}
override fun onAccuracyChanged(
sensor: Sensor, accuracy: Int
) { }
}
sensorManager.registerListener(
sensorEventListener,
accelerometer,
SensorManager.SENSOR_DELAY_GAME
)
В примера SensorManager.SENSOR_DELAY_GAME задава честота на обновяване ~50 Hz, оптимална за игри и интерактивни приложения. За броене на стъпки използвайте SENSOR_DELAY_NORMAL (~5 Hz), за точни измервания — SENSOR_DELAY_FASTEST (~200 Hz). В onSensorChanged масивът event.values съдържа текущите показания на сензора. На базата на стойностите X, Y, Z се изчислява ъгълът на наклон (pitch) чрез atan2 — това е основната формула за определяне на ориентацията на устройството без използване на сензор за ориентация. Не забравяйте да отмените регистрацията на слушателя в onPause за пестене на батерия.
private val alpha = 0.8f
private val gravity = FloatArray(3)
private val linearAcceleration = FloatArray(3)
override fun onSensorChanged(event: SensorEvent) {
// Нискочестотен филтър (LPF) за отделяне на гравитацията
gravity[0] = alpha * gravity[0] + (1 - alpha) * event.values[0]
gravity[1] = alpha * gravity[1] + (1 - alpha) * event.values[1]
gravity[2] = alpha * gravity[2] + (1 - alpha) * event.values[2]
// Изваждане на гравитацията — получаваме линейно ускорение
linearAcceleration[0] = event.values[0] - gravity[0]
linearAcceleration[1] = event.values[1] - gravity[1]
linearAcceleration[2] = event.values[2] - gravity[2]
}
Нискочестотният филтър с коефициент alpha отделя гравитационния компонент (статичен вектор), чието изваждане дава чистото ускорение на устройството (линейно ускорение). Това е необходимо за определяне на движение без отчитане на ориентацията — например за откриване на стъпка, разклащане или удар. Стойност alpha 0.8 означава, че филтърът пропуска ~20% от новия сигнал и запазва 80% от предишния — достатъчно за изглаждане на шума без значително забавяне.
На iOS достъпът до акселерометъра се предоставя от рамката Core Motion чрез класа CMMotionManager. Приложението създава инстанция на мениджъра и извиква startAccelerometerUpdates с посочване на опашка и handler. Данните се връщат като CMAccelerometerData, съдържащо структурата CMAcceleration с полета x, y и z. По-долу е даден пример за получаване на данни от акселерометъра на Swift с филтриране на шум.
import CoreMotion
let motionManager = CMMotionManager()
motionManager.accelerometerUpdateInterval = 1.0 / 60.0
guard motionManager.isAccelerometerAvailable else { return }
motionManager.startAccelerometerUpdates(to: OperationQueue.current!) {
data, error in
guard let acceleration = data?.acceleration,
error == nil else { return }
// Стойности в g (1 g = 9.8 m/s²)
let magnitude = sqrt(
acceleration.x * acceleration.x +
acceleration.y * acceleration.y +
acceleration.z * acceleration.z
)
// Ако magnitude > 2.5 g — открито е разклащане
if magnitude > 2.5 {
DispatchQueue.main.async {
self.handleShake()
}
}
}
В примера accelerometerUpdateInterval е зададен на 1/60 s (~60 Hz) — оптимално за плавна анимация и игри. Методът isAccelerometerAvailable проверява наличието на сензора в устройството. Стойностите на ускорението се връщат в единици g (където 1 g = 9.8 m/s²). Векторът magnitude се изчислява като Евклидова норма на трите компонента — ако стойността надвишава 2.5 g, това се интерпретира като разклащане на устройството (shake). За спиране на обновяванията извикайте stopAccelerometerUpdates при напускане на екрана.
Акселерометърът се използва в широк спектър от мобилни приложения. Най-очевидният сценарий е автоматичното завъртане на екрана: системата превключва между портретна и пейзажна ориентация на базата на данни от акселерометъра. В игрите акселерометърът служи като контролер за управление — накланянето на устройството завърта волана или движи персонажа. Фитнес приложенията броят стъпки на базата на характерни пикове на ускорение при ходене. По-долу е дадена таблица с типични сценарии и изисквания към сензора.
| Сценарий | Честота (Hz) | Точност | Филтриране |
|---|---|---|---|
| Автоматично завъртане на екрана | 5-10 | Ниска | LPF |
| Броене на стъпки | 20-50 | Средна | HPF + детектор на пикове |
| Игри (състезания) | 50-200 | Висока | Калибриране + LPF |
| Стабилизиране на камера | 200-1000 | Максимална | Комплементарен филтър |
| Разпознаване на жестове | 50-100 | Средна | HPF + детектор на праг |
При имплементиране на акселерометъра трябва да се има предвид, че нагряването на устройството и стареенето на сензора могат да повлияят на точността на показанията. За критични измервания (стабилизиране на видео, компас) се препоръчва допълнително използване на жироскоп и магнитометър в рамките на сензорна интеграция (sensor fusion).
Акселерометрите са подложени на няколко типа грешки: отместване на нулата (bias) — когато сензорът показва различна от нула стойност в покой; грешка на мащабния коефициент (scale factor error) — когато чувствителността по различните оси е различна; и шум на измерване (noise), който намалява точността на единично отчитане. При производството MEMS сензорите се калибрират, но с течение на времето параметрите могат да се отклонят поради температура и механични натоварвания. За корекция в приложението може да се имплементира просто калибриране: в състояние на покой запишете средната стойност (отместването) и я изваждайте от всички последващи измервания. По-точно калибриране изисква завъртане на устройството около всички оси — този метод се нарича шестточково калибриране (six-point calibration) и дава грешка под 0.5%.
Често задавани въпроси
Акселерометърът в смартфона е MEMS сензор с размер около 1 мм, който измерва ускорение по три оси. Той определя ориентацията на устройството (портретна или пейзажна), разклащане, стъпки и движение без външни източници.
Акселерометърът измерва линейно ускорение (включително гравитация), а жироскопът измерва ъглова скорост (въртене). Акселерометърът определя ориентацията, жироскопът — въртенето. Заедно те осигуряват точно проследяване на движението в пространството (sensor fusion).
Използвайте SensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) за получаване на сензора, след това registerListener с SensorEventListener. В onSensorChanged масивът event.values съдържа стойностите X, Y, Z в m/s². Отменете регистрацията в onPause.
Изчислете magnitude = sqrt(x² + y² + z²). Ако magnitude надвишава 2-3 g (след филтриране на гравитацията), устройството е разклатено. За iOS използвайте CMMotionManager с праг 2.5 g, за Android — Sensor.TYPE_LINEAR_ACCELERATION с праг 15 m/s².
Да, за просто калибриране поставете устройството върху равна повърхност, запишете средните показания за всяка ос за 2-3 секунди и изваждайте тези стойности от всички последващи измервания. Това компенсира отместването на нулата (bias), но не и грешката на мащаба.
Резюме
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също