「AtomS3 Lite」に標準で搭載されているタッチスイッチ機能について使い方から感度の調整方法まで、サンプルプログラムを使用して詳しく紹介します。
「AtomS3 Lite」の使い方、端子配列については以下のリンクで詳しく紹介しています。
1.タッチスイッチとは
2.使用可能な端子
3.タッチスイッチ制御コマンドの使い方
・touchRead
・touchSetCycles
・touchAttachInterrupt(初期設定)
・touchAttachInterruptArg
・touchInterruptGetLastStatus(ESP32S2,S3のみ)
・その他
4.サンプルプログラム(コピペ)
5.動作確認
6.サンプルプログラムの詳細
7.まとめ
1.タッチスイッチとは
タッチスイッチとは触れた時にONし、離した時にOFFさせることができるスイッチです。
物理的なスイッチやセンサを接続しなくても、リード線等の電極を付けておいて、それに触れるだけでON/OFF検知ができるようになります。
タッチセンサー機能のある端子には、コンデンサへの充放電サイクル数をカウントするためのカウンターがあり、設定された期間ごとに充放電の回数をカウントしています。
タッチセンサーの端子に接続したリード線やパッドに触れると、その端子の等価静電容量(コンデンサ容量)が変化するため、充放電サイクルのカウント数が変化します。
このサイクル数を定期的に取得して、サイクル数の変化が設定した「しきい値(変化量)」以上に増減したことを検知することで、タッチスイッチのON/OFFを検知することができます。
2.使用可能な端子
「AtomS3 Lite」でタッチスイッチ機能が使える端子は下画像の「Touch」が記載されている端子で、ほとんどの端子で使用可能です。
3.タッチスイッチ制御コマンドの使い方
タッチスイッチを制御するための「Arduinoコマンド」の使い方について詳しく紹介します。
・touchRead
各端子のタッチセンサーのデータを取得できます。
タッチセンサーには、コンデンサへの充放電回数をカウントするためのカウンターがあり、タッチセンサーの端子に接続したリード線等に触れた時に変化する充放電回数の変化でスイッチのON/OFFを検知しています。
以下のように、指定した端子の充放電回数を取得することができます。
// 使用例
touchRead(5);
・touchSetCycles
充放電回数の測定周期を設定する機能です。
「touchRead()」関数で取得される値はここでの設定に依存します。
感度調整について「しきい値」だけでは不十分な時にこの測定周期で調整します。
初期値の充放電回数の測定時間は0.512ms(0x1000/8M)に設定されています。
// 使用例
touchSetCycles(500, 500);
・測定時間:充放電回数を測定する時間(設定値x0.1ms)を設定
・休止時間:次の測定を開始するまでの待ち時間(設定値x0.1ms)を設定
・touchAttachInterrupt(初期設定)
この関数でタッチスイッチの初期設定を行います。(「setup()」に記入)
設定した「端子番号」の充放電回数の取得データが「しきい値」を超えた時に設定した「割り込み関数」を呼び出します。
// 使用例
// タッチ割り込み処理関数
void gotTouch() {
touchdetected = true; // タッチ割り込みフラグON
}
// タッチイベント設定(初期設定)
void setup() {
touchAttachInterrupt(5, gotTouch, 1000);
}
・端子番号:対象の端子番号を数値で指定
・関数名:タッチスイッチのON/OFFを検知した時に実行される関数を指定
・しきい値:タッチスイッチの感度(充放電回数の変化量)を設定
・touchAttachInterruptArg
上で紹介した「touchAttachInterrupt()」関数で呼び出す関数に「引数」を渡したい時に使用します。
・touchInterruptGetLastStatus(ESP32S2,S3のみ)
この関数は、タッチスイッチに触れ続けている場合は「true」を返し、それ以外の場合は「false」を返します。
// 使用例
if (touchInterruptGetLastStatus(5) { // 端子5に触れていれば
// ここに触れている時の処理を書く
} else { // 端子5に触れていいなければ
// ここに触れていない時の処理を書く
}
・端子番号:対象の端子番号を数値で指定
・その他
touchDetachInterrupt
この関数は、タッチスイッチから割り込みを切り離す(タッチスイッチを無効)ために使用されます。
// 使用例
touchDetachInterrupt(5);
touchSleepWakeUpEnable
この関数は、ディープ スリープからのウェイク アップ ソースとしてタッチスイッチを設定するために使用されます。
// 使用例
touchSleepWakeUpEnable(5, 3000);
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」を接続したものが下画像になります。
ワニ口付配線がタッチスイッチ1用、リード端子がタッチスイッチ2用になります。
タッチスイッチ1(モーメンタリ動作)
ワニ口付配線のどこでも良いので握ると「AtomS3 Lite」本体のLEDが赤に点灯し、離すと白色に戻ります。
タッチスイッチ2(オルタネイト動作)
リード端子に触れるごとに、本体LEDの点灯色が青と白で切り替わります。
リード端子に触れるとLEDが青色に点灯
離してもそのまま青色点灯
もう一度触れると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(タッチ割り込み発生)した時に、タッチスイッチの状態を確認して、実行する処理を分岐させます。
タッチスイッチ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」のほとんどの端子で使えるようになったこともあって今回使ってみました。
使ってみると意外と使えて、感度調整も簡単にできました。
信頼性が必要な場合にはメカスイッチが必要ですが、メカスイッチは配線をしたり、配置したりするのが意外と大変だったりするので、ちょっとしたスイッチには便利に使えます。
用途に合わせて使い分けていきましょう。使ったことがない方は是非一度使ってみてください。
コメント