【Arduino101教程】IMU中断检测-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 5384|回复: 0

【Arduino101教程】IMU中断检测

[复制链接]
发表于 2017-3-12 17:35 | 显示全部楼层 |阅读模式
除了姿态检测外,IMU还可以用于设备运动状态的检测。CurieIMU自带了多种运动状态检测模式,检测到相关状态后,可以生成一个中断事件,并执行相应的中断函数。
要使用该功能,需要先定义一个中断函数:
  
static void eventCallback() {
  
//函数内容
  
}
  
中断函数应无参数无返回值。
与I/O的中断类似,IMU中断同样需要指定中断函数和中断模式。中断函数的设置语句如下:
  
//设置中断函数
  
CurieIMU.attachInterrupt(eventCallback);
  
eventCallback即中断函数名,当中断触发后,会运行该函数名对应的中断函数。
中断模式设置语句如下:
  
//设置中断模式
  
CurieIMU.interrupts(CURIE_IMU_MODE);
  
其中参数CURIE_IMU_MODE为中断模式,CurieIMU支持的中断模式如表x-xx
  
中断模式
  
对应枚举值
自由落体
CURIE_IMU_FREEFALL
震动检测
CURIE_IMU_SHOCK
运动检测
CURIE_IMU_MOTION
零移检测
CURIE_IMU_ZERO_MOTION
计步功能
CURIE_IMU_STEP
单击检测
CURIE_IMU_TAP
敲击并震动检测
CURIE_IMU_TAP_SHOCK
敲击并禁止检测
CURIE_IMU_TAP_QUIET
双击检测
CURIE_IMU_DOUBLE_TAP
当设定的中断模式被触发后,即会运行中断函数eventCallback
如果不再需要IMU中断,则可以使用中断分离语句关闭中断功能。语句如下:
  
CurieIMU.detachInterrupt();
  

利用CurieIMU中断,我们可检测Genuino101是否在移动的,并得知移动方向。可通过Arduino IDE菜单>文件>示例>CurieIMU> ZeroMotionDetect 打开运动检测示例,示例程序如下:
  
/*
  
    Copyright (c) 2016 Intel Corporation.   All rights reserved.
  
    See the bottom of this file for full license terms.
  
*/
  
  
/*
  
    This sketch example demonstrates how the BMI160 accelerometer on the
  
    Intel(R) Curie(TM) module can be used to detect zero motion events
  
*/
  
  
#include "CurieIMU.h"
  
  
boolean ledState = false;          // state of the LED
  
void setup() {
  
   Serial.begin(9600); // initialize Serial communication
  
   while(!Serial) ;    // wait for  serial port to connect.
  
  
   /* Initialise the IMU */
  
   CurieIMU.begin();
  
   CurieIMU.attachInterrupt(eventCallback);
  
  
   /* Enable Zero Motion Detection */
  
   CurieIMU.setDetectionThreshold(CURIE_IMU_ZERO_MOTION, 50);  // 50mg
  
   CurieIMU.setDetectionDuration(CURIE_IMU_ZERO_MOTION, 2);    // 2s
  
   CurieIMU.interrupts(CURIE_IMU_ZERO_MOTION);
  
  
   /* Enable Motion Detection */
  
   CurieIMU.setDetectionThreshold(CURIE_IMU_MOTION, 20);      // 20mg
  
   CurieIMU.setDetectionDuration(CURIE_IMU_MOTION, 10);       // trigger times of consecutive slope  data points
  
   CurieIMU.interrupts(CURIE_IMU_MOTION);
  
  
   Serial.println("IMU initialisation complete, waiting for events...");
  
}
  
  
void loop() {
  
   // if zero motion is detected, LED will be turned up.
  
   digitalWrite(13, ledState);
  
}
  
  
static void eventCallback(void){
  
   if (CurieIMU.getInterruptStatus(CURIE_IMU_ZERO_MOTION)) {
  
     ledState = true;
  
     Serial.println("zero motion detected...");
  
   }  
  
   if (CurieIMU.getInterruptStatus(CURIE_IMU_MOTION)) {
  
     ledState = false;
  
     if (CurieIMU.motionDetected(X_AXIS, POSITIVE))
  
       Serial.println("Negative motion detected on X-axis");
  
     if (CurieIMU.motionDetected(X_AXIS, NEGATIVE))
  
       Serial.println("Positive motion detected on X-axis");
  
     if (CurieIMU.motionDetected(Y_AXIS, POSITIVE))
  
       Serial.println("Negative motion detected on Y-axis");
  
     if (CurieIMU.motionDetected(Y_AXIS, NEGATIVE))
  
       Serial.println("Positive motion detected on Y-axis");
  
     if (CurieIMU.motionDetected(Z_AXIS, POSITIVE))
  
       Serial.println("Negative motion detected on Z-axis");
  
     if (CurieIMU.motionDetected(Z_AXIS, NEGATIVE))
  
       Serial.println("Positive motion detected on Z-axis");
  
   }  
  
}
  
