SIK Experiment Guide for the Arduino 101/Genuino 101 Board

Pages
Contributors: D___Run___
Favorited Favorite 3

Experiment 19: Tap Detection

Introduction

One of the strengths of the 101 board is that it has some pretty sophisticated technology when it comes to gesture and movement recognition. This is all made possible through the Inertial Measurement Unit (IMU) on the 101 board. The IMU measures both accelerometer (gravitational force) and gyroscope (rotation) data. We played around with the accelerometer in Experiment 18. Let's dig a little deeper and leverage the Curie module, which can make sense of the data to determine if you are taking a step and counting them, detecting if you are tapping on the board and even its orientation in space.

As an example of using the combination of the IMU and the the Curie module, we will create a simple RGB circuit that will blink green twice when you double tap on the top of the 101 board and blink red twice when you double tap on the bottom of the 101 board.

Parts Needed

You will need the following parts:

  • 1x Breadboard
  • 1x Arduino 101 or Genuino 101 board
  • 1x Common Cathode RGB LED
  • 3x 100Ω Resistor
  • 6x Jumper Wires

Didn't Get the SIK?

If you are conducting this experiment and didn't get the SIK, we suggest using these parts:

Breadboard - Self-Adhesive (White)

Breadboard - Self-Adhesive (White)

PRT-12002
$4.95
39
Jumper Wires - Connected 6" (M/M, 20 pack)

Jumper Wires - Connected 6" (M/M, 20 pack)

PRT-12795
$1.95
2
Momentary Pushbutton Switch - 12mm Square

Momentary Pushbutton Switch - 12mm Square

COM-09190
$0.50
4
Mini Speaker - PC Mount 12mm 2.048kHz

Mini Speaker - PC Mount 12mm 2.048kHz

COM-07950
$1.95
5

Resistor 100 Ohm 1/4th Watt PTH - 20 pack

COM-13761
Retired

You will also need either an Arduino 101 OR Genuino 101 board.

Arduino 101

DEV-13787
9 Retired

Genuino 101

DEV-13984
Retired

Suggested Reading

Before continuing with this experiment, we recommend you be familiar with the concepts in the following tutorials:

Introducing the Inertial Measurement Unit

An Inertial Measurement Unit (IMU) is a combination of sensors used to determine the sensors' orientation in three-dimensional space. The 101 uses an accelerometer and gyroscope to detect physical orientation (by measuring gravity pulling on the sensor), and a gyroscope to detect rotational motion.

The 101 board can translate the IMU data into certain pre-programmed gestures such as: taking a step, tapping or double tapping on it, or dropping the board. This experiment will focus on detecting taps/double taps, but please play around with the other example code found under File > Examples > CurieIMU.

Note: The 101 board has an IMU populated on the board and is accessed through the Arduino library. There is no wiring required to use the IMU!

Hardware Hookup

Ready to start hooking everything up? Check out the wiring diagram below to see how everything is connected.

Pay special attention to the component’s markings indicating how to place it on the breadboard. Polarized components can only be connected to a circuit in one direction.

Wiring Diagram for the Experiment

alt text

Having a hard time seeing the circuit? Click on the wiring diagram for a closer look.

Open the Sketch

Open the Arduino IDE software on your computer. Coding in the Arduino language will control your circuit. Open the code for Circuit 19 by accessing the “101 SIK Guide Code” you downloaded and placed into your “Examples” folder earlier.

To open the code go to: File > Examples > SIK Guide Code > Circuit_19

You can also copy and paste the following code into the Arduino IDE. Hit upload, and see what happens!

language:cpp
/*
SparkFun Inventor's Kit 
Example sketch 19

TAP DETECTION

Use the 101 board's on-board IMU to detect a tap and double tap and react accordingly.

This sketch was written by SparkFun Electronics,
with lots of help from the Arduino community.
This code is completely free for any use.
Visit http://learn.sparkfun.com/products/2 for SIK information.
Visit http://www.arduino.cc to learn more about Arduino.
*/

#include "CurieIMU.h"

