Example of single tap and double tap detection for LSM6DSL in X-NUCLEO-IKS01A2
Dependencies: X_NUCLEO_IKS01A2 mbed
Fork of SingleDoubleTap_IKS01A2 by
Single and Double Tap Demo Application based on sensor expansion board X-NUCLEO-IKS01A2
Main function is to show how to detect the single and double tap events using the sensor expansion board and send a notification using UART to a connected PC or Desktop and display it on terminal applications like TeraTerm.
After connection has been established:
- the user can try to tap the board and then view the notification using an hyper terminal. When the single tap is detected,
the LED is switched on for a while.
- the user can press the user button to pass from the single tap detection to the double tap detection feature. The user can try to double tap the board and then view the notification using an hyper terminal. When the double tap is detected, the LED is switched on twice for a while.
- the user can press again the user button to disable the single and double tap detection feature.
- the user can press the user button to enable again the single tap detection feature and so on.
Revision 7:4f512b172555, committed 2016-11-24
- Comitter:
- cparata
- Date:
- Thu Nov 24 16:45:55 2016 +0000
- Parent:
- 6:2380444e4c75
- Child:
- 8:0e76b8668551
- Commit message:
- Add possibility to choose the interrupt line for HW events
Changed in this revision
--- a/X_NUCLEO_IKS01A2/Components/LSM6DSLSensor/LSM6DSLSensor.cpp Wed Nov 23 16:46:14 2016 +0000
+++ b/X_NUCLEO_IKS01A2/Components/LSM6DSLSensor/LSM6DSLSensor.cpp Thu Nov 24 16:45:55 2016 +0000
@@ -861,6 +861,17 @@
*/
int LSM6DSLSensor::Enable_Free_Fall_Detection(void)
{
+ return Enable_Free_Fall_Detection(LSM6DSL_INT1_PIN);
+}
+
+/**
+ * @brief Enable free fall detection
+ * @param pin the interrupt pin to be used
+ * @note This function sets the LSM6DSL accelerometer ODR to 416Hz and the LSM6DSL accelerometer full scale to 2g
+ * @retval 0 in case of success, an error code otherwise
+*/
+int LSM6DSLSensor::Enable_Free_Fall_Detection(LSM6DSL_Interrupt_Pin_t pin)
+{
/* Output Data Rate selection */
if(Set_X_ODR(416.0f) == 1)
{
@@ -909,9 +920,24 @@
return 1;
}
- /* INT1_FF setting */
- if ( LSM6DSL_ACC_GYRO_W_FFEvOnInt1( (void *)this, LSM6DSL_ACC_GYRO_INT1_FF_ENABLED ) == MEMS_ERROR )
+ /* Enable free fall event on either INT1 or INT2 pin */
+ switch (pin)
{
+ case LSM6DSL_INT1_PIN:
+ if ( LSM6DSL_ACC_GYRO_W_FFEvOnInt1( (void *)this, LSM6DSL_ACC_GYRO_INT1_FF_ENABLED ) == MEMS_ERROR )
+ {
+ return 1;
+ }
+ break;
+
+ case LSM6DSL_INT2_PIN:
+ if ( LSM6DSL_ACC_GYRO_W_FFEvOnInt2( (void *)this, LSM6DSL_ACC_GYRO_INT2_FF_ENABLED ) == MEMS_ERROR )
+ {
+ return 1;
+ }
+ break;
+
+ default:
return 1;
}
@@ -925,12 +951,18 @@
*/
int LSM6DSLSensor::Disable_Free_Fall_Detection(void)
{
- /* INT1_FF setting */
+ /* Disable free fall event on INT1 pin */
if ( LSM6DSL_ACC_GYRO_W_FFEvOnInt1( (void *)this, LSM6DSL_ACC_GYRO_INT1_FF_DISABLED ) == MEMS_ERROR )
{
return 1;
}
+ /* Disable free fall event on INT2 pin */
+ if ( LSM6DSL_ACC_GYRO_W_FFEvOnInt2( (void *)this, LSM6DSL_ACC_GYRO_INT2_FF_DISABLED ) == MEMS_ERROR )
+ {
+ return 1;
+ }
+
/* Disable basic Interrupts */
if ( LSM6DSL_ACC_GYRO_W_BASIC_INT( (void *)this, LSM6DSL_ACC_GYRO_BASIC_INT_DISABLED ) == MEMS_ERROR )
{
@@ -1104,6 +1136,17 @@
* @retval 0 in case of success, an error code otherwise
*/
int LSM6DSLSensor::Enable_Tilt_Detection(void)
+{
+ return Enable_Tilt_Detection(LSM6DSL_INT1_PIN);
+}
+
+/**
+ * @brief Enable the tilt detection for LSM6DSL accelerometer sensor
+ * @param pin the interrupt pin to be used
+ * @note This function sets the LSM6DSL accelerometer ODR to 26Hz and the LSM6DSL accelerometer full scale to 2g
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::Enable_Tilt_Detection(LSM6DSL_Interrupt_Pin_t pin)
{
/* Output Data Rate selection */
if( Set_X_ODR(26.0f) == 1 )
@@ -1128,13 +1171,28 @@
{
return 1;
}
-
- /* Enable tilt event on INT1. */
- if ( LSM6DSL_ACC_GYRO_W_TiltEvOnInt1( (void *)this, LSM6DSL_ACC_GYRO_INT1_TILT_ENABLED ) == MEMS_ERROR )
+
+ /* Enable tilt detection on either INT1 or INT2 pin */
+ switch (pin)
{
+ case LSM6DSL_INT1_PIN:
+ if ( LSM6DSL_ACC_GYRO_W_TiltEvOnInt1( (void *)this, LSM6DSL_ACC_GYRO_INT1_TILT_ENABLED ) == MEMS_ERROR )
+ {
+ return 1;
+ }
+ break;
+
+ case LSM6DSL_INT2_PIN:
+ if ( LSM6DSL_ACC_GYRO_W_TiltEvOnInt2( (void *)this, LSM6DSL_ACC_GYRO_INT2_TILT_ENABLED ) == MEMS_ERROR )
+ {
+ return 1;
+ }
+ break;
+
+ default:
return 1;
}
-
+
return 0;
}
@@ -1150,6 +1208,12 @@
return 1;
}
+ /* Disable tilt event on INT2. */
+ if ( LSM6DSL_ACC_GYRO_W_TiltEvOnInt2( (void *)this, LSM6DSL_ACC_GYRO_INT2_TILT_DISABLED ) == MEMS_ERROR )
+ {
+ return 1;
+ }
+
/* Disable tilt calculation. */
if ( LSM6DSL_ACC_GYRO_W_TILT( (void *)this, LSM6DSL_ACC_GYRO_TILT_DISABLED ) == MEMS_ERROR )
{
@@ -1172,6 +1236,17 @@
*/
int LSM6DSLSensor::Enable_Wake_Up_Detection(void)
{
+ return Enable_Wake_Up_Detection(LSM6DSL_INT2_PIN);
+}
+
+/**
+ * @brief Enable the wake up detection for LSM6DSL accelerometer sensor
+ * @param pin the interrupt pin to be used
+ * @note This function sets the LSM6DSL accelerometer ODR to 416Hz and the LSM6DSL accelerometer full scale to 2g
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::Enable_Wake_Up_Detection(LSM6DSL_Interrupt_Pin_t pin)
+{
/* Output Data Rate selection */
if( Set_X_ODR(416.0f) == 1 )
{
@@ -1201,10 +1276,25 @@
{
return 1;
}
-
- /* INT2_WU setting */
- if ( LSM6DSL_ACC_GYRO_W_WUEvOnInt2( (void *)this, LSM6DSL_ACC_GYRO_INT2_WU_ENABLED ) == MEMS_ERROR )
+
+ /* Enable wake up detection on either INT1 or INT2 pin */
+ switch (pin)
{
+ case LSM6DSL_INT1_PIN:
+ if ( LSM6DSL_ACC_GYRO_W_WUEvOnInt1( (void *)this, LSM6DSL_ACC_GYRO_INT1_WU_ENABLED ) == MEMS_ERROR )
+ {
+ return 1;
+ }
+ break;
+
+ case LSM6DSL_INT2_PIN:
+ if ( LSM6DSL_ACC_GYRO_W_WUEvOnInt2( (void *)this, LSM6DSL_ACC_GYRO_INT2_WU_ENABLED ) == MEMS_ERROR )
+ {
+ return 1;
+ }
+ break;
+
+ default:
return 1;
}
@@ -1217,7 +1307,13 @@
*/
int LSM6DSLSensor::Disable_Wake_Up_Detection(void)
{
- /* INT2_WU setting */
+ /* Disable wake up event on INT1 */
+ if ( LSM6DSL_ACC_GYRO_W_WUEvOnInt1( (void *)this, LSM6DSL_ACC_GYRO_INT1_WU_DISABLED ) == MEMS_ERROR )
+ {
+ return 1;
+ }
+
+ /* Disable wake up event on INT2 */
if ( LSM6DSL_ACC_GYRO_W_WUEvOnInt2( (void *)this, LSM6DSL_ACC_GYRO_INT2_WU_DISABLED ) == MEMS_ERROR )
{
return 1;
@@ -1266,6 +1362,17 @@
*/
int LSM6DSLSensor::Enable_Single_Tap_Detection(void)
{
+ return Enable_Single_Tap_Detection(LSM6DSL_INT1_PIN);
+}
+
+/**
+ * @brief Enable the single tap detection for LSM6DSL accelerometer sensor
+ * @param pin the interrupt pin to be used
+ * @note This function sets the LSM6DSL accelerometer ODR to 416Hz and the LSM6DSL accelerometer full scale to 2g
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::Enable_Single_Tap_Detection(LSM6DSL_Interrupt_Pin_t pin)
+{
/* Output Data Rate selection */
if( Set_X_ODR(416.0f) == 1 )
{
@@ -1324,9 +1431,24 @@
return 1;
}
- /* Enable single tap interrupt on INT1 pin. */
- if ( LSM6DSL_ACC_GYRO_W_SingleTapOnInt1( (void *)this, LSM6DSL_ACC_GYRO_INT1_SINGLE_TAP_ENABLED ) == MEMS_ERROR )
+ /* Enable single tap on either INT1 or INT2 pin */
+ switch (pin)
{
+ case LSM6DSL_INT1_PIN:
+ if ( LSM6DSL_ACC_GYRO_W_SingleTapOnInt1( (void *)this, LSM6DSL_ACC_GYRO_INT1_SINGLE_TAP_ENABLED ) == MEMS_ERROR )
+ {
+ return 1;
+ }
+ break;
+
+ case LSM6DSL_INT2_PIN:
+ if ( LSM6DSL_ACC_GYRO_W_SingleTapOnInt2( (void *)this, LSM6DSL_ACC_GYRO_INT2_SINGLE_TAP_ENABLED ) == MEMS_ERROR )
+ {
+ return 1;
+ }
+ break;
+
+ default:
return 1;
}
@@ -1345,6 +1467,12 @@
return 1;
}
+ /* Disable single tap interrupt on INT2 pin. */
+ if ( LSM6DSL_ACC_GYRO_W_SingleTapOnInt2( (void *)this, LSM6DSL_ACC_GYRO_INT2_SINGLE_TAP_DISABLED ) == MEMS_ERROR )
+ {
+ return 1;
+ }
+
/* Disable basic Interrupts */
if ( LSM6DSL_ACC_GYRO_W_BASIC_INT( (void *)this, LSM6DSL_ACC_GYRO_BASIC_INT_DISABLED ) == MEMS_ERROR )
{
@@ -1401,6 +1529,17 @@
*/
int LSM6DSLSensor::Enable_Double_Tap_Detection(void)
{
+ return Enable_Double_Tap_Detection(LSM6DSL_INT1_PIN);
+}
+
+/**
+ * @brief Enable the double tap detection for LSM6DSL accelerometer sensor
+ * @param pin the interrupt pin to be used
+ * @note This function sets the LSM6DSL accelerometer ODR to 416Hz and the LSM6DSL accelerometer full scale to 2g
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::Enable_Double_Tap_Detection(LSM6DSL_Interrupt_Pin_t pin)
+{
/* Output Data Rate selection */
if( Set_X_ODR(416.0f) == 1 )
{
@@ -1467,9 +1606,24 @@
return 1;
}
- /* Enable double tap interrupt on INT1 pin. */
- if ( LSM6DSL_ACC_GYRO_W_TapEvOnInt1( (void *)this, LSM6DSL_ACC_GYRO_INT1_TAP_ENABLED ) == MEMS_ERROR )
+ /* Enable double tap on either INT1 or INT2 pin */
+ switch (pin)
{
+ case LSM6DSL_INT1_PIN:
+ if ( LSM6DSL_ACC_GYRO_W_TapEvOnInt1( (void *)this, LSM6DSL_ACC_GYRO_INT1_TAP_ENABLED ) == MEMS_ERROR )
+ {
+ return 1;
+ }
+ break;
+
+ case LSM6DSL_INT2_PIN:
+ if ( LSM6DSL_ACC_GYRO_W_TapEvOnInt2( (void *)this, LSM6DSL_ACC_GYRO_INT2_TAP_ENABLED ) == MEMS_ERROR )
+ {
+ return 1;
+ }
+ break;
+
+ default:
return 1;
}
@@ -1488,6 +1642,12 @@
return 1;
}
+ /* Disable double tap interrupt on INT2 pin. */
+ if ( LSM6DSL_ACC_GYRO_W_TapEvOnInt2( (void *)this, LSM6DSL_ACC_GYRO_INT2_TAP_DISABLED ) == MEMS_ERROR )
+ {
+ return 1;
+ }
+
/* Disable basic Interrupts */
if ( LSM6DSL_ACC_GYRO_W_BASIC_INT( (void *)this, LSM6DSL_ACC_GYRO_BASIC_INT_DISABLED ) == MEMS_ERROR )
{
@@ -1612,6 +1772,17 @@
*/
int LSM6DSLSensor::Enable_6D_Orientation(void)
{
+ return Enable_6D_Orientation(LSM6DSL_INT1_PIN);
+}
+
+/**
+ * @brief Enable the 6D orientation detection for LSM6DSL accelerometer sensor
+ * @param pin the interrupt pin to be used
+ * @note This function sets the LSM6DSL accelerometer ODR to 416Hz and the LSM6DSL accelerometer full scale to 2g
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::Enable_6D_Orientation(LSM6DSL_Interrupt_Pin_t pin)
+{
/* Output Data Rate selection */
if( Set_X_ODR(416.0f) == 1 )
{
@@ -1636,9 +1807,24 @@
return 1;
}
- /* INT1_6D setting. */
- if ( LSM6DSL_ACC_GYRO_W_6DEvOnInt1( (void *)this, LSM6DSL_ACC_GYRO_INT1_6D_ENABLED ) == MEMS_ERROR )
+ /* Enable 6D orientation on either INT1 or INT2 pin */
+ switch (pin)
{
+ case LSM6DSL_INT1_PIN:
+ if ( LSM6DSL_ACC_GYRO_W_6DEvOnInt1( (void *)this, LSM6DSL_ACC_GYRO_INT1_6D_ENABLED ) == MEMS_ERROR )
+ {
+ return 1;
+ }
+ break;
+
+ case LSM6DSL_INT2_PIN:
+ if ( LSM6DSL_ACC_GYRO_W_6DEvOnInt2( (void *)this, LSM6DSL_ACC_GYRO_INT2_6D_ENABLED ) == MEMS_ERROR )
+ {
+ return 1;
+ }
+ break;
+
+ default:
return 1;
}
@@ -1651,12 +1837,18 @@
*/
int LSM6DSLSensor::Disable_6D_Orientation(void)
{
- /* INT1_6D setting. */
+ /* Disable 6D orientation interrupt on INT1 pin. */
if ( LSM6DSL_ACC_GYRO_W_6DEvOnInt1( (void *)this, LSM6DSL_ACC_GYRO_INT1_6D_DISABLED ) == MEMS_ERROR )
{
return 1;
}
+ /* Disable 6D orientation interrupt on INT2 pin. */
+ if ( LSM6DSL_ACC_GYRO_W_6DEvOnInt2( (void *)this, LSM6DSL_ACC_GYRO_INT2_6D_DISABLED ) == MEMS_ERROR )
+ {
+ return 1;
+ }
+
/* Disable basic Interrupts */
if ( LSM6DSL_ACC_GYRO_W_BASIC_INT( (void *)this, LSM6DSL_ACC_GYRO_BASIC_INT_DISABLED ) == MEMS_ERROR )
{
@@ -1892,7 +2084,7 @@
return 1;
}
- if(Md1_Cfg & LSM6DSL_ACC_GYRO_INT1_FF_MASK)
+ if((Md1_Cfg & LSM6DSL_ACC_GYRO_INT1_FF_MASK) || (Md2_Cfg & LSM6DSL_ACC_GYRO_INT2_FF_MASK))
{
if((Wake_Up_Src & LSM6DSL_ACC_GYRO_FF_EV_STATUS_MASK))
{
@@ -1900,7 +2092,7 @@
}
}
- if(Md2_Cfg & LSM6DSL_ACC_GYRO_INT2_WU_MASK)
+ if((Md1_Cfg & LSM6DSL_ACC_GYRO_INT1_WU_MASK) || (Md2_Cfg & LSM6DSL_ACC_GYRO_INT2_WU_MASK))
{
if((Wake_Up_Src & LSM6DSL_ACC_GYRO_WU_EV_STATUS_MASK))
{
@@ -1908,7 +2100,7 @@
}
}
- if(Md1_Cfg & LSM6DSL_ACC_GYRO_INT1_SINGLE_TAP_MASK)
+ if((Md1_Cfg & LSM6DSL_ACC_GYRO_INT1_SINGLE_TAP_MASK) || (Md2_Cfg & LSM6DSL_ACC_GYRO_INT2_SINGLE_TAP_MASK))
{
if((Tap_Src & LSM6DSL_ACC_GYRO_SINGLE_TAP_EV_STATUS_MASK))
{
@@ -1916,7 +2108,7 @@
}
}
- if(Md1_Cfg & LSM6DSL_ACC_GYRO_INT1_TAP_MASK)
+ if((Md1_Cfg & LSM6DSL_ACC_GYRO_INT1_TAP_MASK) || (Md2_Cfg & LSM6DSL_ACC_GYRO_INT2_TAP_MASK))
{
if((Tap_Src & LSM6DSL_ACC_GYRO_DOUBLE_TAP_EV_STATUS_MASK))
{
@@ -1924,7 +2116,7 @@
}
}
- if(Md1_Cfg & LSM6DSL_ACC_GYRO_INT1_6D_MASK)
+ if((Md1_Cfg & LSM6DSL_ACC_GYRO_INT1_6D_MASK) || (Md2_Cfg & LSM6DSL_ACC_GYRO_INT2_6D_MASK))
{
if((D6D_Src & LSM6DSL_ACC_GYRO_D6D_EV_STATUS_MASK))
{
@@ -1932,7 +2124,7 @@
}
}
- if(Int1_Ctrl & LSM6DSL_ACC_GYRO_INT1_PEDO_MASK)
+ if((Int1_Ctrl & LSM6DSL_ACC_GYRO_INT1_PEDO_MASK))
{
if((Func_Src & LSM6DSL_ACC_GYRO_PEDO_EV_STATUS_MASK))
{
@@ -1940,7 +2132,7 @@
}
}
- if(Md1_Cfg & LSM6DSL_ACC_GYRO_INT1_TILT_MASK)
+ if((Md1_Cfg & LSM6DSL_ACC_GYRO_INT1_TILT_MASK) || (Md2_Cfg & LSM6DSL_ACC_GYRO_INT2_TILT_MASK))
{
if((Func_Src & LSM6DSL_ACC_GYRO_TILT_EV_STATUS_MASK))
{
--- a/X_NUCLEO_IKS01A2/Components/LSM6DSLSensor/LSM6DSLSensor.h Wed Nov 23 16:46:14 2016 +0000
+++ b/X_NUCLEO_IKS01A2/Components/LSM6DSLSensor/LSM6DSLSensor.h Thu Nov 24 16:45:55 2016 +0000
@@ -99,6 +99,12 @@
/* Typedefs ------------------------------------------------------------------*/
+typedef enum
+{
+ LSM6DSL_INT1_PIN,
+ LSM6DSL_INT2_PIN
+} LSM6DSL_Interrupt_Pin_t;
+
typedef struct
{
unsigned int FreeFallStatus : 1;
@@ -142,6 +148,7 @@
int Disable_X(void);
int Disable_G(void);
int Enable_Free_Fall_Detection(void);
+ int Enable_Free_Fall_Detection(LSM6DSL_Interrupt_Pin_t pin);
int Disable_Free_Fall_Detection(void);
int Set_Free_Fall_Threshold(uint8_t thr);
int Enable_Pedometer(void);
@@ -150,19 +157,24 @@
int Reset_Step_Counter(void);
int Set_Pedometer_Threshold(uint8_t thr);
int Enable_Tilt_Detection(void);
+ int Enable_Tilt_Detection(LSM6DSL_Interrupt_Pin_t pin);
int Disable_Tilt_Detection(void);
int Enable_Wake_Up_Detection(void);
+ int Enable_Wake_Up_Detection(LSM6DSL_Interrupt_Pin_t pin);
int Disable_Wake_Up_Detection(void);
int Set_Wake_Up_Threshold(uint8_t thr);
int Enable_Single_Tap_Detection(void);
+ int Enable_Single_Tap_Detection(LSM6DSL_Interrupt_Pin_t pin);
int Disable_Single_Tap_Detection(void);
int Enable_Double_Tap_Detection(void);
+ int Enable_Double_Tap_Detection(LSM6DSL_Interrupt_Pin_t pin);
int Disable_Double_Tap_Detection(void);
int Set_Tap_Threshold(uint8_t thr);
int Set_Tap_Shock_Time(uint8_t time);
int Set_Tap_Quiet_Time(uint8_t time);
int Set_Tap_Duration_Time(uint8_t time);
int Enable_6D_Orientation(void);
+ int Enable_6D_Orientation(LSM6DSL_Interrupt_Pin_t pin);
int Disable_6D_Orientation(void);
int Get_6D_Orientation_XL(uint8_t *xl);
int Get_6D_Orientation_XH(uint8_t *xh);
--- a/main.cpp Wed Nov 23 16:46:14 2016 +0000
+++ b/main.cpp Thu Nov 24 16:45:55 2016 +0000
@@ -49,19 +49,19 @@
InterruptIn mybutton(USER_BUTTON);
DigitalOut myled(LED1);
-volatile int tap = 0;
+volatile int mems_event = 0;
volatile int change_mode = 0;
static int mode = 1; /* 0 means No tap, 1 means Single Tap enabled, 2 means Double Tap enabled*/
-void pressed();
-void tap_cb();
+void pressed_cb();
+void INT1_cb();
/* Simple main function */
int main() {
/* Attach callback to User button press */
- mybutton.fall(&pressed);
+ mybutton.fall(&pressed_cb);
/* Attach callback to LSM6DSL INT1 */
- acc_gyro->AttachINT1IRQ(&tap_cb);
+ acc_gyro->AttachINT1IRQ(&INT1_cb);
/* Enable LSM6DSL accelerometer */
acc_gyro->Enable_X();
@@ -91,8 +91,8 @@
}
}
- if (tap) {
- tap = 0;
+ if (mems_event) {
+ mems_event = 0;
switch(mode) {
case 0:
default:
@@ -132,10 +132,10 @@
}
}
-void pressed() {
+void pressed_cb() {
change_mode = 1;
}
-void tap_cb() {
- tap = 1;
+void INT1_cb() {
+ mems_event = 1;
}
