date
Jan 9, 2025
slug
2025-01-09-Gsensor-theory-and-application
status
Published
tags
硬件
GSensor
summary
G-Sensor:Gravity Sensor即重力传感器,或者Accelerometer即加速度传感器,其作用主要是检测物体在运动过程中加速度的突然变化。GSensor最典型的应用就是在行车记录仪中,当GSensor检测到瞬间的加速、碰撞或者减速(例如急刹车)状态,会自动触发行车记录仪摄像头的内部记录事件,保存一个紧急录影文件作为后续进行事故分析的证据。
type
Post
category
硬件
AI summary
G-Sensor:Gravity Sensor即重力传感器,或者Accelerometer即加速度传感器,其作用主要是检测物体在运动过程中加速度的突然变化。
GSensor最典型的应用就是在行车记录仪中,当GSensor检测到瞬间的加速、碰撞或者减速(例如急刹车)状态,会自动触发行车记录仪摄像头的内部记录事件,保存一个紧急录影文件作为后续进行事故分析的证据。
G-Sensor的工作原理
可以结合下图来理解GSensor的工作原理。使用两个弹簧把一个质量块固定,当没有加速度的情况下,质量块的位置处于两个弹簧的中间;当整个测试机构向左加速运动或者向右减速运动时,质量块因为惯性向右偏移,根据动态的偏移量就可以得到此时向右的加速度大小。相反,当整个测试机构向右加速运动或者向左减速运动时,质量块因为惯性向左偏移,根据动态的偏移量就可以得到此时向左的加速度大小。

这个偏移方向和偏移量对应的就是这个轴向上的加速度值,反映在GSensor上就是X、Y、Z三个轴上的加速度大小。

G-Sensor输出值的计量单位是g,1g代表一个重力加速度,也就是9.8m/s^2,1g=1000mg。对于GSensor器件而言,其输入值一般为I2C或者SPI接口的数字信号。以STK8327为例,其输出值的范围为可由用户配置的±2g/±4g/±8g/±16g,每个轴进行一次采样产生一个16bit数据,三个轴进行一次采样就会生成6个字节的加速度数据,这6个字节就是一个frame。GSensor内部FIFO对于加速度数据的存取,以及与MCU之间通过I2C/SPI读取加速度数据,都应该以frame为单位。
G-Sensor的内置检测算法
除了能够检测、缓存并输出加速度数据以外,大多数GSensor型号内部还内置了一些基于加速度数据进行判断的常用检测算法。可以通过寄存器配置这些检测算法的使能,并且通过外部中断等方式通知MCU检测事件的发生。这些常用的加速度检测算法包括:动作检测,自由落体检测,方向检测,点击检测等。
以下简单介绍两个常用的GSensor内置算法:Any-Motion(Slope) Detection,Significant Motion。这两个算法在部分的GSensor里面都有,只不过命名方式有差异。
Any-Motion(Slope) Detection,这个算法主要就是对通常的运动行为进行检测和判断,只不过额外增加了一点过滤。以下面的这个截图来说明Slope Detection算法的工作原理。上图是GSensor的连续采样点的值,中图是各个采样点数据与阈值之间的比较,下图是中断引脚的波形。从图中可以看到,当GSensor的连续三个采样值幅度超过设置的阈值时,中断引脚才会触发,而当连续三个采样值幅度小于设置的阈值的时候,中断引脚拉低。通过这样的方式对Motion事件的判断进行一定程度的过滤,避免突发的1-2个毛刺造成中断引脚的误触发,可以让Motion判断的结果更稳定。

Significant Motion算法主要是针对设备/用户位置发生变化的行为进行准确的判断,但是希望能避免过多的误触发。该算法最典型的应用就是在手环、智能手表这类可穿戴设备上的应用,能够稳定的检测到人行走过程中的状态,但是希望能够自动过滤一些比较轻微的加速度值变化的行为,例如手机/手环放在桌面上,周围环境的轻微震动应该能够被自动过滤掉。
Significant Motion算法的工作原理,本质上也是对GSensor的实时采集数据进行一段时间的判断,结合不同大小的阈值来决定是真正的SIgnificant Motion还是一些小的干扰。
GSensor休眠过程中是否还在采集数据?
Gsensor在应用中一个很有意思的问题就是:GSensor处于休眠的状态下,究竟是否还需要不断地采集加速度数据?
- 如果需要的话,那么跟不休眠是没有本质上的区别,其内部的采集电路要始终处于工作的状态之下,如何能够实现低功耗呢?要知道低功耗对于手环、手表这类产品可是极度重要的。
- 而如果不需要的话,那它什么时候会唤醒呢?最简单的答案就是加速度值超过一定阈值的时候唤醒,但问题是如果它都没有采集数据,如何能够知道当前的加速度值是否超过设置的阈值呢?这就变成了一个鸡生蛋,还是蛋生鸡的问题了。 通过对几份GSensor的数据手册进行学习,我大概搞明白了GSensor实现低功耗状态的工作逻辑:大致就是,GSensor处于低功耗工作模式下,也是需要定期醒来采集数据的,其运行时间会被区分为休眠周期和唤醒周期。 在休眠周期中,绝大部分电路和数据采集转换的功能关闭,保持极低的运行功耗。 当休眠周期的时间到了以后,GSensor自动进入唤醒周期,唤醒后经过一个短的稳定时间settle time,然后采集一组数据保存在FIFO中,并比较这组采集数据跟寄存器设置的阈值,决定是否需要通过中断引脚唤醒MCU。如果低于阈值则重新进入休眠周期,等待下个唤醒周期的到来。 例如下图是STK8327低功耗模式EDM的工作时序图,红色部分就是唤醒周期,绿色部分就是休眠周期。

