Arduinoタッチスイッチの使い方、M5Stack AtomS3 Lite使用

タッチスイッチの使い方 Arduinoコマンド

「AtomS3 Lite」に標準で搭載されているタッチスイッチ機能について使い方から感度の調整方法まで、サンプルプログラムを使用して詳しく紹介します。


「AtomS3 Lite」の使い方、端子配列については以下のリンクで詳しく紹介しています。

AtomS3 Liteの使い方、端子配列、初期設定をサンプルプログラムで詳しく紹介
Atom Liteの高機能版AtomS3 Liteの使い方を,端子配列,開発環境別の初期設定,Atom Liteとの違い等をサンプルプログラムで詳しく紹介します。
スポンサーリンク

1.タッチスイッチとは

タッチスイッチとは触れた時にONし、離した時にOFFさせることができるスイッチです。
物理的なスイッチやセンサを接続しなくても、リード線等の電極を付けておいて、それに触れるだけでON/OFF検知ができるようになります。

タッチセンサー機能のある端子には、コンデンサへの充放電サイクル数をカウントするためのカウンターがあり、設定された期間ごとに充放電の回数をカウントしています。

タッチセンサーの端子に接続したリード線やパッドに触れると、その端子の等価静電容量(コンデンサ容量)が変化するため、充放電サイクルのカウント数が変化します。

このサイクル数を定期的に取得して、サイクル数の変化が設定した「しきい値(変化量)」以上に増減したことを検知することで、タッチスイッチのON/OFFを検知することができます。

充放電サイクルのデータ取得期間内に「しきい値」以上の変化があった時にタッチスイッチがON/OFFを検知するため、スイッチ部にゆっくり触れていくと反応しないこともあります。
この場合はデータの取得期間と「しきい値」を小さくする等して感度を上げますが、誤動作もしやすくなるため、バランスを見ながら調整する作業が必要となります。
スポンサーリンク

2.使用可能な端子

「AtomS3 Lite」でタッチスイッチ機能が使える端子は下画像の「Touch」が記載されている端子で、ほとんどの端子で使用可能です。

AtomS3-Liteの使い方、端子配列
スポンサーリンク

3.タッチスイッチ制御コマンドの使い方

タッチスイッチを制御するための「Arduinoコマンド」の使い方について詳しく紹介します。

・touchRead

各端子のタッチセンサーのデータを取得できます。

タッチセンサーには、コンデンサへの充放電回数をカウントするためのカウンターがあり、タッチセンサーの端子に接続したリード線等に触れた時に変化する充放電回数の変化でスイッチのON/OFFを検知しています。

以下のように、指定した端子の充放電回数を取得することができます。

// 使用例
touchRead(5);
touchRead(端子番号);
端子番号:取得データ(充放電回数)を確認したい端子番号を数値で指定
touchRead」で指定した「端子番号」の充放電回数が確認できるため、動作確認や感度調整をする時に使用できます。

・touchSetCycles

充放電回数の測定周期を設定する機能です。

touchRead()」関数で取得される値はここでの設定に依存します。
感度調整について「しきい値」だけでは不十分な時にこの測定周期で調整します。
初期値の充放電回数の測定時間は0.512ms(0x1000/8M)に設定されています。

// 使用例
touchSetCycles(500, 500);
touchSetCycles ( 測定時間, 休止時間 );

測定時間:充放電回数を測定する時間(設定値x0.1ms)を設定
休止時間:次の測定を開始するまでの待ち時間(設定値x0.1ms)を設定

設定内容は全ての端子で共通で使用されます。
各時間の設定値は整数で指定できますが0.1ms単位の設定となります。(500で0.5ms)
最大値は以下の式で求めらているようです。
 0xffff(65535) / 8M = 8.19(ms)
※AtomS3ではこれ以上の数値も設定できたのでデバイスによるようですが、感度的に実用的ではないので、基本は初期値でいいように思います。
両方初期値は「0x1000(4096)」のため8Mだと「0.512ms」と思います。
合計時間が長すぎると、タッチの応答が遅くなり、測定時間が短すぎると十分なサンプリングが行われず、測定が不正確になるようです。

・touchAttachInterrupt(初期設定)

この関数でタッチスイッチの初期設定を行います。(「setup()」に記入)
設定した「端子番号」の充放電回数の取得データが「しきい値」を超えた時に設定した「割り込み関数」を呼び出します。

