找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5351|回复: 0
打印 上一主题 下一主题
收起左侧

三轴加速度传感器BMA223调试记录

[复制链接]
跳转到指定楼层
楼主
ID:393021 发表于 2018-9-3 15:49 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
BMA223调试记录

一、运动中断检测
1.斜率运动
寄存器:                                                                                      参数设置:            
0x00              BMA2x2_CHIP_ID_REG
0x0f              BMA2x2_RANGE_SEL_REG:   0x03    //量程(+-)2g
0x10              BMA2x2_BW_SEL_REG:      0x0f              //带宽1000Hz
0x16              BMA2x2_INT_ENABLE1_REG:  0x07   //在组0中使能斜率中断
0x19              BMA2x2_INT1_PAD_SEL_REG: 0x04   //斜率中断信号映射到 INT1 引脚
0x1b              BMA2x2_INT2_PAD_SEL_REG: 0x04   //斜率中断信号映射到 INT2 引脚
0x20              BMA2x2_INT_SET_REG:     0x05   //设置INT1/INT2 引脚空闲高电平
0x21              BMA2x2_INT_CTRL_REG:    0x8e   //设置中断延时50ms后 复位
0x27              BMA2x2_SLOPE_DURN_REG:  0x03   //设置中断连续样本数据点个数
0x28              BMA2x2_SLOPE_THRES_REG: 0x14 //设置中断阈值 20*3.91mg = 78.2 mg


slope(t 0 + Δ t)= acc(t 0 + Δ t) - acc(t 0 )
使用连续加速度信号之间的斜率来检测运动的变化。当斜率(加速度差的绝对值)超过预设阈值时,产生中断。一旦斜率降到阈值以下,中断被清除


2.1慢/无运动之慢运动
SLOW_NO_MOTION :*15.63 mg (8-g range)--:threshold->5(78mg)~8(125 mg)
寄存器:                                                                                      参数设置:            
0x00              BMA2x2_CHIP_ID_REG
0x0f              BMA2x2_RANGE_SEL_REG:   0x03    //量程(+-)8g
0x10              BMA2x2_BW_SEL_REG:      0x0f              //带宽1000Hz
0x18              BMA2x2_INT_SLO_NO_MOT_REG: 0x07   //在组2中使能慢/无运动中断
0x19              BMA2x2_INT1_PAD_SEL_REG: 0x08   //斜率中断信号映射到 INT1 引脚
0x1b              BMA2x2_INT2_PAD_SEL_REG: 0x08   //斜率中断信号映射到 INT2 引脚
0x20              BMA2x2_INT_SET_REG:     0x05   //设置INT1/INT2 引脚空闲高电平
0x21              BMA2x2_INT_CTRL_REG:    0x8e    //设置中断延时50ms后 复位
0x27              BMA2x2_SLO_NO_MOT_THRES_REG: 0x28 //设置中断连续样本数据点个数
0x28              BMA2x2_SLO_NO_MOT_THRES_REG: 0x14 //设置中断阈

在慢动作模式中,当至少一个使能轴的测量斜率超过可编程数量的样本的可编程斜率阈值时,触发中断。 因此,引擎的行为类似于任意运动中断,但具有不同的参数集。 为了抑制误触发,如果一定数量N的连续斜率数据点大于(小于)由(0x27)slo_no_mot_dur <1:0>给出的斜率阈值,则仅产生(清除)中断。 数字是N =(0x27)slo_no_mot_dur <1:0> + 1


2.2慢/无运动之无运动
NO_MOTION :*15.63 mg
0x00              BMA2x2_CHIP_ID_REG
0x0f              BMA2x2_RANGE_SEL_REG:   0x08    //(+-)8g
0x10              BMA2x2_BW_SEL_REG:      0x0f              //1000Hz
0x18              BMA2x2_INT_SLO_NO_MOT_REG:0x0F //*在组2中使能慢/无运动中断0x19              BMA2x2_INT1_PAD_SEL_REG: 0x08   //斜率中断信号映射到 INT1 引脚
0x1b              BMA2x2_INT2_PAD_SEL_REG: 0x08   //斜率中断信号映射到 INT2 引脚
0x20              BMA2x2_INT_SET_REG:     0x05   //设置INT1/INT2 引脚空闲高电平
0x21              BMA2x2_INT_CTRL_REG:    0x8e   //设置中断延时50ms后 复位
0x27              BMA2x2_SLO_NO_MOT_THRES_REG:0x08 //设置中断触发条件持续时间
0x28              BMA2x2_SLO_NO_MOT_THRES_REG: 0x10   //设置中断阈值

