MPR121

概要

このレッスンでは、MPR121の使用方法を学びます。プロジェクトに多くのタッチスイッチを追加したい場合に適しています。MPR121の電極は導体で延長できます。ワイヤーをバナナに接続すれば、バナナをタッチスイッチに変えることができ、フルーツピアノのようなプロジェクトを実現できます。

必要なコンポーネント

このプロジェクトには、以下のコンポーネントが必要です。

全セットを購入するのが便利です。こちらがリンクです:

名称

このキットのアイテム数

リンク

Elite Explorer Kit

300+

Elite Explorer Kit

以下のリンクから個別に購入することもできます。

コンポーネント紹介

購入リンク

Arduino Uno R4 WiFi

-

ブレッドボード

BUY

ジャンパーワイヤー

BUY

MPR121

-

配線図

この例では、MPR121をブレッドボードに挿入します。MPR121のGNDをGNDに、3.3Vを3V3に、IRQをデジタルピン2に、SCLをピンSCL(A5)に、SDAをピンSDA(A4)に接続します。タッチセンシング用の12個の電極があります。

注釈

MPR121は3.3Vで動作します。5Vではありません。

../_images/23-mpr121_bb.png

回路図

../_images/23_mpr121_schematic.png

コード

注釈

  • ファイル 23-mpr121.inoelite-explorer-kit-main\basic_project\23-mpr121 のパスで直接開くことができます。

  • ここでは Adafruit MPR121 ライブラリを使用しています。 Library Manager からインストールできます。

    ../_images/22_mpr121_lib.png

UNOボードにコードをアップロードした後、MPR121のピン「1」と「0」のタッチ状態が12ビットのブール配列に記録されます。この配列はシリアルモニターに表示されます。

コード解析

このコードは、MPR121タッチセンサーの通信と操作を容易にします。タッチ電極の状態を検出し、タッチされたり解放されたりした電極に関する情報をシリアルインターフェースに出力することができます。詳細なセンサーデータが必要な場合は、関連するコードのコメントを外すことができます。

コードの分析は以下の通りです:

  1. ライブラリのインポート:

    #include <Wire.h>
    #include "Adafruit_MPR121.h"
    
    • Wire.h:I2C通信用。

    • Adafruit_MPR121.h:AdafruitのMPR121ライブラリで、MPR121タッチセンサーの操作に使用します。

  2. _BV マクロの定義:

    #ifndef _BV
    #define _BV(bit) (1 << (bit))
    #endif
    

    _BV(bit) は、指定されたビットを対応するバイナリ値に変換するマクロを定義します。これは1 << bitに似ています。

  3. Adafruit_MPR121 クラスインスタンスの初期化:

    Adafruit_MPR121 cap = Adafruit_MPR121();
    

    Adafruit_MPR121 クラスのインスタンスを cap として作成します。 cap オブジェクトは、MPR121タッチセンサーとの通信および操作に使用されます。

  4. setup() 関数:

    9600ボーレートでシリアル通信を初期化し、デフォルトのI2Cアドレス0x5AでMPR121タッチセンサーを初期化します。初期化に失敗した場合は、エラーメッセージを出力し、無限ループに入ります。

    void setup() {
        Serial.begin(9600);
    
        while (!Serial) { // needed to keep leonardo/micro from starting too fast!
            delay(10);
        }
    
        Serial.println("Adafruit MPR121 Capacitive Touch sensor test");
    
        // Default address is 0x5A, if tied to 3.3V its 0x5B
        // If tied to SDA its 0x5C and if SCL then 0x5D
        if (!cap.begin(0x5A)) {
            Serial.println("MPR121 not found, check wiring?");
            while (1);
        }
        Serial.println("MPR121 found!");
    }
    
  5. loop() 関数:

    • 現在のタッチ状態を取得し、16ビットの整数として返します。

      currtouched = cap.touched();
      
    • 12個の電極(0から11までの番号)の状態を反復処理します。

      for (uint8_t i=0; i<12; i++) {
         // it if *is* touched and *wasnt* touched before, alert!
          if ((currtouched & _BV(i)) && !(lasttouched & _BV(i)) ) {
              Serial.print(i); Serial.println(" touched");
          }
          // if it *was* touched and now *isnt*, alert!
          if (!(currtouched & _BV(i)) && (lasttouched & _BV(i)) ) {
              Serial.print(i); Serial.println(" released");
          }
      }
      
      • もし電極がタッチされ、以前にタッチされていなかった場合、「x touched」と出力します。ここで、xは電極の番号です。

      • もし電極が以前タッチされていたが、現在タッチされていない場合、「x released」と出力します。

    • lasttouched を更新し、次の反復で比較するための現在のタッチ状態を格納します。

      lasttouched = currtouched;
      
    • デバッグ情報(オプションのセクション):

      // debugging info, what
      Serial.print("\t\t\t\t\t\t\t\t\t\t\t\t\t 0x"); Serial.println(cap.touched(), HEX);
      Serial.print("Filt: ");
      for (uint8_t i=0; i<12; i++) {
          Serial.print(cap.filteredData(i)); Serial.print("\t");
      }
      Serial.println();
      Serial.print("Base: ");
      for (uint8_t i=0; i<12; i++) {
          Serial.print(cap.baselineData(i)); Serial.print("\t");
      }
      Serial.println();
      
      // put a delay so it isn't overwhelming
      delay(100);