Shake Detect

To roll a dice, you pick it up and shake it. Then you toss it down and see where it lands. We'll want to do this with our Circuit Playground dice as well. Let's see if we can use the accelerometer to sense when the Circuit Playground is being shaken.

For an overview of how the accelerometer works on the Circuit Playground, check out this guide. You will see the following plot shown there.

What we are interested in is the SHAKE IT UP! part. That's where the Circuit Playground is being shaken. The lines are the return values from motionX(), motionY(), and motionZ(). This is a mess of positive and negative values with little hope of using simple logic to determine what is going on.

For detecting shaking, all we really care about is the magnitude of the acceleration. We don't care what direction it is being shaken. Therefore, we can use the total acceleration magnitude.

You can use the simple sketch below to try this out.

Download: file
///////////////////////////////////////////////////////////////////////////////
// Circuit Playground Total Acceleration
//
// Author: Carter Nelson
// MIT License (https://opensource.org/licenses/MIT)

#include <Adafruit_CircuitPlayground.h>

float X, Y, Z, totalAccel;
  
///////////////////////////////////////////////////////////////////////////////
void setup() {
  Serial.begin(9600);

  CircuitPlayground.begin();
  CircuitPlayground.setAccelRange(LIS3DH_RANGE_8_G);
}

///////////////////////////////////////////////////////////////////////////////
void loop() {
  X = 0;
  Y = 0;
  Z = 0;
  for (int i=0; i<10; i++) {
    X += CircuitPlayground.motionX();
    Y += CircuitPlayground.motionY();
    Z += CircuitPlayground.motionZ();
    delay(1);
  }
  X /= 10;
  Y /= 10;
  Z /= 10;

  totalAccel = sqrt(X*X + Y*Y + Z*Z);

  Serial.println(totalAccel);

  delay(100);
}

To smooth things out, we take 10 readings and average them. Then the total acceleration is computed with:

totalAccel = sqrt(X*X + Y*Y + Z*Z);

With the above sketch loaded and running on the Circuit Playground, open the Serial Plotter

Tools -> Serial Plotter

and give the Circuit Playground a shake. You should see something like what is shown in the figure below.

It still looks noisy, but if we pick an appropriate value for ROLL_THRESHOLD, then we can detect shaking by simply comparing it to the total acceleration value.

The sketch below uses this idea to play a sound if it detects shaking.

Download: file
///////////////////////////////////////////////////////////////////////////////
// Circuit Playground Shake Detect
//
// Author: Carter Nelson
// MIT License (https://opensource.org/licenses/MIT)

#include <Adafruit_CircuitPlayground.h>

#define ROLL_THRESHOLD  30 // Total acceleration threshold for roll detect

float X, Y, Z, totalAccel;

///////////////////////////////////////////////////////////////////////////////
void setup() {
  Serial.begin(9600);

  CircuitPlayground.begin();
  CircuitPlayground.setAccelRange(LIS3DH_RANGE_8_G);
}

///////////////////////////////////////////////////////////////////////////////
void loop() {
  // Compute total acceleration
  X = 0;
  Y = 0;
  Z = 0;
  for (int i=0; i<10; i++) {
    X += CircuitPlayground.motionX();
    Y += CircuitPlayground.motionY();
    Z += CircuitPlayground.motionZ();
    delay(1);
  }
  X /= 10;
  Y /= 10;
  Z /= 10;

  totalAccel = sqrt(X*X + Y*Y + Z*Z);

  // Play sound if rolling
  if (totalAccel > ROLL_THRESHOLD) {
    CircuitPlayground.playTone(800, 100);
  }
}

Play around with different values of ROLL_THRESHOLD. If it's too low, the detect is too sensitive. If it's too high, you'll break your arm trying to get it to beep. The value of 30 in the above sketch seemed to work OK for me.

This guide was first published on Dec 16, 2016. It was last updated on Dec 16, 2016. This page (Shake Detect) was last updated on Nov 13, 2019.