在非运动模式下,如果所有选定轴上的斜率在可编程延迟时间内保持小于可编程阈值,则会产生中断。阈值的缩放与慢动作中断的缩放相同。 但是,在无运动模式寄存器(0x27)中,slo_no_mot_dur定义了触发无运动中断之前的延迟时间。 表19列出了使用寄存器(0x27)slo_no_mot_dur调整的延迟时间。 计时器滴答周期为1秒。 因此,使用短延迟时间会导致相当大的时序不确定性。


3.1HIGH_G 运动中断:
0x00              BMA2x2_CHIP_ID_REG
0x0f              BMA2x2_RANGE_SEL_REG:   0x03    //(+-)2g
0x10              BMA2x2_BW_SEL_REG:      0x0f              //1000Hz
0x17              BMA2x2_INT_ENABLE1_REG:  0x07   //在组2中使能HIGH_G运动中断
0x19              BMA2x2_INT1_PAD_SEL_REG: 0x04   //斜率中断信号映射到 INT1 引脚0x1b              BMA2x2_INT2_PAD_SEL_REG: 0x04   //斜率中断信号映射到 INT2 引脚
0x20              BMA2x2_INT_SET_REG:     0x05   //设置INT1/INT2 引脚空闲高电平
0x21              BMA2x2_INT_CTRL_REG:    0x1e    //设置中断延时50ms后 复位
0x24              BMA2x2_LOW_HIGH_HYST_REG 0x41  //high-g 中断滞后:*125 mg
0x25              BMA2x2_HIGH_DURN_REG :  0x18 //设置中断触发条件持续时间[0x18+1] * 2 ms
0x26              BMA2x2_HIGH_THRES_REG:   0xC0    //设置中断阈值
threshold:0xC0->192 (default)  192*7.81mg = 1499 mg
如果使能的三个轴(或关系)里至少有一个的加速度绝对值高于阈值,并且至少持续寄存器(0x25)high_dur里定义的时间,则产生高g中断。
如果使能的三个轴(与关系,也就是全部轴)的加速度绝对值低于阈值,并且至少持续寄存器(0x25)high_dur里定义的时间,则高g中断产生复位。在位(0x09)high_int中存储中断状态。

3.2LOW_G 运动中断:
0x00              BMA2x2_CHIP_ID_REG
0x0f              BMA2x2_RANGE_SEL_REG:   0x03    //(+-)2g
0x10              BMA2x2_BW_SEL_REG:      0x0f              //1000Hz
0x17              BMA2x2_INT_ENABLE1_REG:  0x07   //在组2中使能HIGH_G运动中断
0x19              BMA2x2_INT1_PAD_SEL_REG: 0x04   //斜率中断信号映射到 INT1 引脚0x1b              BMA2x2_INT2_PAD_SEL_REG: 0x04   //斜率中断信号映射到 INT2 引脚
0x20              BMA2x2_INT_SET_REG:     0x05   //设置INT1/INT2 引脚空闲高电平
0x21              BMA2x2_INT_CTRL_REG:    0x1e    //设置中断延时50ms后 复位
0x24              BMA2x2_LOW_HIGH_HYST_REG 0x41  //high-g 中断滞后:*125 mg
0x25              BMA2x2_HIGH_DURN_REG :  0x18 //设置中断触发条件持续时间[0x18+1] * 2 ms
0x26              BMA2x2_HIGH_THRES_REG:   0xC0    //设置中断阈值
threshold:0xC0->192 (default)  192*7.81mg = 1499 mg
如果所有轴的加速度的绝对值(在单模式下为'and'关系)或它们的总和(在和模式的情况下)至少在定义的时间内低于阈值,则产生低g中断 通过(0x22)low_dur寄存器。
如果至少一个轴的加速度的绝对值(在单模式的情况下为'or'关系)或绝对值的总和(在和模式的情况下)至少一次的数据采集中高于阈值加滞后,则重置中断。 在位(0x09)low_int中存储中断状态。