// 使用例
// タッチ割り込み処理関数
void gotTouch() {
  touchdetected = true;  // タッチ割り込みフラグON
}
// タッチイベント設定(初期設定)
void setup() {
  touchAttachInterrupt(5, gotTouch, 1000);
}
touchAttachInterrupt ( 端子番号, 関数名, しきい値 );

端子番号:対象の端子番号を数値で指定
関数名:タッチスイッチのON/OFFを検知した時に実行される関数を指定
しきい値:タッチスイッチの感度(充放電回数の変化量)を設定

しきい値」の設定は、タッチスイッチに「触れている時」と「触れていない時」の充放電回数を「touchRead()」関数で取得して、シリアルモニタ等で確認しながら設定します。
タッチセンサーの値(充放電回数)が ESP32-S2/S3 で指定されたしきい値を上回った場合(ESP32 では下回った場合)に呼び出されます。

・touchAttachInterruptArg

上で紹介した「touchAttachInterrupt()」関数で呼び出す関数に「引数」を渡したい時に使用します。

touchAttachInterruptArg ( 端子番号 , 関数名 , 引数 , しきい値 );
引数」以外の設定内容は「touchAttachInterrupt()」関数と同じです。

・touchInterruptGetLastStatus(ESP32S2,S3のみ)

この関数は、タッチスイッチに触れ続けている場合は「true」を返し、それ以外の場合は「false」を返します。

