Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: BLE_API mbed-dev-bin nRF51822
Fork of microbit-dal by
Revision 38:1a9e8e5e23f2, committed 2016-07-13
- 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
--- 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();
