After a lot of shaking, you might wear your arm out. So let's add another way to roll the dice. The accelerometer on the Circuit Playground has a built in tap detect function. Let's use that to allow the dice to be rolled by taping the Circuit Playground.
There are two library functions associated with this feature:
setAccelTap();
getAccelTap();
There are also a couple of example sketches that you can look at to explore the tap detect feature. You can access them via:
File -> Examples -> Adafruit Circuit Playground -> accelTap
and
File -> Examples -> Adafruit Circuit Playground -> comm_badge
In each of these you will see something like this cryptic line:
attachInterrupt(digitalPinToInterrupt(7), myFunction, RISING);
This is setting up a function callback for an interrupt. This is somewhat of an advanced topic, but you can think of it as off loading the tap detection work to the accelerometer hardware. What the above line of code does is set things up so that when the accelerometer detects tap(s), the function myFunction
will be called. It's up to you to create myFunction
to do what you want, and the name can be any valid name.
If you look at the code in the accelTap example, you will see that there is no code in the loop()
function. That's because the function tapTime()
is being called via the interrupt.
You can still put code in the loop()
function if you want. In fact, we'll be doing that for our D6 Dice. Here's another example that will be more like how we will use the tap detect for our dice. The callback function simply sets a flag. We then look for the state of that flag in loop()
.
/////////////////////////////////////////////////////////////////////////////// // Circuit Playground Tap Detect // // Author: Carter Nelson // MIT License (https://opensource.org/licenses/MIT) #include <Adafruit_CircuitPlayground.h> #define TAP_THRESHOLD 10 // Tap detect threshold bool tapDetected; /////////////////////////////////////////////////////////////////////////////// void tapCallback() { tapDetected = true; } /////////////////////////////////////////////////////////////////////////////// void setup(void) { Serial.begin(9600); CircuitPlayground.begin(); CircuitPlayground.setAccelRange(LIS3DH_RANGE_8_G); CircuitPlayground.setAccelTap(2, TAP_THRESHOLD); attachInterrupt(digitalPinToInterrupt(7), tapCallback, FALLING); tapDetected = false; } /////////////////////////////////////////////////////////////////////////////// void loop() { if (tapDetected) { Serial.println("TAP!"); tapDetected = false; } }
Note that we set up the detect for double tap by passing in a 2 in the setup()
function:
CircuitPlayground.setAccelTap(2, TAP_THRESHOLD);
The way this works it that in the loop()
function we look for a boolean value which is set to true in the interrupt callback function tapCallback()
. This boolean is then set to false so that the print statement only happens once, until another double tap causes it to be true. Etc. Etc.
Text editor powered by tinymce.