The next feature we need to add is a time delay for the alarm. Currently, it sounds the instant the slouch angle is exceeded. But what if you were just leaning over to look at something? We should give you a chance to straighten back up before sounding the alarm.
This idea is shown in the figure below, which shows two cases where the current angle exceeded the slouch angle.
We don't want to sound an alarm for the first case (TIME1). That was a brief event like someone bending over to look at something. However, in the second case, the angle has been exceed for a longer period of time (TIME2). Either the person is slouching or has fallen asleep. In either case, we want to sound the alarm.
To make this work, we need to keep track of time. Specifically, how long we've been slouching, and compare that to a preset value (SLOUCH_TIME). We only sound the alarm if (a) we are slouching, and (b) we've been doing so for longer than this preset value.
Here is the code that adds this feature:
/////////////////////////////////////////////////////////////////////////////// // Circuit Playground Slouch Detector v3 // // Push button(s) to set a target angle. // Compute current angle using accelerometer and compare // to preset slouch angle. Sound alarm if slouching after // a preset period of time. // // Author: Carter Nelson // MIT License (https://opensource.org/licenses/MIT) #include <Adafruit_CircuitPlayground.h> #define SLOUCH_ANGLE 10.0 // allowable slouch angle (deg) #define SLOUCH_TIME 3000 // allowable slouch time (secs) #define GRAVITY 9.80665 // standard gravity (m/s^s) #define RAD2DEG 52.29578 // convert radians to degrees float currentAngle; float targetAngle; unsigned long slouchStartTime; bool slouching; /////////////////////////////////////////////////////////////////////////////// void setup() { // Initialize Circuit Playground CircuitPlayground.begin(); // Initialize target angle to zero. targetAngle = 0; } /////////////////////////////////////////////////////////////////////////////// void loop() { // Compute current angle currentAngle = RAD2DEG * asin(-CircuitPlayground.motionZ() / GRAVITY); // Set target angle on button press if ((CircuitPlayground.leftButton()) || (CircuitPlayground.rightButton())) { targetAngle = currentAngle; CircuitPlayground.playTone(900,100); delay(100); CircuitPlayground.playTone(900,100); delay(100); } // Check for slouching if (currentAngle - targetAngle > SLOUCH_ANGLE) { if (!slouching) slouchStartTime = millis(); slouching = true; } else { slouching = false; } // If we are slouching if (slouching) { // Check how long we've been slouching if (millis() - slouchStartTime > SLOUCH_TIME) { // Play a tone CircuitPlayground.playTone(800, 500); } } }
Our new preset value is again set globally at the top of the sketch.
#define SLOUCH_TIME 3000 // allowable slouch time (secs)
We add a few variables to keep track of how long we've been slouching.
unsigned long slouchStartTime; bool slouching;
We replace the alarm with time tracking logic. If we aren't slouching, then we set that value false and nothing else happens. However, if we are currently slouching, we set the value to true and note the time when this started.
// Check for slouching if (currentAngle - targetAngle > SLOUCH_ANGLE) { if (!slouching) slouchStartTime = millis(); slouching = true; } else { slouching = false; }
And then move the alarm to a new set of if statements. If we are currently slouching, then check for how long. If it's been too long, sound the alarm.
// If we are slouching if (slouching) { // Check how long we've been slouching if (millis() - slouchStartTime > SLOUCH_TIME) { // Play a tone CircuitPlayground.playTone(800, 500); } }
And that's it. Now let's see how we can make this thing wearable.
Text editor powered by tinymce.