IRQCLR = GP_TIMER_BIT;
媒介
人们在摔倒后会见临双重危险。显而易见的是摔倒本身可能对人体产生伤害;别的,如不雅摔倒后不克不及获得及时的救助,可能会使结不雅加倍恶化。例如,很多老年人因为其身材比较衰弱,自理才能和自我保护才能降低,经常会产生不测摔倒,如不雅得不到及时的救助,这种摔倒可能会导致异常严重的后不雅。有材料显示,很多严重的后不雅并不是因为摔倒直接造成的,而是因为摔倒后,未获得及时的处理和魅护。当出现摔倒情况时,如不雅可以或许及时地通知到救世人员,将会大年夜大年夜地减轻因为摔倒而造成的伤害。
不仅是对白叟,在很多其他情况下,摔倒的报警也是异常有赞助的,尤其是大年夜比较高的处所摔倒下来的时刻。比如人们在登山,建筑,擦窗户,刷油漆和补缀屋顶的时刻。
这促使人们越来越热衷于对摔倒检测以及摔倒预告仪器的研制。近年来,跟着iMEMS®加快度传感器技巧的成长,使得设计基于三轴加快度传感器的摔倒检测器成为可能。这种摔倒检测器的基来源基本理是经由过程测量佩带该仪器的个别在活动过程中的三个正交偏向的加快度变更来感知其身材姿势的变更,并经由过程算法分析断定该个别是否产生摔倒情况。当个别产生摔倒时,仪器可以或许合营GPS模块以及无线发送模块对这一情况进行定位及报警,以便获得响应的救助。而摔倒检测器的核心部分就是断定摔倒情况是否产生的检测道理及算法。
ADXL3451是ADI公司的一款3轴、数字输出的加快度传感器。本文将在研究摔倒检测道理的基本上,提出一种基于ADXL345的新型摔倒检测解决筹划。
iMEMS加快度传感器ADXL345
iMEMS 半导体技巧把微型机械构造与电子电路集成在同一颗芯片上。iMEMS加快度传感器就是应用这种技巧,实现对单轴、双轴甚至三轴加快度进行测量并产生模仿或数字输出的传感器。根据不合的应用,加快度传感器的测量范围大年夜几g到几十g不等。数字输出的加快度传感器还会合成多种中断模式。这些特点可认为用户供给加倍便利灵活的解决筹划。
ADXL345是ADI公司比来推出的基于iMEMS技巧的3轴、数字输出加快度传感器。ADXL345具有+/-2g,+/-4g,+/-8g,+/-16g可变的测量范围;最高13bit分辨率;固定的4mg/LSB灵敏度;3mm*5mm*1mm超小封装;40-145uA超低功耗;标准的I2C或SPI数字接口;32级FIFO存储;以及内部多种活动状况检测和灵活的中断方法等特点。所有这些特点,使得ADXL345有助于大年夜大年夜简化摔倒检测算法,使其成为一款异常合实用于摔倒检测器应用的加快度传感器。
中断体系
ADXL345Registers[XL345_THRESH_INACT]=NOMOVEMENT_THRESHOLD;
图1给出了ADXL345的体系框图及管脚定义。
图1 ADXL345体系框图及管脚定义
ADXL345具有两个可编程的中断管脚:Int1和Int2。以及Data_Ready、Single_Tap、Double_Tap、Activity、Inactivity、Free_Fall、Watermark、Overrun,共计8个中断源。每个中断源可以自力地使能或禁用,还可以灵活地选择是否映射到Int1或Int2中断管脚。所有的功能都可以同时应用,只是某些功能可能须要共用中断管脚。中断功能经由过程INT_ENABLE存放器的响应位来选择使能或禁用,经由过程INT_MAP存放器的响应位来选择映射到Int1管脚或Int2管脚。中断功能的具体定义如下:
1. Data_Ready 当有新的数据产生时,Data_Ready中断置位;当没有新的数据时,Data_Ready中断清除。
2. Single_Tap 当加快度值跨越必定门限(THRESH_TAP)并且持续时光小于一准时光范围(DUR)的时刻,Single_Tap中断置位。
3. Double_Tap 当第一次Single_Tap事宜产生后,在一准时光(LATENT)之后,并在一准时光(WINDOW)之内,又产生第二次Single_Tap事宜时,Double _Tap中断置位。
图2给出了有效的Single_Tap中断和Double _Tap中断的示意图。
图2 Single_Tap和Double _Tap中断示意
4. Activity 当加快度值跨越必定门限(THRESH_ACT)时,Activity中断置位。
5. Inactivity 当加快度值低于必定门限(THRESH_INACT)并且持续跨越一准时光(TIME_INACT)时,Inactivity中断置位。TIME_INACT可以设定的最长时光为255s。
须要指出的是,对于Activity和Inactivity中断,用户可以针对X、Y、Z轴来分别进行使能或禁用。比如,可以只使能X轴的Activity中断,而禁用Y轴和Z轴的Activity中断。
对摔倒检测道理的研究主如果找到人体在摔倒过程中的加快度变更特点。
ADXL345Registers[XL345_ACT_INACT_CTL]=XL345_INACT_Z_ENABLE | XL345_INACT_Y_ENABLE
别的,对于Activity和Inactivity中断,用户还可以自由选择DC coupled工作方法或者AC coupled工作方法。其差别在于,DC coupled工作方法下,每个采样点的加快度值将直接与门限(THRESH_ACT或THRESH_INACT)进行比较,来断定是否产生中断;而AC coupled工作方法下,新的采样点将以之前的某个采样点为参考,用两个采样点的差值与门限(THRESH_ACT或THRESH_INACT)进行比较,来断定是否产生中断。AC coupled工作方法下的Activity检测,是选择检测开端时的那一个采样点作为参考,今后每个采样点的加快度值都与参考点进行比较。如不雅它们的差值跨越门限(THRESH_ACT),则Activity中断置位。AC coupled工作方法下的Inctivity检测,同样要选择一个参考点。如不雅新采样点与参考点的加快度差值跨越门限(THRESH_INACT),参考点会被该采样点更新。如不雅新采样点与参考点的加快度差值小于门限(THRESH_INACT),并且持续跨越一准时光(TIME_INACT),则Inctivity置位。
6. Free_Fall 当加快度值低于必定门限(THRESH_FF)并且持续跨越一准时光(TIME_FF)时,Free_Fall中断置位。与Inactivity中断的差别在于,Free_Fall中断重要用于对自由落体活动的检测。是以, X、Y、Z轴老是同时被使能或禁用;当时光设定也比Inactivity中断中要小很多,TIME_FF可以设定的最大年夜值为1.28s;并且Free_Fall中断只能是DC coupled工作方法。
7. Watermark 当FIFO里所存的采样点跨越必定点数(SAMPLES)时,Watermark中断置位。当FIFO里的采样点被攫取,使得个中保存的采样点数小于该数值(SAMPLES)时,Watermark中断主动清除。
须要指出的是,ADXL345的FIFO最多可以存储32个采样点(X、Y、Z三轴数值),且具有Bypass模式、通俗FIFO模式、Stream模式和Trigger模式,一共4种工作模式。FIFO功能也是ADXL345的一个重要且十分有效的功能。然则本文后面给出的解决筹划中,并没有应用到FIFO功能,所以,在此不做具体介绍。
if((IRQSTA&SPM4_IO_BIT)==SPM4_IO_BIT) // External interrupt form ADXL345 INT0
TimerWaitForStable++;
8. Overrun 当有新采样点更新了未被攫取得前次采样点时,Overrun中断置位。 Overrun功能与FIFO的工作模式有关,当FIFO工作在Bypass模式下,如不雅有新采样点更新了DATAX、DATAY和DATAZ存放器里的数值,则Overrun中断置位。当FIFO工作在其他三种模式下,只有FIFO被存满32点时,Overrun中断才会置位。FIFO里的采样点被攫取后,Overrun中断主动清除。
摔倒过程中的加快度变更特点
图3给出的是加快度在不合活动过程中的变更曲线,包含(a)步行上楼、(b)步行下楼、(c)坐下、(d)起立。假设摔倒检测器被固定在被测的人体上。个中红色的曲线是Y轴(垂直偏向)的加快度曲线,颇┞俘常静止状况下应当为-1g;黑色和黄色的曲线分别是X轴(前后偏向)和Z轴(阁下偏向)的加快度曲线,颇┞俘常静止状况下应当为0g;绿色的曲线是三轴加快度的矢量和,颇┞俘常静止状况下应当为+1g。
图3 不合活动过程中的加快度变更曲线因为老年人的活动比拟较较慢,所以在通俗的步行过程中,加快度变更不会很大年夜。最明显的加快度变更就是在坐下动作中Y轴加快度(和加快度矢量和)上有一个跨越3g的尖峰,这个尖峰是因为身材与椅子接触而产生的。
而摔倒过程中的加快度变更则完全不合。图4给出的是不测摔倒过程中的加快度变更曲线。经由过程图4和图3的比较,可以发明摔倒过程中的加快度变更有4个重要特点,这可以作为摔倒检测的准则。这4个特这在图4中以红色的方框标注,下面将对个一一进行具体介绍。
图4 摔倒过程中的加快度变更曲线
1. 掉重:在摔倒的开端都邑产生必定的掉重现象。在自由落体的降低过程,这个现象会加倍明显,加快度的矢量和会降低到接近0g,持续时光与自由落体的高度有关。对于一般的摔倒,掉重现象固然不会有像自由落体那么明显,但也会产生合加快度小于1g的情况(平日情况下合加快度应大年夜于1g)。是以,这可以作为摔倒状况的第一个断定根据。可以由ADXL345的Free_Fall中断来检测。
{
3. 静止:平日,人体在摔倒后,也就是撞击产生之后,弗成能立时起来,会有短暂的静止状况(如不雅人因为摔倒而导致晕厥,甚至可能是较长时光的静止)。表示在加快度曲线上就是会有一段时光的安稳。这可以经由过程ADXL345的Inactivity中断来检测。是以,Activity中断之后的Inactivity中断是摔倒状况的第三个断定根据。
4. 与初始状况比较:摔倒之后,人领会产生翻转,是以人体的偏向会与本来静止站立的姿势(初始状况)不合。这使得摔倒之后的静止状况下的三轴加快度数值与初始状况下的三轴加快度不合(见图4)。假设摔倒检测器固定在被测人体上的某个部位,如许初始状况下的三轴加快度数值可以认为是已知的(本例中,初始状况为:X轴0g,Y轴-1g,Z轴0g)。攫取Inactivity中断之后的三轴加快度数据,并与初始状况进行比较。如图4所示,重力加快度偏向由Y轴上的-1g变为了Z轴上的1g,这解释人体产生了侧向摔倒。是以,摔倒检测的第四个根据就是摔倒后的静止状况下加快度值与初始状况产生变更,且矢量变更跨越必定的门限值5泵比0.7g)。
这四个断定根据综合在一路,构成了全部的摔倒检测算法,可以对摔倒状况给出报警。当然,还要留意各个中断之间的时光距离要在合理典范围之内。比如,除非是大年夜很高的楼顶掉落下来,不然Free_Fall中断(掉重)和Activity中断(撞蛔缉之间的时光距离不会很长。同样,平日情况下, Activity中断(撞蛔缉和Inactivity中断(静止)之间的时光距离也不会很长。本文接下来会经由过程一个具体实例给出一组合理的取值。当然,相干中断的检测门限以及时光参数也可以根据须要而灵活设置。
别的,如不雅摔倒造成了严重的后不雅,比如,导致了人的晕厥。那么人领会在更常的一段时光内都保持静止。这个状况仍然可以经由过程Inactivity中断来检测。也就是说,如不雅发明在摔倒之后的很长时光内都保持Inactivity状况,可以再次给出一个严重报警。
典范电路连接
ADXL345和微控制器之间的电路连接异常简单。本文中的测试平台由ADXL345和微控制器ADuC70262构成。图5给出了ADXL345和ADuC70262之间的典范电路连接。ADXL345的\CS管脚接高电平,表示ADXL345工作在I2C模式。SDA和SCL是I2C总线的数据线和时钟线,分别连接到ADuC7026响应的I2C总线管脚。ADuC7026的一个GPIO管脚连接到ADXL345的ALT管脚,用来选择ADXL345的I2C地址。ADXL345的INT1管脚连接到ADuC7026的IRQ输入用来产生中断旌旗灯号。
其他的单片机或者处理器都可以采取与图5类似的电路与ADXL345进行连接。ADXL345还可以工作在SPI模式以获得更高的数据传输速度。关于SPI工作模式的具体描述,请参考ADXL345数据手册。
图5 ADXL345与微控制器之间的典范电路连接
应用ADXL345简化摔倒检测算法
本节将给出以上解决筹划的具体算法实现。表1中扼要说清楚明了每个存放器的感化以及在本算法中的设置值。对于各个存放中每一位的具体含义,请参考ADXL345的数据手册。
表1 ADXL345存放器功能解释
地址存放器名称 类型默认值解释 设置值设置的功能0DEVID只读0xE5器件ID只读-1-1CReserved--保存,不要操作保存-1DTHRESH_TAP读/写 0x00Tap的门限不应用-1EOFSX读/写0x00X轴掉调0x06补偿X轴掉调,经由过程初始化校订获得1FOFSY读/写0x00Y轴掉调0xF9补偿Y轴掉调,经由过程初始化校订获得20OFSZ读/写0x00Z轴掉调0xFC补偿Z轴掉调,经由过程初始化校订获得21DUR读/写0x00Tap的持续时光不应用-22LATENT读/写0x00Tap的延迟时光不应用-23WINDOW读/写0x00Tap的时光窗不应用-24THRESH_ACT读/写0x00Activity的门限0x20/0x08设置Activity的门限为2g或0.5g25THRESH_INACT读/写0x00Inactivity的门限0x03设置Inactivity的门限为0.1875g26TIME_INACT读/写0x00Inactivity的时光0x02/0x0A设置Inactivity的时光为2s或10s27ACT_INACT_CTL读/写0x00Activity/Inactivity使能控制0x7F/0xFF使能X、Y、Z三轴的Activity和Inactivity功能,个中Inactivity为AC coupled模式,Activity为DC coupled 或 AC coupled模式28THRESH_FF读/写0x00Free-Fall的门限0x0C设置Free-Fall的门限为0.75g29TIME_FF读/写0x00Free-Fall的时光0x06设置Free-Fall的时光为30ms2ATAP_AXES读/写0x00Tap/Double Tap使能控制不应用-2BACT_TAP_STATUS只读0x00Activity/Tap中断轴指导只读-2CBW_RATE读/写0x0A采样率和功耗模式控制0x0A设置采样率为100Hz2DPOWER_CTL读/写0x00工作模式控制0x00设置为正常工作模式2EINT_ENABLE读/写0x00中断使能控制0x1C使能Activity、Inactivity、Free-Fall中断2FINT_MAP读/写0x00中断暗射┞菲握0x00所有中断暗射到Int1管脚30INT_SOURCE只读0x00中断源指导只读-31DATA_FORMAT读/写0x00数据格局控制0x0B设置为+/-16g测量范围,13bit右对齐模式,中断为高电平触发,应用I2C数据接口32DATAX0只读0x00X轴数据只读-33DATAX1只读0x00只读-34DATAY0只读0x00Y轴数据只读-35DATAY1只读0x00只读-36DATAZ0只读0x00Z轴数据只读-37DATAZ1只读0x00只读-38FIFO_CTL读/写0x00FIFO控制不应用-39FIFO_STATUS只读0x00FIFO状况不应用-
须要指出的是,表1给出的设置值中,某些存放器会给出两个数值,这解释在算法中会切换应用这两个数值,来达到不合的检测目标。算法的流程图如图6所示。
图6 算法流程图
算法中,关于复荡蛐断的门限以及时光参数的设置如下所述。
2. 撞蛔己掉重之后,人体产生摔倒的时刻会与地面或其他物体产生撞蛔棘在加快度曲线中会产生一个很大年夜的冲击。这个冲击可以经由过程ADXL345的Activity中断来检测。是以,Free_Fall中断之后,紧接着产生Activity中断是摔倒状况的第二个断定根据。
4. Activity中断产生之后,体系开端等待Inactivity中断(撞击后的静止),这里把THRESH_INACT设为0.1875g,把TIME_INACT设为2s,Inactivity中断为AC coupled工作模式。
5. 在Activity中断产(撞蛔缉生之后的3.5s时光之内,应当有Inactivity中断(撞击后的静止)产生。如不雅超时,则认为无效。3.5s计时须要经由过程MCU中的准时器来实现。
6. 如不雅Inactivity中断之后的加快度值与初始状况(假设已知)下数值的矢量差跨越0.7g,则解释检测到一次有效的摔倒,体系会给出一个报警。
7. 当检测到摔倒状况之后,为了断定是否在摔倒之后人体有长时光的静止不动。须要持续检测Activity中断和Inactivity中断。这里把THRESH_ACT设为0.5g,Activity中断为AC coupled工作模式。把THRESH_INACT设为0.1875g,把TIME_INACT设为10s,Inactivity中断为AC coupled工作模式。也就是说,如不雅在10s之内,人体一向没有任何动作,则会产生Inactivity中断,使体系给出一个严重报警。而在此时代一旦人体有所动作,则会产生Activity中断,大年夜而停止全部断定过程。
8. 本算法还可以检测进出体大年夜较高的处所跌落。如不雅Free_Fall中断持续产生且之间的距离小于100ms,可以认为,人体处于持续的跌落状况。如不雅Free_Fall中断(掉重)持续产生300ms,则解释人体是大年夜跨越0.45m的高度跌落,体系会给出一个跌落的报警。
本算法已在ADuC7026微控制器中以C说话实现(见附录)。本文设计了一个实验筹划对算法进行验证。实验对向前摔倒,向后摔倒,向左、右两侧摔倒等不合摔倒姿势以及摔倒后是否有长时光静止状况的情况分别进行了10次测试,表2中给出的是相干测试结不雅。
表2 测试结不雅
摔倒姿势摔倒后长时光静止12345678910向前摔倒否PPPPPPPPPP是P*P*P*P*P*P*P*P*P*P*向后摔倒否PPPPPPPPPP是P*P*P*P*P*P*P*P*P*P*向左侧摔倒否PPPPPPPPPP是P*P*P*P*P*P*P*P*P*P*向右侧摔倒否PPPPPPPPPP是P*P*P*P*P*P*P*P*P*P*注:符号√表示检测到摔倒,符号*表示检测到摔倒后的长时光静止。
大年夜这个实验中可以看出基于ADXL345的解决筹划可以或许有效地对摔倒状况进行检测。当然,这里只是一个简单的实验筹划,仍须要进行加倍周全、有效和经久的实验来验证该解决筹划的靠得住性。
{
结论
ADXL345是ADI公司的一款功能强大年夜的加快度传感器产平辜本文应用ADXL345内部的多种活动状况检测功能和灵活的中断功能,提出一种新的摔倒检测解决筹划。经验证,该解决筹划具有算法复杂度低,检测精确度高的长处。
附录
本算法的基于ADXL345和ADuC7026的测试平台实现。经由过程Keil UV3编译,工程中共有4个头文件和一个c文件。下面具体给出了c文件中源代码。
// Include header files
#include "FallDetection.h"
void IRQ_Handler() __irq // IRQ interrupt
{
unsigned char i;
if((IRQSTA & GP_TIMER_BIT)==GP_TIMER_BIT) //TIMER1 Interrupt, interval 20ms
{
T1CLRI = 0; // Clear Timer1 interrupt
if(DetectionStatus==0xF2) // Strike after weightlessness is detected, waiting for stable
{
if(TimerWaitForStable>=STABLE_WINDOW) // Time out, restart
{
IRQCLR = GP_TIMER_BIT; // Disable ADuC7026's Timer1 interrupt
DetectionStatus=0xF0;
putchar(DetectionStatus);
}
ADXL345Registers[XL345_THRESH_ACT]=STRIKE_THRESHOLD;
ADXL345Registers[XL345_ACT_INACT_CTL]=XL345_INACT_Z_ENABLE | XL345_INACT_Y_ENABLE
ADXL345Registers[XL345_ACT_INACT_CTL]=XL345_INACT_Z_ENABLE | XL345_INACT_Y_ENABLE
| XL345_INACT_X_ENABLE | XL345_INACT_AC
| XL345_ACT_Z_ENABLE | XL345_ACT_Y_ENABLE
| XL345_ACT_X_ENABLE | XL345_ACT_DC;
xl345Write(4, XL345_THRESH_ACT, &ADXL345Registers[XL345_THRESH_ACT]);
}
1. 初始化后,体系等待Free_Fall中断(掉重),这里把THRESH_FF设为0.75g,把TIME_FF设为30ms。
}
else if(DetectionStatus==0xF1) // Weightlessness is detected, waiting for strike
TimerWaitForStrike++;
if(TimerWaitForStrike>=STRIKE_WINDOW) // Time out, restart
{
IRQCLR = GP_TIMER_BIT; // Disable ADuC7026's Timer1 interrupt
DetectionStatus=0xF0;
putchar(DetectionStatus);
ADXL345Registers[XL345_THRESH_ACT]=STRIKE_THRESHOLD;
ADXL345Registers[XL345_THRESH_INACT]=NOMOVEMENT_THRESHOLD;
ADXL345Registers[XL345_THRESH_INACT]=NOMOVEMENT_THRESHOLD;
DetectionStatus=0xF0; // Go to Status "F0", restart
ADXL345Registers[XL345_TIME_INACT]=STABLE_TIME;
ADXL345Registers[XL345_ACT_INACT_CTL]=XL345_INACT_Z_ENABLE | XL345_INACT_Y_ENABLE
| XL345_INACT_X_ENABLE | XL345_INACT_AC
| XL345_ACT_Z_ENABLE | XL345_ACT_Y_ENABLE
2. Free_Fall中断产生之后,体系开端等待Activity中断(撞蛔缉,这里把THRESH_ACT设为2g,Activity中断为DC coupled工作模式。
| XL345_ACT_X_ENABLE | XL345_ACT_DC;
xl345Write(4, XL345_THRESH_ACT, &ADXL345Registers[XL345_THRESH_ACT]);
}
}
}
{
IRQCLR = SPM4_IO_BIT; // Disable ADuC7026's external interrupt
xl345Read(1, XL345_INT_SOURCE, &ADXL345Registers[XL345_INT_SOURCE]);
if((ADXL345Registers[XL345_INT_SOURCE]&XL345_ACTIVITY)==XL345_ACTIVITY) // Activity interrupt asserted
{
if(DetectionStatus==0xF1) // Waiting for strike, and now strike is detected
{
DetectionStatus=0xF2; // Go to Status "F2"
putchar(DetectionStatus);
ADXL345Registers[XL345_THRESH_ACT]=STABLE_THRESHOLD;
ADXL345Registers[XL345_ACT_INACT_CTL]=XL345_INACT_Z_ENABLE | XL345_INACT_Y_ENABLE
ADXL345Registers[XL345_THRESH_INACT]=NOMOVEMENT_THRESHOLD;
ADXL345Registers[XL345_TIME_INACT]=STABLE_TIME;
ADXL345Registers[XL345_TIME_INACT =STABLE_TIME;
| XL345_INACT_X_ENABLE | XL345_INACT_AC
| XL345_ACT_Z_ENABLE | XL345_ACT_Y_ENABLE
| XL345_ACT_X_ENABLE | XL345_ACT_AC;
xl345Write(4, XL345_THRESH_ACT, &ADXL345Registers[XL345_THRESH_ACT]);
IRQEN|=GP_TIMER_BIT; // Enable ADuC7026's Timer1 interrupt
TimerWaitForStable=0;
}
else if(DetectionStatus==0xF4) // Waiting for long time motionless, but a movement is detected
putchar(DetectionStatus);
ADXL345Registers[XL345_THRESH_ACT]=STRIKE_THRESHOLD;
ADXL345Registers[XL345_TIME_INACT]=STABLE_TIME;
ADXL345Registers[XL345_ACT_INACT_CTL]=XL345_INACT_Z_ENABLE | XL345_INACT_Y_ENABLE
| XL345_INACT_X_ENABLE | XL345_INACT_AC
| XL345_ACT_Z_ENABLE | XL345_ACT_Y_ENABLE
| XL345_ACT_X_ENABLE | XL345_ACT_DC;
xl345Write(4, XL345_THRESH_ACT, &ADXL345Registers[XL345_THRESH_ACT]);
}
}
else if((ADXL345Registers[XL345_INT_SOURCE]&XL345_INACTIVITY)==XL345_INACTIVITY) // Inactivity interrupt asserted
{
if(DetectionStatus==0xF2) // Waiting for stable, and now stable is detected
{
DetectionStatus=0xF3; // Go to Status "F3"
else // Not a continuous free fall
putchar(DetectionStatus);
xl345Read(6, XL345_DATAX0, &ADXL345Registers[XL345_DATAX0]);
DeltaVectorSum=0;
for(i=0;i<3; i++)
{
Acceleration[i]=ADXL345Registers[XL345_DATAX1+i*2]&0x1F;
Acceleration[i]=(Acceleration[i]<<8)|ADXL345Registers[XL345_DATAX0+i*2];
if(Acceleration[i]<0x1000)
{
putchar(DetectionStatus);
}
else //if(Acceleration[i]>=4096)
{
Acceleration[i]=Acceleration[i]-0x1000;
}
ADXL345Registers[XL345_ACT_INACT_CTL]=XL345_INACT_Z_ENABLE
if(Acceleration[i]>InitialStatus[i])
{
DeltaAcceleration[i]=Acceleration[i]-InitialStatus[i];
}
else
{
}
if(DetectionStatus==0xF0) // Waiting for weightless, and now it is detected
DeltaVectorSum=DeltaVectorSum+DeltaAcceleration[i]*DeltaAcceleration[i];
}
if(DeltaVectorSum>DELTA_VECTOR_SUM_THRESHOLD // The stable status is different from the initial status
{
DetectionStatus=0xF4; // Valid fall detection
putchar(DetectionStatus);
ADXL345Registers[XL345_THRESH_ACT]=STABLE_THRESHOLD;
ADXL345Registers[XL345_THRESH_INACT]=NOMOVEMENT_THRESHOLD;
ADXL345Registers[XL345_TIME_INACT]=NOMOVEMENT_TIME;
| XL345_INACT_X_ENABLE | XL345_INACT_AC
| XL345_ACT_Z_ENABLE | XL345_ACT_Y_ENABLE
| XL345_ACT_X_ENABLE | XL345_ACT_AC;
xl345Write(4, XL345_THRESH_ACT, &ADXL345Registers[XL345_THRESH_ACT]);
}
else // Delta vector sum is not exceed the threshold
{
DetectionStatus=0xF0; // Go to Status "F0", restart
putchar(DetectionStatus);
ADXL345Registers[XL345_THRESH_ACT]=STRIKE_THRESHOLD;
ADXL345Registers[XL345_TIME_INACT]=STABLE_TIME;
| XL345_INACT_X_ENABLE | XL345_INACT_AC
| XL345_ACT_Z_ENABLE | XL345_ACT_Y_ENABLE
| XL345_ACT_X_ENABLE | XL345_ACT_DC;
xl345Write(4, XL345_THRESH_ACT, &ADXL345Registers[XL345_THRESH_ACT]);
}
}
else if(DetectionStatus==0xF4) // Wait for long time motionless and now it is detected
{
}
DetectionStatus=0xF5; // Valid critical fall detection
putchar(DetectionStatus);
ADXL345Registers[XL345_THRESH_ACT]=STRIKE_THRESHOLD;
ADXL345Registers[XL345_THRESH_INACT]=NOMOVEMENT_THRESHOLD;
ADXL345Registers[XL345_TIME_INACT]=STABLE_TIME;
| XL345_INACT_X_ENABLE | XL345_INACT_AC
ADXL345Registers[XL345_ACT_INACT_CTL]=XL345_INACT_Z_ENABLE | XL345_INACT_Y_ENABLE
ADXL345Registers[XL345_THRESH_INACT]=NOMOVEMENT_THRESHOLD;
| XL345_ACT_Z_ENABLE | XL345_ACT_Y_ENABLE
| XL345_ACT_X_ENABLE | XL345_ACT_DC;
xl345Write(4, XL345_THRESH_ACT, &ADXL345Registers[XL345_THRESH_ACT]);
DetectionStatus=0xF0; // Go to Status "F0", restart
}
}
else if((ADXL345Registers[XL345_INT_SOURCE]&XL345_FREEFALL)==XL345_FREEFALL) // Free Fall interrupt asserted
{
{
{ // consider that a free fall from high place is detected
DetectionStatus=0xF1; // Go to Status "F1"
沃森仪表
putchar(DetectionStatus);
ADXL345Registers[XL345_THRESH_ACT]=STRIKE_THRESHOLD;
ADXL345Registers[XL345_THRESH_INACT]=NOMOVEMENT_THRESHOLD;
ADXL345Registers[XL345_TIME_INACT]=STABLE_TIME;
ADXL345Registers[XL345_ACT_INACT_CTL]=XL345_INACT_Z_ENABLE | XL345_INACT_Y_ENABLE
| XL345_INACT_X_ENABLE | XL345_INACT_AC
| XL345_ACT_X_ENABLE | XL345_ACT_DC;
xl345Write(4, XL345_THRESH_ACT, &ADXL345Registers[XL345_THRESH_ACT]);
IRQEN|=GP_TIMER_BIT; // Enable ADuC7026's Timer1 interrupt
TimerWaitForStrike=0;
TimerFreeFall=0;
}
else if(DetectionStatus==0xF1) // Waiting for strike after weightless, and now a new free fall is detected
{
if(TimerWaitForStrike
{ // then it is consider as a continuous free fall
TimerFreeFall=TimerFreeFall+TimerWaitForStrike;
}
{
TimerFreeFall=0;
}
TimerWaitForStrike=0;
if(TimerFreeFall>=FREE_FALL_OVERTIME) // if the continuous time of free fall is longer than "FREE_FALL_OVERTIME"
3. Free_Fall中断(掉重)与Activity中断(撞蛔缉之间的时光距离设置为200ms。如不雅跨越200ms,则认为无效。200ms计时须要经由过程MCU中的准时器来实现。
DetectionStatus=0xFF;
putchar(DetectionStatus);
ADXL345Registers[XL345_THRESH_ACT =STRIKE_THRESHOLD;
ADXL345Registers[XL345_THRESH_INACT]=NOMOVEMENT_THRESHOLD;
DeltaAcceleration[i]=InitialStatus[i]-Acceleration[i];
ADXL345Registers[XL345_TIME_INACT]=STABLE_TIME;
| XL345_ACT_Z_ENABLE | XL345_ACT_Y_ENABLE
Acceleration[i]=Acceleration[i]+0x1000;
| XL345_INACT_Y_ENABLE
| XL345_INACT_X_ENABLE | XL345_INACT_AC
| XL345_ACT_Z_ENABLE | XL345_ACT_Y_ENABLE
| XL345_ACT_X_ENABLE | XL345_ACT_DC;
xl345Write(4, XL345_THRESH_ACT, &ADXL345Registers[XL345_THRESH_ACT]);
DetectionStatus=0xF0;
putchar(DetectionStatus);
}
}
else
{
TimerFreeFall=0;
}
IRQEN |=SPM4_IO_BIT; // Enable ADuC7026's external interrupt
}
}
void main(void)
{
ADuC7026_Initiate(); // ADuC7026 initialization
ADXL345_Initiate(); // ADXL345 initialization
DetectionStatus=0xF0; // Clear detection status, Start
InitialStatus[0]=0x1000; // X axis=0g, unsigned short int, 13 bit resolution, 0x1000 = 4096 = 0g, +/-0xFF = +/-256 = +/-1g
本文给出的摔倒检测解决筹划,完全基于ADXL345内部的活动状况检测功能和中断功能,甚至不须要对加快度的具体数值进行及时攫取和复杂的计算操作,可以使算法的复杂度降至最低。
InitialStatus[1]=0x0F00; // Y axis=-1g
InitialStatus[2]=0x1000;// Z axis=0g
IRQEN =SPM4_IO_BIT; // Enable ADuC7026's external interrupt, to receive the interrupt from ADXL345 INT0
while(1) // Endless loop, wait for interrupts
{
;
}
参考材料
1ADXL345数据手册(www.analog.com,搜刮ADXL345)
2ADuC7026数据手册(www.analog.com,搜刮ADuC7026)(end)