4.1双击检测
0x00              BMA2x2_CHIP_ID_REG
0x0f              BMA2x2_RANGE_SEL_REG:   0x08    //(+-)8g
0x10              BMA2x2_BW_SEL_REG:      0x0f              //1000Hz
0x16              BMA2x2_INT_SLO_NO_MOT_REG: 0x10   //在组0中使能双击运动中断
0x19              BMA2x2_INT1_PAD_SEL_REG: 0x10   //斜率中断信号映射到 INT1 引脚
0x1b              BMA2x2_INT2_PAD_SEL_REG: 0x10   //斜率中断信号映射到 INT2 引脚
0x20              BMA2x2_INT_SET_REG:     0x05   //设置INT1/INT2 引脚空闲高电平
0x21              BMA2x2_INT_CTRL_REG:    0x8e    //设置中断延时50ms后 复位
0x2A              BMA2x2_TAP_PARAM_REG:  0x07     //设置中断第二击的时间窗口
                                                                                                                                                                        0X06-->500ms,0x07-->700ms
0x2B              BMA2x2_TAP_THRES_REG: 0x14    //设置中断阈值
threshold*250 mg (8-g range)--:threshold->2(500mg)~10(2500mg)


4.2单击检测
0x00              BMA2x2_CHIP_ID_REG
0x0f              BMA2x2_RANGE_SEL_REG:   0x08    //(+-)8g
0x10              BMA2x2_BW_SEL_REG:      0x0f              //1000Hz
0x16              BMA2x2_INT_SLO_NO_MOT_REG: 0x10   //在组0中使能双击运动中断
0x19              BMA2x2_INT1_PAD_SEL_REG: 0x10   //斜率中断信号映射到 INT1 引脚
0x1b              BMA2x2_INT2_PAD_SEL_REG: 0x10   //斜率中断信号映射到 INT2 引脚
0x20              BMA2x2_INT_SET_REG:     0x05   //设置INT1/INT2 引脚空闲高电平
0x21              BMA2x2_INT_CTRL_REG:    0x8e    //设置中断延时50ms后 复位
0x2A              BMA2x2_TAP_PARAM_REG:  0x07     //设置中断第二击的时间窗口
                                                                                                                                                                        0X06-->500ms,0x07-->700ms
0x2B              BMA2x2_TAP_THRES_REG: 0x14    //设置中断阈值
threshold:0x14->20 (default)  20*3.91mg = 78.2 mg

如果超过至少一个轴的加速度的预定义斜率,则检测到轻敲事件。区分两个不同的点击事件:“单击”是特定时间内的单个事件,然后是某个安静时间。 “双击”包括第一个这样的事件,然后是在规定的时间范围内的第二个事件。


二、静态特殊方向检测:
1.在静止的情况下三轴加速度数据,其中两个轴的数据几乎接近0(>0mg&&<60mg),另一个轴数据接近1000mg。
  1. if((GsensorDataHX<14) && (GsensorDataHX >0))
  2.                             {
  3.                                           if((GsensorDataHY<14) && (GsensorDataHY>0))
  4.                                           {
  5.                                                         if((GsensorDataHZ<80) && (GsensorDataHZ>28) && (GsensorDataZ ==0))
  6.                                                                       printf("positive\r\n");                                                      
  7.                                                         else if((GsensorDataHZ<80) && (GsensorDataHZ>28) && (GsensorDataZ ==1))
  8.                                                                       printf("negative \r\n");                                                      
  9.                                           }
  10.                             }
  11.                             if((GsensorDataHX<14) && (GsensorDataHX >0))
  12.                             {
  13.                                           if((GsensorDataHZ<14) && (GsensorDataHZ>0))
  14.                                           {
  15.                                                         if((GsensorDataHY<80) && (GsensorDataHY>28) && (GsensorDataY ==0))
  16.                                                                       printf("Left\r\n");                                                                    
  17.                                                         else if((GsensorDataHY<80) && (GsensorDataHY>28) && (GsensorDataY ==1))
  18.                                                                       printf("Right \r\n");                                                                                                
  19.                                           }
  20.                             }
  21.                             if((GsensorDataHY<14) && (GsensorDataHY >0))
  22.                             {
  23.                                           if((GsensorDataHZ<14) && (GsensorDataHZ>0))
  24.                                           {
  25.                                                         if((GsensorDataHX<80) && (GsensorDataHX>28) && (GsensorDataX ==0))
  26.                                                                       printf("Front\r\n");                                                                                                                           
  27.                                                         else if((GsensorDataHX<80) &&(GsensorDataHX>28) && (GsensorDataX ==1))
  28.                                                                       printf("Back \r\n");                                                                                                
  29.                                           }
  30.                             }
复制代码

