Nano 33 BLE Senseで近接検出

Nano 33 BLE Senseの内蔵近接センサーを用いて、内蔵RGB LEDを制御する方法を学びます。


AUTHOR: Fabricio Troya、LAST REVISION: 2023/02/20 18:07


このチュートリアルでは、内蔵されているAPDS9960センサーにより実現される近接検出を行うのに、Arduino Nano 33 BLE Senseを利用します。

単純な近接検出を表示し、ボードのRGB LEDを制御するために、センサーを使います。さらに、ボードへの物体の接近により、RGB LEDの色を変化させるようボードをプログラムします。

目的

このプロジェクトの目的は以下の通りです。

  • APDS9960センサーがどのように動作るかを学びます。
  • APDS9960ライブラリを使用します。
  • Arduino Nano 33 BLE Senseから生のセンサーデータを出力する方法を学びます。
  • 近接検出モニターを作ります。
  • 近接データの値を使い、RGB LEDを制御する方法を学びます。

必要なハードウェアとソフトウェア

  • このプロジェクトでは、外部のセンサーや機器を利用しません。
  • このチュートリアルでは、ボードのプログラムを記述するのに、Arduino Webエディタを利用します。

APDS9960センサー

APDS9960センサーは、高度なジェスチャー検出、近接検出、デジタル周辺光検出(ALS: Ambient Light Sense)、色検出(RGBC)を提供する多目的デバイスです。

APDSS9960センサー

APDSS9960センサー

センサーのジェスチャー検出は、4方向のフォトダイオードを利用し、内蔵LEDを光源とする反射赤外線エネルギー検出し、物理的な動作情報(速度や方向、距離など)をデジタル信号に変換します。

以下の機能を持ちます。

  • 異なる方向に反応する4つの独立したダイオード
  • 周辺光除去
  • オフセット補償
  • 赤外線LED電流用プログラマブルドライバー
  • 32個のデータセットのFIFOストレージ
  • 割り込みベースのI2Cバス通信

APDS9960センサーモジュールの詳細を知りたければ、こちらを参照してください。

ライブラリ

APDS9960ライブラリは、ボード上のセンサーを利用し、ジェスチャーや色、明るさ、近接を読み取ります。ライブラリは以下のような関数を提供します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
begin()
end()
gestureAvailable()
readGesture()
colorAvailable()
readColor()
proximityAvailable()
readProximity()
setGestureSensitivity()
setInterruptPin()
setLEDBoost()

ライブラリの各関数をさらに深く理解したい場合は、Arduinoリファレンスを参照してください。

このチュートリアルの目的のため、4つのフォトダイオードの物体検出を基本に、センサー内部でミリメートルに変換した、距離を読み取ることに焦点をあてます。

プログラム作成

  1. 設定

Arduino Webエディタを開き、Librariesタブをクリックし、APDS9960ライブラリを探します。その後、> Examplesで、ProximitySensorスケッチを開きます。開いた後は、Proximity_LEDという名前に変更します。

Webエディタでライブラリを探す

Webエディタでライブラリを探す

  1. ボードを接続する

次に、Arduino Nano 33 BLE SenseをPCに接続し、Webエディタが認識することを確認します。すると、ポートとボードが以下の図で示すように現れます。現れない場合は、指示に従いエディタがボードを認識するためのプラグインをインストールしてください。

ボードを選択する

ボードを選択する

  1. 距離による点滅パータン

距離によりRGB LEDの色を変化させるために、スケッチ例のコードを修正します。

1
2
3
4
5
6
7
8
9
#include <Arduino_APDS9960.h>

int ledState = LOW;

unsigned long previousMillis = 0;

const long intervalLong = 1000;
const long intervalMed = 500;
const long intervalShort = 100;

次に、setup()の最後で、出力(OUTPUT)として振舞うために、LEDピンを設定する必要があります。そして、以下の命令を追加して全てのLEDをオフにします。

1
2
3
4
5
6
7
8
9
// set the LEDs pins as outputs
  pinMode(LEDR, OUTPUT);
  pinMode(LEDG, OUTPUT);
  pinMode(LEDB, OUTPUT);

  // turn all the LEDs off
  digitalWrite(LEDR, HIGH);
  digitalWrite(LEDG, HIGH);
  digitalWrite(LEDB, HIGH);

loop()では、currentMillisという、スケッチが動作している時間を格納する、新しい変数を初期化します。if()文では、ジェスチャーセンサーが利用可能かを確認し、利用可能であれば、ジェスチャー検出を読み取ります。

