ESP32のタッチセンサの使い方と外れ値処理

はじめに

Arduinoの無線版であるESP32(正式名称はESP-WROOM-32)モジュールにはデフォルトでタッチセンサが10個もついています。ライブラリもあって使うのは非常に簡単です。今回はタッチセンサの使い方と、実際に自作デバイスを作るときのノウハウについて書きます。

使い方

無線チップが乗っていてArduinoとしてプログラミングもできるモジュールESP32を使用します。


ちなみに20円安くwavesという所からも出てますが、ピンヘッダの半田付けが悪くブレッドボードに刺さりにくいというレビューがあったので、こちらのHiletgoの方をおすすめします。ピンヘッダも問題ありませんでした。

ArduinoIDEにライブラリをインストールするのはこちらを参考にしました。
ESP32-DevKitCを使ってみた〜環境構築からタッチセンサによるLチカまで〜

タッチセンサを使うプログラムはめちゃくちゃ簡単で、次のコードだけです。(サンプルコードそのまま)

// ESP32 Touch Test
// Just test touch pin - Touch0 is T0 which is on GPIO 4.

void setup()
{
  Serial.begin(115200);
  delay(1000); // give me time to bring up serial monitor
  Serial.println("ESP32 Touch Test");
}

void loop()
{
  Serial.println(touchRead(T0));  // get value using T0
  delay(1000);
}

何も宣言しなくても、「touchRead(T0)」を書くだけで値の取得ができます。T0ピンに触れていないときは40~70の値、触れてるときは10~30の値になります。

タッチ判定

このタッチセンサを使うシチュエーションとしては、センサに触ったら何かの動作をさせることが多いと思います。タッチの判定条件として一番簡単でよく使われているのは、「センサ値がt以下になった時、処理を実行する」です。

void setup() {
  Serial.begin(115200);
}

void loop() {

  int t0 = touchRead(T0);
  Serial.println(t0);
  
  if(t0 < 40){
    Serial.println("なんらかの処理");
    /*
     * なんらかの処理
     */

  }

  delay(10);

}

しかし、これだとセンサに触れている間はずっとt0<40になってしまい、処理が連続で実行されてしまいます。そこで、一度タッチしたらセンサから指を離すまで待つことが必要です。

void setup() {
  Serial.begin(115200);
}

void loop() {

  int t0 = touchRead(T0);
  Serial.println(t0);
  
  if(t0 < 40){
    Serial.println("なんらかの処理");
    /*
     * なんらかの処理
     */

    //継続して触れている間は何もしない
    while(t0 < 40){
      t0 = touchRead(T0);
      Serial.println(t0);
      delay(10);
    }
  }

  delay(10);

}

たまに外れ値が出る。。。

はじめは上のプログラムで動かしていたのですが、このタッチセンサはたまに触れていないのに0を出すことがあります。

センサ値をプロットしたところ、触れていないのに変な値が出ることがある

この外れ値は連続で出るわけではなく、一瞬出てすぐに普通の値に戻ります。そのような外れ値に対応するための処理として急激な変化の影響を少なくする、ローパスフィルタというものがあります。ローパスフィルタのプログラムは簡単で、前の値を覚えておいて今回の値の方にちょっとずらすことを繰り返します。

サンプルコードはこんな感じです。

int t0_old;

void setup() {
  Serial.begin(115200);
}

void loop() {

  int t0 = touchRead(T8)*0.1 + t0_old*0.9;
  t0_old = t0;
  
  Serial.println(t0);

  
  if(t0 < 40){
    Serial.println("なんらかの処理");
    
    while(t0 < 40){
      t0 = touchRead(T8)*0.1 + t0_old*0.9;
      t0_old = t0;
      Serial.println(t0);
      delay(10);
    }
  }

  delay(10);

}

このときのセンサ値をプロットしたものがこちらです。

ローパスフィルタによって外れ値が除去できました!

ローパスフィルタによって外れ値が除去できました。これでタッチ判定が誤作動することも無くなります。あとは何らかの処理を書けば、簡易スイッチの完成です!

コメントを残す

メールアドレスが公開されることはありません。