前回記事でESP32(ESP32-DevKitC)の導入と無線通信(WiFi、Bluetooth)について書きました。
 今回はタッチセンサー機能について試してみました

タッチセンサー

 ESP32にはタッチセンサーが内臓されています。 ですので、外付けのモジュール無しでタッチセンサーの機能が使えます。
 このリンク先のボードマップにタッチセンサーのピン配置が記載されています。 全部で10チャンネルでセンシングが可能です。
 タッチセンサーの電極を指等で触れると、電極と指等の間に静電容量が発生します。この静電容量を測定することでタッチを検出します。

センサー入力値の取得

 まずセンサー入力値の取得を試してみました。
 非常に簡単でESP32開発環境が整ったArduino IDEインストール済みPCとESP32-DevKitC、USBケーブル(マイクロUSB)、あったらメス-オスのジャンパーワイヤーで、5分もあればできます。

配線

 タッチセンサーが設定されているピン(サンプルスケッチをそのまま使う場合はTOUCH0(GPIO4) )にメス-オスのジャンパーワイヤーを接続するだけです。
 ジャンパーワイヤーが無ければ何もつながなくてもできます。

スケッチ

 ESP32の開発環境が整ったArduino IDEを使います。開発環境の構築はこちらで書きました。

 サンプルスケッチを開きます。
 『ファイル』⇒『スケッチ例』⇒『ESP32』⇒『Touch』⇒『TouchRead』

 サンプルスケッチは改変せずそのまま使います(使用したいピンを変える場合は13行目”T0”をT0~T9の範囲で変えます)。

 13行目”touchRead(T0)”がセンサー値を出力するコマンドになります。”T0”が使用するピンの番号でT0~T9まで使えます。

実行

 PCとESP32-DevKitCを接続し、シリアルモニターを起動しておき、 をクリックして書き込みます。

 シリアルモニタに1秒毎に数値が出力されます。
 ジャンパーワイヤーの先を指で触ると出力される数値が小さくなります。
 ジャンパーワイヤーが無くても、ピンを指で触ったり、導電性の物を介して触れると数値が変わります。

広告

閾値を設定してタッチを検出

 タッチしているかどうかの判断はセンサーが検出した数値で判断します。ある値(閾値)をプログラムで設定してそれ以下であればタッチと判断します。
 しかし環境などによってセンサーの基準値がぶれますので、実際に試してみて閾値を決める必要があります。

配線

 TOUCH2(GPIO2)とTOUCH3(GPIO15)にメス-オスのジャンパーワイヤーをつなぎます。
 ジャンパーワイヤーがなければつながなくてもできます。

スケッチ

 サンプルスケッチを開きます。
 『ファイル』⇒『スケッチ例』⇒『ESP32』⇒『Touch』⇒『TouchIntrrerupt』

  サンプルスケッチ6行目

int threshold = 40;

 の”40″が閾値になります。”センサー入力値の取得”で触っていないときと触ったときの数値を読んで、閾値を決めて値を変えます。

 22、23行目

  touchAttachInterrupt(T2, gotTouch1, threshold);
  touchAttachInterrupt(T3, gotTouch2, threshold);

 がセンサー値を判断して割り込みを発生させるコマンドになります。
 loop()関数の実行中に、一つ目の引値(T2,T3)で設定したピンの信号値が三番目の引数(threshold)の閾値を下回ると二つ目の関数(gotTouch1,gotTouch2)を割り込みで実行します。

実行

 PCとESP32-DevKitCを接続し、シリアルモニターを起動しておき、 をクリックして書き込みます。
 閾値は40のままで試してみました。

 ジャンパーワイヤーの先端を指で触ると”Touch 1 detected”, ”Touch 2 detected”とシリアルモニタに出力されました。

広告

簡単タッチパネルを作ってみる

 タッチセンサー機能を使って3×3の簡単なタッチパネルを作ってみました。タッチディスプレイにするには透明電極を使いますがITOなど扱えないのでアルミテープで電極を作りました。

簡易タッチパネルの作成

 使わなくなった古いスマートフォンにアルミテープを幅3mm程で短冊切りしたものを等間隔に張っていきました。
 端部はワニ口で挟みやすいように折っておきました。

 最初に張ったアルミテープに直交させるように短冊切りしたセロハンテープを張って絶縁とし、その上にアルミテープを3枚貼りました。

配線

 T0(GPIO4),T2(GPIO2),T3(GPIO15),T4(GPIO13),T5(GPIO12),T6(GPIO14)にメス-オスのジャンパーワイヤーを刺し、ジャンパーワイヤーの先にワニ口クリップをつけ、ワニ口クリップを作成した簡易タッチパネルのアルミテープ電極につなぎます。

スケッチ

  ”TouchRead”のスケッチを改造して縦のテープと横のテープの双方が検出されるとシリアルモニタに数値を出力するようにしました。

int threshold = 15; // 閾値
bool touch1detected = false;
bool touch2detected = false;
bool touch3detected = false;
bool touch4detected = false;
bool touch5detected = false;
bool touch6detected = false;

void gotTouch1(){
 touch1detected = true;
}
void gotTouch2(){
 touch2detected = true;
}
void gotTouch3(){
 touch3detected = true;
}
void gotTouch4(){
 touch4detected = true;
}
void gotTouch5(){
 touch5detected = true;
}
void gotTouch6(){
 touch6detected = true;
}

void setup() {
  Serial.begin(115200);
  delay(1000); // give me time to bring up serial monitor
  Serial.println("ESP32 Touch Panel Test");
  touchAttachInterrupt(T0, gotTouch1, threshold);
  touchAttachInterrupt(T2, gotTouch2, threshold);
  touchAttachInterrupt(T3, gotTouch3, threshold);
  touchAttachInterrupt(T4, gotTouch4, threshold);
  touchAttachInterrupt(T5, gotTouch5, threshold);
  touchAttachInterrupt(T6, gotTouch6, threshold);
}

void loop(){
  bool t1 = false;
  bool t2 = false;
  bool t3 = false;
  bool t4 = false;
  bool t5 = false;
  bool t6 = false;
  int detected = 0;

  if(touch1detected){
    t1 = true;
    touch1detected = false;
  }
  if(touch2detected){
    t2 = true;
    touch2detected = false;
  }
  if(touch3detected){
    t3 = true;
    touch3detected = false;
  }
  if(touch4detected){
    t4 = true;
    touch4detected = false;
  }
  if(touch5detected){
    t5 = true;
    touch5detected = false;
  }
  if(touch6detected){
    t6 = true;
    touch6detected = false;
  }

 if(t1 && t4){
    detected = 1;
  }else if(t1 && t5){
    detected = 2;
  }else if(t1 && t6){
    detected = 3;
  }else if(t2 && t4){
    detected = 4;
  }else if(t2 && t5){
    detected = 5;
  }else if(t2 && t6){
    detected = 6;
  }else if(t3 && t4){
    detected = 7;
  }else if(t3 && t5){
    detected = 8;
  }else if(t3 && t6){
    detected = 9;
  }

 if(detected == 0){
    delay(100);
 }else{
    Serial.println(detected);
    delay(1000);
 } 
}

 いろいろ試してみた結果、閾値は15としました。

実行

 シリアルモニタを見ながらアルミテープの交点を指で押さえると1~9の数が出力されました。

 反応しない、または反応しっぱなしであれば1行目の閾値を変えてみます。

広告