概要

ここでは、Arduinoでジェスチャセンサ(APDS-9960)を使用する方法を記載する。
実際に、上下左右にLEDを配置して、ジェスチャセンサの前で手を上下左右に振った方向にあるLEDを点灯させる。

Arduinoは5[V]で動作するが、APDS-9960は3[V]〜3.8[V]で動作するので、
もし、Arduinoクローンを使用している場合は、接続するために双方向レベルシフタが必要な可能性が高い。
双方向レベルシフタの接続において、3.3[V]側、5[V]側、それぞれに電源を接続して、レベルシフトする線同士を同じチャネルに接続するだけである。

また、APDS-9960は、GY-9960LLCというモジュールで駆動させている。

ピンアウトは下図の通り、電源(VIN)とGND、I2Cインターフェイス(SCLとSDA)およびび割り込みピンである。
I2Cインターフェイスは、Arduino UNOであればA4(SDA)とA5(SCL)、Arduino Megaであれば20(SDA)と21(SCL)に接続する。
また、I2Cインターフェイスは、10[kΩ]程度の抵抗でプルアップする。


割り込みピンは、Arduino UnoではD2(割り込み番号 : 0)である。
詳細は、Arduinoの基礎の"割り込みとISR"セクションを参照すること。

また、LEDの電流制限抵抗は、220[Ω]とする。



サンプルコード

サンプルコードでは、SparkfunのAPDS-9960ライブラリを使用している。
Arduino IDEのライブラリマネージャから9960で検索して、ライブラリをインストールすること。

正常に動作すると、手を振った方向にあるLEDが点灯する。

 #include <Wire.h>
 #include <SparkFun_APDS9960.h>
 
 const int APDS9960_INT = 2;
 const int PIN_LED_RIGHT = 8;
 const int PIN_LED_LEFT = 9;
 const int PIN_LED_UP = 10;
 const int PIN_LED_DOWN = 11;
 
 SparkFun_APDS9960 apds = SparkFun_APDS9960();
 int isr_flag = 0;
 
 void setup()
 {
    Serial.begin(9600);
 
    pinMode(APDS9960_INT, INPUT);
 
    pinMode( PIN_LED_RIGHT, OUTPUT );
    pinMode( PIN_LED_LEFT, OUTPUT );
    pinMode( PIN_LED_UP, OUTPUT );
    pinMode( PIN_LED_DOWN, OUTPUT );
 
    digitalWrite( PIN_LED_RIGHT, LOW );
    digitalWrite( PIN_LED_LEFT, LOW );
    digitalWrite( PIN_LED_UP, LOW );
    digitalWrite( PIN_LED_DOWN, LOW );
 
    attachInterrupt( digitalPinToInterrupt(APDS9960_INT), interruptRoutine, FALLING);
 
    if ( !apds.init() )
    {
       Serial.println("Failed to initialize APDS-9960.");
    }
 
    if ( !apds.enableGestureSensor(true) )
    {
       Serial.println("Could not start APDS-9960.");
    }
 }
 
 void loop()
 {
    if( isr_flag == 1 )
    {
       detachInterrupt(0);
       handleGesture();
       isr_flag = 0;
       attachInterrupt(0, interruptRoutine, FALLING);
    }
 }
 
 void interruptRoutine()
 {
    isr_flag = 1;
 }
 
 void handleGesture()
 {
    if ( apds.isGestureAvailable() )
    {
       switch ( apds.readGesture() )
       {
          case DIR_UP:
             turnOnLED( PIN_LED_UP );
             break;
          case DIR_DOWN:
             turnOnLED( PIN_LED_DOWN );
             break;
          case DIR_LEFT:
             turnOnLED( PIN_LED_LEFT );
             break;
          case DIR_RIGHT:
             turnOnLED( PIN_LED_RIGHT );
             break;
       }
    }
 }
 
 void turnOnLED( int ledPin )
 {
    digitalWrite( ledPin, HIGH );
    delay( 1000 );
    digitalWrite( ledPin, LOW );
 }