当前位置:首页 > 消费电子 > 消费电子
[导读]手环计步不是“加速度超阈值就+1”。手腕运动复杂,抬手、敲键盘、甩臂都会出尖峰,固定阈值一上就乱计。 低资源MCU里正确做法是:三轴合成→轻量滤波→动态阈值→峰谷配对→步频窗口过滤→连续合法步才计数。算法本身不重,重的是别用浮点堆、别主循环轮询、别每步刷屏。


手环计步不是“加速度超阈值就+1”。手腕运动复杂,抬手、敲键盘、甩臂都会出尖峰,固定阈值一上就乱计。 低资源MCU里正确做法是:三轴合成→轻量滤波→动态阈值→峰谷配对→步频窗口过滤→连续合法步才计数。算法本身不重,重的是别用浮点堆、别主循环轮询、别每步刷屏。

一、信号合成消除朝向依赖

手环戴法乱、姿态变,单轴不可靠。先合成三轴幅值:

/* 低资源版用绝对值和,省sqrt */

int32_t acc_mag(int16_t x,int16_t y,int16_t z){

   return abs(x)+abs(y)+abs(z);

}

有FPU再开方求模长,M0/M3直接用绝对值和,步态峰值一样抓得住。

二、滑动平均压毛刺

MEMS原始数据有热噪和量化毛刺,先4点滑动:

#define FILT_N 4

static int32_t filt_buf[FILT_N];

static uint8_t fi=0;


int32_t acc_filter(int32_t m){

   filt_buf[fi]=m; fi=(fi+1)%FILT_N;

   int32_t sum=0;

   for(int i=0;i<FILT_N;i++) sum+=filt_buf[i];

   return sum/FILT_N;

}

窗口别太大,4~8点足够;25Hz采样时延迟可控,不会把慢走步幅平滑掉。

三、动态阈值:跟背景走

固定阈值对手腕松紧、快走慢走都不适配。阈值跟着近期峰谷中值走:

static int32_t bg_level;     // 背景幅值慢跟踪

static int32_t dyn_th;


void threshold_update(int32_t m){

   bg_level = bg_level*15/16 + m*1/16;   // Q点平滑

   dyn_th = bg_level + STEP_BIAS;        // 偏置按标定来

}

ADI参考设计里每若干采样更新一次Max/Min,取中值当动态阈值,比单次固定阈值稳得多。

四、峰谷状态机防重复计

一个宽波峰不能被记成两步,规则是“上升越过阈值→标记候选→必须回落到阈值下→才算一步”:

typedef enum { BELOW, ABOVE } ped_state_t;

static ped_state_t st = BELOW;

static uint32_t last_step_ms = 0;

static uint8_t valid_chain = 0;

static uint32_t step_cnt = 0;


void ped_process(int32_t m, uint32_t now){

   threshold_update(m);

   if(st==BELOW && m > dyn_th){

       st = ABOVE;

       uint32_t gap = now - last_step_ms;

       if(gap > MIN_STEP_MS && gap < MAX_STEP_MS){

           valid_chain++;

           if(valid_chain >= 3){          // 连续3步才认

               step_cnt++;

               last_step_ms = now;

           }

       }else{

           valid_chain = 0;

       }

   }else if(st==ABOVE && m < dyn_th){

       st = BELOW;                       // 回落,准备下一步

   }

}

MIN_STEP_MS约300ms、MAX_STEP_MS约1500ms,能挡掉抖手毛刺和长时间停顿。

五、低资源优化要点

1. 中断/FIFO取数,不当主循环轮询

ADXL362/367、LIS2DH都带FIFO和watermark中断,MCU睡眠,中断里读一批再处理,平时CPU睡觉。

2. 定点化

bg_level*15/16这种移位平均比float快,M0无FPU别碰sqrtf。

3. 静止降采样

加速度方差低于门限→降到10Hz甚至停采;检测到运动再回25~50Hz。

4. 步数缓存不上屏

步数放全局step_cnt,每30秒或息屏前写一次Flash/NVS,别每步I2C刷OLED。

5. 连续步链防误触

单次峰不算步,连续3~4个合法间隔才提交,公交颠簸基本被滤掉。

六、落坑清单

单轴阈值→朝向一变就漏计

固定阈值0.5g→老人慢走漏、甩手误计

不回落去重→一个波峰记两步

无步频窗口→抖腕狂加步

每步刷屏→OLED耗电+卡

主循环轮询I2C→MCU睡不下去

浮点开根号→M0吃紧

不连续确认→单次震动误判成步

七、标定顺序

25Hz采三轴,绝对值和合成

4点滑动平均

背景幅值慢跟踪出动态阈值

上升越阈+回落状态机

步间隔300~1500ms过滤

连续3步提交计数

静止降采样、中断取FIFO

实戴标定STEP_BIAS

手环计步精度不在“算法多复杂”,在动态阈值跟不跟得住背景、步频窗口能不能挡掉手腕噪声。低资源MCU别上卡尔曼、别每点浮点,合加速度+滑动平均+动态阈值+峰谷状态机四件套,F103级芯片都能跑,误差压到日常±3%问题不大。 真要再稳一点,加陀螺仪判手臂摆动,但纯加速度这套已经是量产手环底线方案。



本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
关闭