fdsg

Dependencies:   BLE_API MicroBitEffectsPedal nRF51822

Fork of microbit-dal by Lancaster University

Files at this revision

API Documentation at this revision

Comitter:
LancasterUniversity
Date:
Wed Jul 13 12:18:17 2016 +0100
Parent:
37:b624ae5e94a5
Child:
39:112df23f039f
Commit message:
Synchronized with git rev b5846f06
Author: Joe Finney
microbit: Fixed unreachable High-G gesture events [issue #109]

Ammended basic gesture recogniser to correclty generate threshold events for
high G forces (3G, 6G and 8G threshold events).

Also refined semantics such that events for any given impulse will be
generated for ALL thresholds below that below. e.g a 7G impulse will now raise
both the 3G and 6G threshold events.

Changed in this revision

inc/drivers/MicroBitAccelerometer.h Show annotated file Show diff for this revision Revisions of this file
source/drivers/MicroBitAccelerometer.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/inc/drivers/MicroBitAccelerometer.h	Wed Jul 13 12:18:16 2016 +0100
+++ b/inc/drivers/MicroBitAccelerometer.h	Wed Jul 13 12:18:17 2016 +0100
@@ -155,8 +155,12 @@
                 x:1,
                 y:1,
                 z:1,
+                unused,
+                impulse_3,
+                impulse_6,
+                impulse_8,
                 count:4,
-                timer:8;
+                timer:4;
 };
 
 /**
@@ -176,6 +180,7 @@
     MicroBitI2C&    i2c;                // The I2C interface to use.
     float           roll;               // Roll of the device, in radians.
     uint8_t         sigma;              // the number of ticks that the instantaneous gesture has been stable.
+    uint8_t         impulseSigma;       // the number of ticks since an impulse event has been generated.
     BasicGesture    lastGesture;        // the last, stable gesture recorded.
     BasicGesture    currentGesture;     // the instantaneous, unfiltered gesture detected.
     ShakeHistory    shake;              // State information needed to detect shake events.
@@ -464,4 +469,4 @@
     BasicGesture instantaneousPosture();
 };
 
-#endif
+#endif
\ No newline at end of file
--- a/source/drivers/MicroBitAccelerometer.cpp	Wed Jul 13 12:18:16 2016 +0100
+++ b/source/drivers/MicroBitAccelerometer.cpp	Wed Jul 13 12:18:17 2016 +0100
@@ -189,6 +189,7 @@
 
     // Initialise gesture history
     this->sigma = 0;
+    this->impulseSigma = 0;
     this->lastGesture = GESTURE_NONE;
     this->currentGesture = GESTURE_NONE;
     this->shake.x = 0;
@@ -196,6 +197,10 @@
     this->shake.z = 0;
     this->shake.count = 0;
     this->shake.timer = 0;
+    this->shake.tap = 1;
+    this->shake.impulse_3 = 1;
+    this->shake.impulse_6 = 1;
+    this->shake.impulse_8 = 1;
 
     // Configure and enable the accelerometer.
     if (this->configure() == MICROBIT_OK)
@@ -318,9 +323,9 @@
  */
 BasicGesture MicroBitAccelerometer::instantaneousPosture()
 {
-    int force = instantaneousAccelerationSquared();
     bool shakeDetected = false;
 
+
     // Test for shake events.
     // We detect a shake by measuring zero crossings in each axis. In other words, if we see a strong acceleration to the left followed by
     // a strong acceleration to the right, then we can infer a shake. Similarly, we can do this for each axis (left/right, up/down, in/out).
@@ -358,21 +363,11 @@
         }
     }
 
+    // Shake events take the highest priority, as under high levels of change, other events
+    // are likely to be transient.
     if (shake.shaken)
         return GESTURE_SHAKE;
 
-    if (force < MICROBIT_ACCELEROMETER_FREEFALL_THRESHOLD)
-        return GESTURE_FREEFALL;
-
-    if (force > MICROBIT_ACCELEROMETER_3G_THRESHOLD)
-        return GESTURE_3G;
-
-    if (force > MICROBIT_ACCELEROMETER_6G_THRESHOLD)
-        return GESTURE_6G;
-
-    if (force > MICROBIT_ACCELEROMETER_8G_THRESHOLD)
-        return GESTURE_8G;
-
     // Determine our posture.
     if (getX() < (-1000 + MICROBIT_ACCELEROMETER_TILT_TOLERANCE))
         return GESTURE_LEFT;
@@ -401,6 +396,39 @@
   */
 void MicroBitAccelerometer::updateGesture()
 {
+    // Check for High/Low G force events - typically impulses, impacts etc.
+    // Again, during such spikes, these event take priority of the posture of the device.
+    // For these events, we don't perform any low pass filtering.
+    int force = instantaneousAccelerationSquared();
+
+    if (force > MICROBIT_ACCELEROMETER_3G_THRESHOLD)
+    {
+        if (force > MICROBIT_ACCELEROMETER_3G_THRESHOLD && !shake.impulse_3)
+        {
+            MicroBitEvent e(MICROBIT_ID_GESTURE, GESTURE_3G);
+            shake.impulse_3 = 1;
+        }
+        if (force > MICROBIT_ACCELEROMETER_6G_THRESHOLD && !shake.impulse_6)
+        {
+            MicroBitEvent e(MICROBIT_ID_GESTURE, GESTURE_6G);
+            shake.impulse_6 = 1;
+        }
+        if (force > MICROBIT_ACCELEROMETER_8G_THRESHOLD && !shake.impulse_8)
+        {
+            MicroBitEvent e(MICROBIT_ID_GESTURE, GESTURE_8G);
+            shake.impulse_8 = 1;
+        }
+
+        impulseSigma = 0;
+    }
+
+    // Reset the impulse event onve the acceleration has subsided.
+    if (impulseSigma < MICROBIT_ACCELEROMETER_GESTURE_DAMPING)
+        impulseSigma++;
+    else
+        shake.impulse_3 = shake.impulse_6 = shake.impulse_8 = 0;
+
+
     // Determine what it looks like we're doing based on the latest sample...
     BasicGesture g = instantaneousPosture();