1
2
3
4
5
6
7
8
9
unsigned long currentMillis = millis();

  // check if a proximity reading is available
  if (APDS.proximityAvailable()) {
    // read the proximity
    // - 0   => close
    // - 255 => far
    // - -1  => error
    int proximity = APDS.readProximity();

次にすることは、物体が遠いかどうかを判定するif文です。遠ければ、intervalLongを点滅時間を設定し、緑のLEDをゆっくり点滅させます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
if (proximity > 150) {
      if (currentMillis - previousMillis >= intervalLong) {
        previousMillis = currentMillis;

        // if the LED is off turn it on and vice-versa:
        if (ledState == LOW) {
          ledState = HIGH;
        } else {
          ledState = LOW;
        }

        // set the green LED with the ledState of the variable and turn off the rest
        digitalWrite(LEDG, ledState);
        digitalWrite(LEDR, HIGH);
        digitalWrite(LEDB, HIGH);
      }
    }

次に、else if文を使い、物体がボードから中距離にあるか調べるために同じことを行います。このときは、intervalMedにより、青いLEDが先ほどよりも早く点滅します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
else if(proximity > 50 && proximity <= 150){
    if (currentMillis - previousMillis >= intervalMed) {
      previousMillis = currentMillis;

      // if the LED is off turn it on and vice-versa:
      if (ledState == LOW) {
        ledState = HIGH;
        } else {
          ledState = LOW;
        }

        // set the blue LED with the ledState of the variable and turn off the rest
        digitalWrite(LEDB, ledState);
        digitalWrite(LEDR, HIGH);
        digitalWrite(LEDG, HIGH);
      }
    }

最後に、elseを使い物体がボードにとても近いかを判定します。このときは、intervalShortにより赤色LEDを点滅させます。最後に、Serial.println()関数を使い、距離をリリアルモニターに表示します。delay()関数を削除するのを忘れないでください。これを使うと、データの欠損が発生します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
else {
    if (currentMillis - previousMillis >= intervalShort) {
      previousMillis = currentMillis;

      // if the LED is off turn it on and vice-versa:
      if (ledState == LOW) {
        ledState = HIGH;
      } else {
        ledState = LOW;
      }

      // set the blue LED with the ledState of the variable and turn off the rest
      digitalWrite(LEDR, ledState);
      digitalWrite(LEDB, HIGH);
      digitalWrite(LEDG, HIGH);
      }
    }

    // print value to the Serial Monitor
    Serial.println(proximity);
  }
}

これでコードは完成です。

  1. 完全なコード

コード作成セクションをスキップした場合のために、完全なコードを以下に示します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include <Arduino_APDS9960.h>

int ledState = LOW;

unsigned long previousMillis = 0;

const long intervalLong = 1000;
const long intervalMed = 500;
const long intervalShort = 100;

void setup() {
  Serial.begin(9600);
  while (!Serial);

  if (!APDS.begin()) {
    Serial.println("Error initializing APDS9960 sensor!");
  }

  // set the LEDs pins as outputs
  pinMode(LEDR, OUTPUT);
  pinMode(LEDG, OUTPUT);
  pinMode(LEDB, OUTPUT);

  // turn all the LEDs off
  digitalWrite(LEDR, HIGH);
  digitalWrite(LEDG, HIGH);
  digitalWrite(LEDB, HIGH);
}

void loop() {
  unsigned long currentMillis = millis();

  // check if a proximity reading is available
  if (APDS.proximityAvailable()) {
    // read the proximity
    // - 0   => close
    // - 255 => far
    // - -1  => error
    int proximity = APDS.readProximity();

    if (proximity > 150) {
      if (currentMillis - previousMillis >= intervalLong) {
        previousMillis = currentMillis;

        // if the LED is off turn it on and vice-versa:
        if (ledState == LOW) {
          ledState = HIGH;
        } else {
          ledState = LOW;
        }

        // set the green LED with the ledState of the variable and turn off the rest
        digitalWrite(LEDG, ledState);
        digitalWrite(LEDR, HIGH);
        digitalWrite(LEDB, HIGH);
      }
    }

    else if(proximity > 50 && proximity <= 150){
      if (currentMillis - previousMillis >= intervalMed) {
        previousMillis = currentMillis;

        // if the LED is off turn it on and vice-versa:
        if (ledState == LOW) {
          ledState = HIGH;
        } else {
          ledState = LOW;
        }

        // set the blue LED with the ledState of the variable and turn off the rest
        digitalWrite(LEDB, ledState);
        digitalWrite(LEDR, HIGH);
        digitalWrite(LEDG, HIGH);
      }
    }

    else {
      if (currentMillis - previousMillis >= intervalShort) {
        previousMillis = currentMillis;

        // if the LED is off turn it on and vice-versa:
        if (ledState == LOW) {
          ledState = HIGH;
        } else {
          ledState = LOW;
        }

        // set the blue LED with the ledState of the variable and turn off the rest
        digitalWrite(LEDR, ledState);
        digitalWrite(LEDB, HIGH);
        digitalWrite(LEDG, HIGH);
      }
    }

    // print value to the Serial Monitor
    Serial.println(proximity);
  }
}

テスト

スケッチの検証とボードへのアップロードが成功したら、左側のメニューからシリアルモニタを開きます。

コードをテストするために、立った位置であなたの前(USBポートが下にある状態)で安定させ、ボードの近くで物体を上下に動かします。シリアルモニターの値が変化し、RGB LEDの色と点滅時間が変わることがわかります。

X軸とY軸の作用

X軸とY軸の作用

シリアルモニタに、これらの値を表示するするスケッチのスクリーンショットを示します。

シリアルモニターに表示されたセンサーデータ

シリアルモニターに表示されたセンサーデータ

トラブルシュート

エラーが起きることもあります。コードが動作しないときはいくつかの共通の問題があり、解決できます。

  • 括弧やセミコロンが抜けている。
  • Arduinoボードが、間違ったポートに接続されている。
  • ケーブル接続の予期しない切断。

おわりに

このチュートリアルで、APDS9960センサーとは何か、Arduino Nano 33 BLE Senseボード内蔵APDS9960センサーの使い方を学びました。さらに、様々な色や時間パターンで、近接検出モニターを作成する方法を紹介しました。

オリジナルのページ

https://docs.arduino.cc/tutorials/nano-33-ble-sense/proximity-sensor

最終更新日

March 6, 2023

inserted by FC2 system