编译上传以上程序,打开串口监视器,并将Genuino 101移动或保持静止,可见串口输出类似信息:

当Genuino 101静止时,CurieIMU.getInterruptStatus(CURIE_IMU_ZERO_MOTION)会返回true;而运动时,CurieIMU.getInterruptStatus(CURIE_IMU_MOTION)会返回true。而使用CurieIMU.motionDetected(X_AXIS,POSITIVE)可以检测该运动是否延着X轴正方向,如果是该函数会返回true。

利用IMU的中断检测功能,可以制作一个非接触式开关LED试验。试验代码如下:
  
#include  "CurieIMU.h"
  
  
bool  state=false;
  
void  setup() {
  
  pinMode(13,OUTPUT);
  
  CurieIMU.begin();
  
  CurieIMU.attachInterrupt(eventCallback);
  
  
  // Increase Accelerometer range to allow  detection of stronger taps (< 16g)
  
  CurieIMU.setAccelerometerRange(32);
  
  CurieIMU.setAccelerometerRate(1600);
  
  
  // Reduce threshold to allow detection of  weaker taps (>= 100mg)
  
   CurieIMU.setDetectionThreshold(CURIE_IMU_TAP, 100);
  
  
  // Enable Tap detection
  
  CurieIMU.interrupts(CURIE_IMU_TAP);
  
}
  
  
void  loop() {
  
}
  
  
static  void eventCallback()
  
{
  
  if  (CurieIMU.getInterruptStatus(CURIE_IMU_TAP)) {
  
    state =!state;
  
    digitalWrite(13,state);
  
  }
  
}
  
编译并上传以上代码后,将Genuino 101平放在桌面上,敲击桌面,即可控制板载LED灯的亮灭。

相关IMU的应用案例还有很多,如计步器。计步器是基于IMU功能的常见应用,智能手机、智能手表几乎都具备此功能,CurieIMU自带四种记步模式,可以满足多种场合的计步需求。

  
模式
  
对应枚举值
正常模式
CURIE_IMU_STEP_MODE_NORMAL
敏感模式
CURIE_IMU_STEP_MODE_SENSITIVE
健壮模式
CURIE_IMU_STEP_MODE_ROBUST
未知模式
CURIE_IMU_STEP_MODE_UNKNOWN

通常使用正常模式即可,语句如下:
  
// 切换到正常计步模式
  
CurieIMU.setStepDetectionMode(CURIE_IMU_STEP_MODE_NORMAL);
  
// 开启计步功能
  
CurieIMU.setStepCountEnabled(true);
  


完整示例程序如下:
  
  
#include "CurieIMU.h"
  
  
boolean stepEventsEnabeled = true;
  
long lastStepCount = 0;
  
  
void setup() {
  
   Serial.begin(9600);
  
   while(!Serial) ;
  
   // 初始化IMU
  
   CurieIMU.begin();
  
   // 切换到正常计步模式
  
   CurieIMU.setStepDetectionMode(CURIE_IMU_STEP_MODE_NORMAL);
  
   // 开启计步功能
  
   CurieIMU.setStepCountEnabled(true);
  
  
   if (stepEventsEnabeled) {
  
     // 关联中断函数
  
CurieIMU.attachInterrupt(eventCallback);
  
// 启用步数检测中断
  
     CurieIMU.interrupts(CURIE_IMU_STEP);
  
     Serial.println("IMU initialisation complete, waiting for  events...");
  
  }
  
}
  
  
void loop() {
  
   //loop中定时检查步数并输出,而不使用计步事件通知
  
   if (!stepEventsEnabeled) {
  
     updateStepCount();
  
  }
  
   delay(1000);
  
}
  
  
static void updateStepCount() {
  
   // 获取步数
  
   int stepCount = CurieIMU.getStepCount();
  
   // 如果步数有更新,则串口输出
  
   if (stepCount != lastStepCount) {
  
     Serial.print("Step count: ");
  
     Serial.println(stepCount);
  
     // 保存步数,用以下一次比较
  
     lastStepCount = stepCount;
  
  }
  
}
  
  
static void eventCallback(void) {
  
   if (CurieIMU.stepsDetected())
  
     updateStepCount();
  
}
  
  
编译上传以上程序,并打开串口监视器,模拟走路姿势摇动Genuino 101,即可看到串口输出步数信息。

-------------------------------------------------------------------------------------------------------------
本教程分为五部分:
1.配置IMU及获取数据   http://www.arduino.cn/thread-42850-1-1.html
2.结算AHRS姿态   http://www.arduino.cn/thread-42851-1-1.html
3.姿态数据可视化   http://www.arduino.cn/thread-42852-1-1.html
4.IMU中断检测   http://www.arduino.cn/thread-42853-1-1.html
5.神经元与机器学习   http://www.arduino.cn/thread-42854-1-1.html

相关帖子

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

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-11-30 23:58 , Processed in 0.127966 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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