2025-07-10 11:00 PM
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?