// 使用例
if (touchInterruptGetLastStatus(5) {  // 端子5に触れていれば
  // ここに触れている時の処理を書く
} else {                              // 端子5に触れていいなければ
  // ここに触れていない時の処理を書く
}
touchInterruptGetLastStatus ( 端子番号 );

端子番号:対象の端子番号を数値で指定

この関数だけで実際のボタンスイッチのON/OFF検知のように使用できます。
動作した瞬間にのみ処理させたい場合は「touchAttachInterrupt()」関数の割り込み処理と組み合わせて使用します。

・その他

touchDetachInterrupt

この関数は、タッチスイッチから割り込みを切り離す(タッチスイッチを無効)ために使用されます。

// 使用例
touchDetachInterrupt(5);
touchDetachInterrupt( 端子番号 );

touchSleepWakeUpEnable

この関数は、ディープ スリープからのウェイク アップ ソースとしてタッチスイッチを設定するために使用されます。

// 使用例
touchSleepWakeUpEnable(5, 3000);
touchSleepWakeUpEnable ( 端子番号 , しきい値 );
ESP32-S2 および ESP32-S3 は、1 つのスリープ ウェイクアップ のみをサポートします。

4.サンプルプログラム(コピペ)

サンプルプログラムは以下になります。「コピペ」して書き込んでください。
※下コード(黒枠)内の右上角にある小さなアイコンのクリックでコピーできます。

#include <M5AtomS3.h> // ヘッダーファイル準備(別途FastLEDライブラリをインストール)

#define TOUCH_PIN1 5  // タッチ端子番号1
#define TOUCH_PIN2 6  // タッチ端子番号2

// FastLEDライブラリでフルカラーLEDを使用するための設定
CRGB dispColor(uint8_t r, uint8_t g, uint8_t b) {
  return (CRGB)((r << 8) | (g << 16) | b);
}
// 変数宣言
int threshold1 = 3000;        // しきい値1(感度)充放電回数の変化(小さいと感度が良い)
int threshold2 = 1000;        // しきい値2(感度)充放電回数の変化(小さいと感度が良い)
bool touch1detected = false;  // タッチ割り込み発生フラグ1
bool touch2detected = false;  // タッチ割り込み発生フラグ2
bool toggle = false;          // タッチ状態格納用
int cnt = 0;                  // シリアル出力タイミングカウント用

// 割り込み処理 ----------------------------------------------
// タッチ割り込み処理1
void gotTouch1() {
  touch1detected = true;  // タッチ割り込みフラグ1 ON
}
// タッチ割り込み処理2
void gotTouch2() {
  touch2detected = true;  // タッチ割り込みフラグ2 ON
}

  // 初期設定 -------------------------------------------------
void setup() {
  auto cfg = M5.config(); // 本体初期設定
  AtomS3.begin(cfg, true);

  Serial.begin(9600); // USBシリアル通信初期化
  delay(1000);        // シリアル出力開始待ち
  Serial.println("AtimS3 Lite TEST"); // シリアル通信出力

  // タッチスイッチ設定(ピン番号, タッチ割り込み発生時実行関数, しきい値)
  touchAttachInterrupt(TOUCH_PIN1, gotTouch1, threshold1); // タッチ1設定
  touchAttachInterrupt(TOUCH_PIN2, gotTouch2, threshold2); // タッチ2設定

  AtomS3.dis.drawpix(dispColor(40, 40, 40));  // 本体LED色指定
}

// メイン ---------------------------------------------------
void loop() {
  // タッチスイッチ処理1(モーメンタリ:触れた時と離した時に処理を実行)
  if (touch1detected) {                             // タッチ割り込みフラグ1がONなら
    touch1detected = false;                         // タッチ割り込みフラグ1をOFFする
    Serial.printf("Value1: %d - ", touchRead(TOUCH_PIN1)); // タッチ1の値シリアル出力
    if (touchInterruptGetLastStatus(TOUCH_PIN1)) {  // タッチ1に触れていれば
      AtomS3.dis.drawpix(dispColor(50, 0, 0));          // 本体LED色指定
      Serial.println("Touch1 Touched!");         // タッチ状態シリアル出力
    } else {                                        // タッチ1に触れていなければ
      AtomS3.dis.drawpix(dispColor(40, 40, 40));        // 本体LED色指定
      Serial.println("Touch1 Released!");        // タッチ状態シリアル出力
    }
  }
  // タッチスイッチ1に触れている間ずっと実行したい場合有効にする
  // if (touchInterruptGetLastStatus(TOUCH_PIN1)) {
  //   AtomS3.dis.drawpix(dispColor(0, 50, 0));  // 本体LED色指定
  // }

  // タッチスイッチ処理2(オルタネイト:ONするごとに処理を切り替え)
  if (touch2detected) {                                               // タッチ割り込みフラグ2がONなら
    touch2detected = false;                                           // タッチ割り込みフラグ2をOFFする
    Serial.printf("Value2: %d - ", touchRead(TOUCH_PIN2));         // タッチ2の値シリアル出力
    if (touchInterruptGetLastStatus(TOUCH_PIN2) && toggle == false) { // タッチスイッチに触れていて、toggleがfalseなら
      AtomS3.dis.drawpix(dispColor(0, 0, 50));                            // 本体LED色指定
      Serial.println("Touch2 Touched!(false)");                    // タッチ状態シリアル出力
    }
    if (touchInterruptGetLastStatus(TOUCH_PIN2) && toggle == true) {  // タッチスイッチに触れていて、toggleがtrueなら
      AtomS3.dis.drawpix(dispColor(40, 40, 40));                          // 本体LED色指定
      Serial.println("Touch2 Touched!(true)");                     // タッチ状態シリアル出力
    }
    if (!touchInterruptGetLastStatus(TOUCH_PIN2)) {   // タッチスイッチに触れていなければ
      toggle = !toggle;                               // タッチ2状態反転
      Serial.println("Touch2 Released!");          // タッチ状態シリアル出力
    }
  }
  // タッチボタン1状態シリアル出力
  if (cnt == 40) { // シリアル出力タイミングカウントが40なら
    cnt = 0;       // カウント値初期化
    Serial.printf("Value1: %d, State1: %d\n", touchRead(TOUCH_PIN1), touchInterruptGetLastStatus(TOUCH_PIN1));  // シリアル出力
  }

  cnt++;          // シリアル出力タイミングカウント+1
  AtomS3.dis.show();  // 本体フルカラーLED出力
  delay(50);      // 遅延時間
}

5.動作確認

以下のようにサンプルプログラムの動作確認を行いました。

「AtomS3 Lite」が接続できるようにブレッドボードに4Pと5Pのピンヘッダーを差しておきます。
「AtomS3 Lite」の端子G5のところにリード線を差し、ワニ口付配線で延長します。
端子G6のところには適当な長さのリード端子を差しておきます。

タッチスイッチの使い方 AtomS3 Lite

「AtomS3 Lite」を接続したものが下画像になります。
ワニ口付配線がタッチスイッチ1用、リード端子がタッチスイッチ2用になります。

タッチスイッチの使い方 AtomS3 Lite

タッチスイッチ1(モーメンタリ動作)

ワニ口付配線のどこでも良いので握ると「AtomS3 Lite」本体のLEDが赤に点灯し、離すと白色に戻ります。

タッチスイッチの使い方 AtomS3 Lite
今回は指1本で触れた程度では動作しないように「しきい値」を調整しました。
感度については使用する配線によって変わるので、それぞれの環境に合わせて調整してみてください。

タッチスイッチ2(オルタネイト動作)

リード端子に触れるごとに、本体LEDの点灯色が青と白で切り替わります。

タッチスイッチの使い方 AtomS3 Lite

リード端子に触れるとLEDが青色に点灯

タッチスイッチの使い方 AtomS3 Lite

離してもそのまま青色点灯

タッチスイッチの使い方 AtomS3 Lite

もう一度触れるとLEDが白色に点灯

感度については使用するリード端子によって変わるので、それぞれの環境に合わせて「しきい値」を調整してみてください。

ブレッドボードは1列の穴数が6個あるサンハヤトの「SAD-101」がおすすめです。
安価なものはありますが、ほとんどが1列の穴数が5個で自由度がなく、ボードが歪んでいたり、抜き差しが硬かったり緩かったりするものが多いように思います。

6.サンプルプログラムの詳細

タッチスイッチ1の処理を抜粋して紹介します。
タッチスイッチ1の処理は「モーメンタリ」動作で、触れた時と離した時に実行させたい処理に使用します。

// タッチスイッチ処理1(モーメンタリ:触れた時と離した時に処理を実行)
if (touch1detected) {                             // タッチ割り込みフラグ1がONなら
  touch1detected = false;                         // タッチ割り込みフラグ1をOFFする
  if (touchInterruptGetLastStatus(TOUCH_PIN1)) {  // タッチ1に触れていれば
    // ここに触れた時に実行したい処理を書く・・・
  } else {                                        // タッチ1に触れていなければ
    // ここに離した時に実行したい処理を書く・・・
  }
}
// タッチスイッチ1に触れている間ずっと実行したい場合有効にする
// if (touchInterruptGetLastStatus(TOUCH_PIN1)) {
//   // ここに触れている間ずっと実行したい処理を書く・・・
// }

「AtomS3」では「touchInterruptGetLastStatus()」関数を使用することでタッチスイッチの状態(触れている:true/触れていない:false)を確認することができます。

タッチスイッチがON/OFF(タッチ割り込み発生)した時に、タッチスイッチの状態を確認して、実行する処理を分岐させます。

この処理はタッチスイッチがON(タッチ割り込み発生)した時にのみ処理を実行しますが、押している間ずっと実行したい場合は上コードの 11〜13行目を有効にします。

タッチスイッチ2の処理を抜粋して紹介します。
タッチスイッチ2の処理は「オルタネイト」動作で、スイッチに触れるごとに実行する処理を切り替えたい時に使用します。

// タッチスイッチ処理2(オルタネイト:ONするごとに処理を切り替え)
if (touch2detected) {                                               // タッチ割り込みフラグ2がONなら
  touch2detected = false;                                           // タッチ割り込みフラグ2をOFFする
  if (touchInterruptGetLastStatus(TOUCH_PIN2) && toggle == false) { // タッチスイッチに触れていて、toggleがfalseなら
    // ここにONした時に実行したい処理を書く・・・
  }
  if (touchInterruptGetLastStatus(TOUCH_PIN2) && toggle == true) {  // タッチスイッチに触れていて、toggleがtrueなら
    // ここにもう一度ONした時に実行したい処理を書く・・・
  }
  if (!touchInterruptGetLastStatus(TOUCH_PIN2)) {   // タッチスイッチに触れていなければ
    toggle = !toggle;                               // タッチ2状態反転
  }
}

タッチスイッチのOFFを検知するごとに変数「toggle」のtrueとfalseを切り替えて、ON/OFF(タッチ割り込み発生)した時には「toggle」の状態を確認して、実行する処理を分岐させます。

7.まとめ

「AtomS3 Lite」を使用したタッチスイッチ機能の使い方について詳しく紹介しました。

前から気にはなっていましたが、動作精度に不安があったのでおまけ程度についてるのかな?と思って使わずに来ましたが「AtomS3」のほとんどの端子で使えるようになったこともあって今回使ってみました。

使ってみると意外と使えて、感度調整も簡単にできました。
信頼性が必要な場合にはメカスイッチが必要ですが、メカスイッチは配線をしたり、配置したりするのが意外と大変だったりするので、ちょっとしたスイッチには便利に使えます。

用途に合わせて使い分けていきましょう。使ったことがない方は是非一度使ってみてください。

6.サンプルプログラムの詳細

コメント

タイトルとURLをコピーしました