void setup() 
{

 pinMode(5, OUTPUT);
 pinMode(6, OUTPUT);

 // Initialise the IMU
 CurieIMU.begin();
 CurieIMU.attachInterrupt(eventCallback);

 // Increase Accelerometer range to allow detection of stronger taps (< 4g)
 CurieIMU.setAccelerometerRange(3);

 // Reduce threshold to allow detection of weaker taps (>= 750mg)
 CurieIMU.setDetectionThreshold(CURIE_IMU_TAP, 750); // (750mg)

 // Set the time window for 2 taps as a double tap (<= 250 milliseconds)
 CurieIMU.setDetectionDuration(CURIE_IMU_DOUBLE_TAP, 250);

 // Enable Double-Tap detection
 CurieIMU.interrupts(CURIE_IMU_DOUBLE_TAP);
 }

void loop() 
{
 // nothing happens in the loop because all the action happens
 // in the callback function.  
 }

static void eventCallback()
{
 if (CurieIMU.getInterruptStatus(CURIE_IMU_DOUBLE_TAP)) {
    if (CurieIMU.tapDetected(Z_AXIS, NEGATIVE))
    {
    digitalWrite(5, HIGH);
    digitalWrite(6, LOW);
    delay(250);
    digitalWrite(5, LOW);
    digitalWrite(6, LOW);
    delay(250);
    digitalWrite(5, HIGH);
    digitalWrite(6, LOW);
    delay(250);
    digitalWrite(5, LOW);
    digitalWrite(6, LOW);
    delay(250);
    }
   else if (CurieIMU.tapDetected(Z_AXIS, POSITIVE))
   {
    digitalWrite(5, LOW);
    digitalWrite(6, HIGH);
    delay(250);
    digitalWrite(5, LOW);
    digitalWrite(6, LOW);
    delay(250);
    digitalWrite(5, LOW);
    digitalWrite(6, HIGH);
    delay(250);
    digitalWrite(5, LOW);
    digitalWrite(6, LOW);
    delay(250);
   }
  else
  {
  digitalWrite(5, LOW);
  digitalWrite(6, LOW);
  } 
 }
}

Code to Note

CurieIMU.begin();

Initialize or start using the on-board IMU. Without this the 101 board would never register any IMU data.

CurieIMU.attachInterrupt(eventCallback);

Interrupts are events that interrupt the loop and tell the 101 board to do something immediately. The 101 then jumps out of the loop, does that thing, and then gets back into the loop. The interrupt specifies a function to be done when the interrupt is triggered. In this case eventCallback.

 // Reduce threshold to allow detection of weaker taps (>= 750mg)
 CurieIMU.setDetectionThreshold(CURIE_IMU_TAP, 750); // (750mg)

 // Set the time window for 2 taps as a double tap (<= 250 milliseconds)
 CurieIMU.setDetectionDuration(CURIE_IMU_DOUBLE_TAP, 250);

To use the IMU to detect a double tap, some setup is required. You need to set a force threshold for both a hard tap as well as a softer tap. You also need to specify a duration for a double tap so that the Curie can tell the difference between a single tap and a double tap.

CurieIMU.interrupts(CURIE_IMU_DOUBLE_TAP); Finally, we attach the interrupt to the double tap event. So any time a double tap event happens, the 101 board will execute the eventCallback function.

What You Should see

Once the code is uploaded the RGB should be off. Pick up the board and double tap the top of the board with your finger at a rhythm and timing that is similar to a mouse double click. The RGB should blink the color green twice and then turn off again. If you do the same thing with the bottom of the board, it will blink red.

alt text

Troubleshooting

Library Not Compiling

Double check that you have an #include "CurieIMU.h" statement. If you do, make sure the header file name is in quotes and not chevrons.

Not Getting a Double Tap

The 101 is looking for a specific timing range for a double tap. Try speeding up your taps or adjusting the double tap timing in the CurieIMU.setDetectionDuration(CURIE_IMU_DOUBLE_TAP, 250); method.

Still Not Working

You can set the sensitivity of the accelerometer. The example is set to 2Gs or twice the amount of gravity we normally experience on Earth. If you make that smaller, it will increase the sensitivity.