三、加速度数据的运动检测
三轴的合加速度G =重力加速度G0+动态加速度Gv
静止时,SVM约等于重力加速度,运动时,G的幅值SVM围绕着重力加速度G=G0上下浮动,此时Gv的幅值SS(i)会大于0。
1.对当前数据点进行动态与静态识别:SVM>1050 --->动态点
2.对动态点的各轴数据进行幅值测试分析
  1.               for(jtemp=x_flag;jtemp<=z_flag;jtemp++)
  2.               {                          
  3.                             array3[jtemp]=array2[jtemp];
  4.                             array2[jtemp]=array1[jtemp];
  5.                             array1[jtemp]=array0[jtemp];                                       
  6. array0[jtemp]= GsensorData [jtemp];                                                                                                  adresult[jtemp]=array0[jtemp]+array1[jtemp]
  7. +array2[jtemp]+array3[jtemp];
  8.               GsensorData_tem_devi[jtemp]=(sumdata-adresult[jtemp)/4;
  9. }
复制代码

四、计步器
1. 滑动窗口采样滤波,找出最大小值
  1. for(jtemp=x_flag;jtemp<=z_flag;jtemp++)
  2.               {                          
  3.                             array3[jtemp]=array2[jtemp];
  4.                             array2[jtemp]=array1[jtemp];
  5.                             array1[jtemp]=array0[jtemp];                                       
  6. array0[jtemp]= GsensorData [jtemp];                                                                                                  adresult[jtemp]=array0[jtemp]+array1[jtemp]
  7. +array2[jtemp]+array3[jtemp];
  8.               adresult[jtemp]=adresult[jtemp]>>2;
  9. if(adresult[jtemp]>max[jtemp])
  10.    max[jtemp]=adresult[jtemp];
  11. if(adresult[jtemp]<min[jtemp])  
  12.                 min[jtemp]=adresult[jtemp];
  13. }
复制代码

2. 计算动态门限和动态精度,采集四五十次数据调整一次
门限值vpp[jtemp]:              30
中值dc[jtemp]:                            500
精度precision[jtemp]:              5
  1. if(sampling_counter>=40)
  2.                                {            
  3.                                   sampling_counter=0;                                       
  4.                                           for(jtemp=0;jtemp<=2;jtemp++)
  5.                                           {
  6.                                                         vpp[jtemp]=max[jtemp]-min[jtemp];
  7.                                                         dc[jtemp] =min[jtemp]+(vpp[jtemp]>>1);
  8.                                                         max[jtemp]=0;
  9.                                                         min[jtemp]=1023;
  10.                                                         bad_flag[jtemp]=0;
  11.                                                         if(vpp[jtemp]>=160)
  12.                                                         {
  13.                                                                       precision[jtemp]=vpp[jtemp]/32; //8
  14.                                                         }
  15.                                                         else if((vpp[jtemp]>=50)&& (vpp[jtemp]<160))         
  16.                                                         {
  17.                                                                       precision[jtemp]=4;
  18.                                                         }
  19.                                                         else if((vpp[jtemp]>=15) && (vpp[jtemp]<50))
  20.                                                         {
  21.                                                                       precision[jtemp]=3;
  22.                                                         }                                          
  23.                                                         else
  24.                                                         {
  25.                                                                                     precision[jtemp]=2;
  26.                                                                                     bad_flag[jtemp]=1;
  27.                                                         }                                       
  28.                                           }
  29.                               }   
复制代码


3. 线性移位寄存器,找出最近两次采集数据之间差异最大的值
  1. for(jtemp=0;jtemp<=2;jtemp++)
  2.               {
  3.                             old_fixed[jtemp]=new_fixed[jtemp];
  4.                   if(adresult[jtemp]>=new_fixed[jtemp]){
  5. if((adresult[jtemp]-new_fixed[jtemp])>=precision[jtemp])   new_fixed[jtemp]=adresult[jtemp];
  6.                   }
  7.                   else if(adresult[jtemp]<new_fixed[jtemp]){
  8. if((new_fixed[jtemp]-adresult[jtemp])>=precision[jtemp])
  9. new_fixed[jtemp]=adresult[jtemp];
  10.                   }
  11.               }
复制代码


4. 动态门限判决,找出两次数据间最大门限值,并判断是否在窗口内进行计步。
  1. if((vpp[0]>=vpp[1])&&(vpp[0]>=vpp[2])){
  2.                             if((old_fixed[0]>=dc[0])&&(new_fixed[0]<dc[0])&&(bad_flag[0]==0)) {                                       
  3.                                           printf("X STEP+1 \r\n ");
  4.                                           Time_Window();
  5.                             }
  6.               }
  7.               else if((vpp[1]>=vpp[0])&&(vpp[1]>=vpp[2])){
  8.                             if((old_fixed[1]>=dc[1])&&(new_fixed[1]<dc[1])&&(bad_flag[1]==0)) {                                       
  9.                                           printf("Y STEP+1 \r\n ");
  10.                                           Time_Window();
  11.                             }
  12.               }
  13.               else if((vpp[2]>=vpp[1])&&(vpp[2]>=vpp[0])){
  14.                             if((old_fixed[2]>=dc[2])&&(new_fixed[2]<dc[2])&&(bad_flag[2]==0)) {                          
  15.                                           printf("Z STEP+1 \r\n ");
  16.                                           Time_Window();
  17.                             }
  18.               }            
复制代码
5.时间窗口
  1. /*------------------------------------------------------------------------------------------------------------------------  
  2. #define TIMEWINDOW_MIN 10        //0.2s     
  3. #define TIMEWINDOW_MAX 100       //2s     
  4. #define REGULATION  4           //   
  5. #define INVALID     2           //
  6. unsigned char Interval=0;       //  
  7. unsigned char TempSteps=0;      //   
  8. unsigned char InvalidSteps=0;   //   
  9. unsigned char ReReg=2;          //   
  10.                                         //  2-   
  11.                                         //  1-   
  12.                                         //  0-         
  13. *------------------------------------------------------------------------------------------------------------------------*/   
  14. void Time_Window(void)   
  15. {   
  16.               Interval=time_win_value;
  17.               time_win_value=0;
  18.     if(ReReg==2)        //  
  19.     {   
  20.         TempSteps++;   
  21.         Interval=0;   
  22.         ReReg=1;   
  23.         InvalidSteps=0;     
  24.     }   
  25.     else                //   
  26.     {
  27.                             printf("Interval:----%d --- \r\n ",Interval);            
  28.         if((Interval>=TIMEWINDOW_MIN)&&(Interval<=TIMEWINDOW_MAX))    //   
  29.         {   
  30.             InvalidSteps=0;     
  31.             if(ReReg==1)                    //  
  32.             {   
  33.                                                                       TempSteps++;                //   
  34.                                                                       if(TempSteps>=REGULATION)    //   
  35.                                                                       {   
  36.                                                                                     ReReg=0;                //   
  37.                                                                                     STEPS=STEPS+TempSteps;  //   
  38.                                                                                     TempSteps=0;                                                                                                               
  39.                                                                                     printf("STEPS+tempstep:%d  \r\n\r\n ",STEPS);            
  40.                                                                       }   
  41.                                                                       Interval=0;   
  42.             }   
  43.             else if(ReReg==0)               //   
  44.             {                                                                                                                                                                                                                     
  45.                                                         STEPS++;   
  46.                                                         TempSteps=0;   
  47.                                                         Interval=0;                                                                                    
  48.                                                         printf("STEPS:%d  \r\n\r\n ",STEPS);            
  49.             }
  50.                                           printf("timer is ok ! \r\n\r\n ");            
  51.         }   
  52.         else if(Interval<TIMEWINDOW_MIN)  //                          
  53.                             {                                                                     
  54.                                           if(ReReg==0)  //            
  55.                                           {
  56.                                                         InvalidSteps++;                             //
  57.                                                         if(InvalidSteps>=INVALID)   //
  58.                                                         {      
  59.                                                                       InvalidSteps=0;   
  60.                                                                       ReReg=1;                                                                                                               
  61.                                                                       TempSteps=1;   
  62.                                                                       Interval=0;   
  63.                                                         }   
  64.                                                         else                                    //     
  65.                                                                       Interval=0;      
  66.                                           }   
  67.                                           else if(ReReg==1)               //  
  68.                                           {   
  69.                                                         InvalidSteps=0;     
  70.                                                         ReReg=1;   
  71.                                                         TempSteps=1;   
  72.                                                         Interval=0;   
  73.                                           }
  74.                                           printf("timer is smaler ! \r\n\r\n ");            
  75.                             }   
  76.                             else if(Interval>TIMEWINDOW_MAX) //     
  77.                             {   
  78.                                           InvalidSteps=0;     
  79.                                           ReReg=1;                           
  80.                                           TempSteps=1;   
  81.                                           Interval=0;
  82.                                           printf("timer is bigger ! \r\n\r\n ");
  83.                             }   
  84.     }           
  85. }   
复制代码

完整的Word格式文档51黑下载地址:
8.16.1调试记录.docx (48.29 KB, 下载次数: 34)


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表