cancel
Showing results for 
Search instead for 
Did you mean: 

LSM6DSL Accelerometer step count

Ranjith_Madara
Associate

I am using the kernel driver for accelerometer i need to find the accurate step count.Below are the reading for accelerometer from the driver from sysfs parameters and how can i find the step count,

root@antler_xedge:/sys/bus/iio/devices/iio:device2#ls
current_timestamp_clock dev events in_accel_scale in_accel_scale_available in_accel_x_raw in_accel_y_raw in_accel_z_raw mount_matrix name of_node power sampling_frequency sampling_frequency_available subsystem uevent
root@antler_xedge:/sys/bus/iio/devices/iio:device2#cat name
lsm6dsl_accel
root@antler_xedge:/sys/bus/iio/devices/iio:device2#cat in
cat: in: No such file or directory
root@antler_xedge:/sys/bus/iio/devices/iio:device2#cat in_accel_scale
0.000598205
root@antler_xedge:/sys/bus/iio/devices/iio:device2#cat in_accel_scale_available
0.000598205 0.001196411 0.002392822 0.004785645
root@antler_xedge:/sys/bus/iio/devices/iio:device2#cat in_accel_x_raw
207
root@antler_xedge:/sys/bus/iio/devices/iio:device2#cat in_accel_y_raw
-16486
root@antler_xedge:/sys/bus/iio/devices/iio:device2#cat in_accel_z_raw
-63
root@antler_xedge:/sys/bus/iio/devices/iio:device2#cat mount_matrix
1, 0, 0; 0, 1, 0; 0, 0, 1
root@antler_xedge:/sys/bus/iio/devices/iio:device2#cat sampling_frequency
12.500000
root@antler_xedge:/sys/bus/iio/devices/iio:device2#cat sampling_frequency_available
12.500 26.000 52.000 104.000 208.000 416.000
root@antler_xedge:/sys/bus/iio/devices/iio:device2#

I have created script as per the datasheet for step count but i am not getting accurate step count and when i increase the sampling frequency to 56 for 16 steps i am getting 8 to 10 steps.

#!/usr/bin/env python3
import time
import math
import sys
from collections import deque

class ImprovedStepCounter:
def __init__(self, device_path="/sys/bus/iio/devices/iio:device2"):
self.device_path = device_path
self.scale = 0.000598205
self.gravity = 9.81
# Improved parameters based on your sensor data
self.threshold = 0.5 # Lower threshold
self.min_step_interval = 0.15 # Reduced from 0.2s
self.max_step_interval = 2.0 # Maximum time between steps
# Step detection state
self.step_count = 0
self.last_step_time = 0
# Use a sliding window for better peak detection
self.window_size = 8
self.magnitude_window = deque(maxlen=self.window_size)
# Calibration data
self.baseline_established = False
self.baseline_samples = 50
self.baseline_magnitudes = []
self.baseline_mean = 0
self.baseline_std = 0
# Peak detection
self.last_peak_time = 0
self.last_peak_value = 0
self.in_step_window = False
# Debug mode
self.debug = True
self.sample_count = 0
def read_accel_raw(self):
try:
with open(f"{self.device_path}/in_accel_x_raw", 'r') as f:
x = int(f.read().strip())
with open(f"{self.device_path}/in_accel_y_raw", 'r') as f:
y = int(f.read().strip())
with open(f"{self.device_path}/in_accel_z_raw", 'r') as f:
z = int(f.read().strip())
return x, y, z
except Exception as e:
print(f"Error reading accelerometer: {e}")
return None, None, None
def convert_to_ms2(self, raw_x, raw_y, raw_z):
x = raw_x * self.scale * self.gravity
y = raw_y * self.scale * self.gravity
z = raw_z * self.scale * self.gravity
return x, y, z
def establish_baseline(self, magnitude):
"""Establish baseline activity level"""
if len(self.baseline_magnitudes) < self.baseline_samples:
self.baseline_magnitudes.append(magnitude)
if len(self.baseline_magnitudes) == self.baseline_samples:
self.baseline_mean = sum(self.baseline_magnitudes) / len(self.baseline_magnitudes)
# Calculate standard deviation manually
variance = sum((x - self.baseline_mean) ** 2 for x in self.baseline_magnitudes) / len(self.baseline_magnitudes)
self.baseline_std = math.sqrt(variance)
self.baseline_established = True
print(f"Baseline established: Mean={self.baseline_mean:.3f}, Std={self.baseline_std:.3f}")
print("Start walking to detect steps...")
def detect_step_simple(self, x, y, z):
"""Simplified step detection focusing on Y-axis"""
current_time = time.time()
# Calculate magnitude and remove gravity
magnitude = math.sqrt(x*x + y*y + z*z)
magnitude_no_gravity = abs(magnitude - self.gravity)
# Store in sliding window
self.magnitude_window.append(magnitude_no_gravity)
# Establish baseline first
if not self.baseline_established:
self.establish_baseline(magnitude_no_gravity)
return False
# Need enough samples for detection
if len(self.magnitude_window) < 3:
return False
# Simple peak detection
current_mag = magnitude_no_gravity
prev_mag = list(self.magnitude_window)[-2] if len(self.magnitude_window) >= 2 else 0
prev_prev_mag = list(self.magnitude_window)[-3] if len(self.magnitude_window) >= 3 else 0
# Dynamic threshold based on baseline
dynamic_threshold = self.baseline_mean + max(0.3, self.baseline_std * 1.5)
# Peak detection: current > threshold and current > previous values
is_peak = (current_mag > dynamic_threshold and
current_mag > prev_mag and
prev_mag > prev_prev_mag)
# Step detection
if is_peak and current_time - self.last_step_time > self.min_step_interval:
self.step_count += 1
self.last_step_time = current_time
if self.debug:
print(f"STEP! #{self.step_count} - Magnitude: {current_mag:.3f}, Threshold: {dynamic_threshold:.3f}")
return True
return False
def run(self):
print("Improved Step Counter Started")
print("Please stand still for 3 seconds to establish baseline...")
print("Press Ctrl+C to stop\n")
try:
while True:
raw_x, raw_y, raw_z = self.read_accel_raw()
if raw_x is None:
break
x, y, z = self.convert_to_ms2(raw_x, raw_y, raw_z)
self.sample_count += 1
step_detected = self.detect_step_simple(x, y, z)
# Debug info every 20 samples
if self.debug and self.sample_count % 20 == 0 and self.baseline_established:
magnitude = math.sqrt(x*x + y*y + z*z)
mag_no_gravity = abs(magnitude - self.gravity)
print(f"Mag: {mag_no_gravity:.3f}, Steps: {self.step_count}, "
f"Baseline: {self.baseline_mean:.3f}")
time.sleep(0.08) # 12.5Hz to match your sensor
except KeyboardInterrupt:
print(f"\nFinal step count: {self.step_count}")

if __name__ == "__main__":
counter = ImprovedStepCounter()
counter.run()


Is there any test application or other ways to get the step count?

  

1 REPLY 1
Federica Bossi
ST Employee

Hi @Ranjith_Madara ,

Your current sampling frequency (12.5 Hz) is quite low for accurate step detection; typical step detection algorithms work better at 50-100 Hz.

You could also use a band-pass filter (e.g., 0.5 Hz - 3 Hz) to isolate step frequency range and peak detection on filtered magnitude or vertical acceleration component.

You can also look at open-source step detection algorithms in Github. 

In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.