Sensor Verileriyle Adımlı Sayıcı: Accelerometer Okuma ve Filtreleme

Akıllı telefonların accelerometer sensörü, cihazın hareketi ölçer. Bu veriyi kullanarak adım sayısını hesaplayabilirsin. Problemi şu: ham sensor verileri gürültülü olur, doğru adımları bulmak için filtreleme gerekir.

Accelerometer üç eksen (X, Y, Z) verisi döndürür. Adım tespiti için bu üç eksenden bileşke ivmeyi hesaplarız, sonra tepe noktalarını buluruz. Her tepe bir adıma karşılık gelir.

Adım 1: Sensor Dinleyici Oluştur

Reklam · TEST
AdSense Test ReklamıYazı arası (gönderi içi) · Yazı arası
1import android.hardware.Sensor
2import android.hardware.SensorEvent
3import android.hardware.SensorEventListener
4import android.hardware.SensorManager
5import kotlin.math.sqrt
6
7class StepCounter(private val onStepDetected: () -> Unit): SensorEventListener {
8private var lastMagnitude = 0f
9private var stepCount = 0
10private val threshold = 25f // Adım eşiği
11private val buffer = mutableListOf<Float>()
12private val bufferSize = 5
13
14override fun onSensorChanged(event: SensorEvent) {
15if (event.sensor.type == Sensor.TYPE_ACCELEROMETER) {
16val x = event.values[0]
17val y = event.values[1]
18val z = event.values[2]
19
20// Bileşke ivme hesapla
21val magnitude = sqrt(x*x + y*y + z*z)
22
23// Hareketli ortalama ile filtreleme
24buffer.add(magnitude)
25if (buffer.size > bufferSize) buffer.removeAt(0)
26val smoothed = buffer.average().toFloat()
27
28// Tepe tespiti: değer eşikten büyük ve önceki değerden fazla
29if (smoothed > threshold && smoothed > lastMagnitude) {
30stepCount++
31onStepDetected()
32}
33lastMagnitude = smoothed
34}
35}
36
37override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {}
38
39fun getStepCount() = stepCount
40}

Adım 2: Activity'de Kullan

1import android.content.Context
2import android.hardware.SensorManager
3import androidx.appcompat.app.AppCompatActivity
4import android.os.Bundle
5import android.widget.TextView
6
7class MainActivity: AppCompatActivity() {
8private lateinit var sensorManager: SensorManager
9private lateinit var stepCounter: StepCounter
10private lateinit var stepText: TextView
11
12override fun onCreate(savedInstanceState: Bundle?) {
13super.onCreate(savedInstanceState)
14setContentView(R.layout.activity_main)
15
16stepText = findViewById(R.id.step_text)
17sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
18
19stepCounter = StepCounter {
20stepText.text = "Adımlar: ${stepCounter.getStepCount()}"
21}
22
23val accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
24sensorManager.registerListener(stepCounter, accelerometer, SensorManager.SENSOR_DELAY_NORMAL)
25}
26
27override fun onDestroy() {
28super.onDestroy()
29sensorManager.unregisterListener(stepCounter)
30}
31}

Beklenen Çıktı:
Ekranda "Adımlar: 42" gibi artan bir sayı görürsün. Cihazı yürüyüş hareketi yaparak test et.

Sık Yapılan Hata:
Eşik değeri (threshold) çok düşükse yanlış adımlar sayılır, çok yüksekse gerçek adımlar kaçırılır. Kullanıcıya göre kalibre et. Ayrıca `SENSOR_DELAY_NORMAL` yerine `SENSOR_DELAY_FASTEST` kullanırsan pil tüketimi artar.

Reklam · TEST
AdSense Test ReklamıGönderi altı · Görüntülü
konu hakkında tepkinizi verebilirsiniz