GSensor的应用
下面以Sensortek的STK8327来解释GSensor在实际产品中应用的注意事项,其他厂家的GSensor型号在具体使用上大同小异。
STK8327是一个XYZ三轴加速度传感器,主要规格包括:
- 可支持用户配置加速度检测范围±2g/±4g/±8g/±16g
- 以16bit数字方式输出加速度值
- 用户配置1s可输出14-2000个加速度采样,片内FIFO可支持缓存32组加速度采样值
- 两个中断引脚,可以通过寄存器灵活配置为对应内部的不同中断模式
- 支持的数字通信接口为I2C或者三线/四线SPI
- 封装是2.0mm x 2.0mm x 1.0mm LGA。

12个引脚,除去NC和Reserved,剩下的10的引脚就是电源、地,SPI、I2C,以及两个中断引脚,使用上非常简单。Layout时需要注意芯片封装上的圆点,具体使用中要根据这个圆点来确定GSensor的XYZ轴的方向。

工作模式及其切换
STK8327有四种工作模式。其中:
- Power OFF是关机模式;
- Normal是正常工作模式,MCU可以在Normal模式下持续的使用I2C或者SPI从GSensor上读取加速度数据,但是不建议在Normal模式下修改寄存器;
- Suspend模式是专门用于设置寄存器的工作模式,这种模式下芯片内的所有模拟电路和晶振都停止工作,一般可以在这种模式下对STK8327的内部寄存器进行设置,设置完成后再切换到Normal模式下读取加速度数据;
- Low Power模式是针对低功耗设计的休眠工作模式。这种模式下除了晶振之外的大部分模拟电路都处于关闭状态,有效的降低了Gsensor的运行功耗。 ![[1736848751069.png]]

四种工作模式中,其他三种在应用上都比较简单。而Low Power实际上才是G Sensor应用的精髓所在,毕竟绝大多数使用G Sensor的产品都要依赖于其Low Power模式来实现低功耗以及Motion事件检测的效果。
Low Power Mode
在STK8327的low power mode下,实际上这个GSensor反复的在休眠周期和唤醒周期下切换:首先按照参数设置的时间周期进入休眠周期,此时停止数据采集,芯片进入极低功耗的工作状态;休眠时间到或者发生其他外部事件后,GSensor进入唤醒周期,开始采样数据并存入FIFO,并根据采样数据决定是否通过中断唤醒MCU;采样数据结束以及中断状态解除后重新进入休眠周期。
在Low Power工作模式下,STK8327提供了两种唤醒周期下的工作时序:EDM和ESM,主要区别是在唤醒周期中GSensor采样数据存入FIFO的逻辑不同,具体要使用哪一种模式,需要考虑MCU端如何使用GSensor FIFO中的历史数据来实现检测和判断算法。
EDM:Event Driven Mode,事件驱动模式。在这种时序模式下,GSensor在低功耗的唤醒周期中所采样的所有数据都会存入FIFO。需要注意的是,如果发生其他类型事件的情况下,GSensor处于唤醒周期的时间可能会延长,这样在FIFO中保存的连续GSensor采样之间的时间间隔就不是固定的。因此,这种模式比较适合于那些不依赖于FIFO缓存历史数据的应用。

ESM:Equidistant-Sampling Mode,等距采样模式。顾名思义,在这种工作时序之下,GSensor保存在FIFO中的连续采样数据的时间间隔总是相同的。如果MCU端需要依赖于FIFO中的历史数据实现一定的判断算法,那么正常情况下使用这种工作模式更为合适。从下图可以看到,如果GSensor进入到唤醒周期,即使有多个数据采样,也只会保存固定时间周期的采样数据(向上箭头)到FIFO中,其他采样数据(五角星)会被丢弃。这种模式比较适合于依赖于FIFO历史数据来执行一些算法判断的产品应用。

参考资料
- STK8327 datasheet