ESP32でタッチセンサーを使ってみた

ESP32でタッチセンサを使う

こんにちは。wak-tech Advent calender 大遅刻の13日目です。
今日はESP32に内蔵されているタッチセンサを使ってみます。

実行環境

回路


いろいろつながっていますが、今回はIO14ピンにジャンパワイヤをつないだだけです。このピンに繋がっている導体の静電容量を読み取ることでセンサーとしているようです。

タッチセンサについて

uint16_t __touchRead(uint8_t pin)
{
   int8_t pad = digitalPinToTouchChannel(pin);
   if(pad < 0){
       return 0;
   }

   pinMode(pin, ANALOG);

   __touchInit();

   uint32_t v0 = READ_PERI_REG(SENS_SAR_TOUCH_ENABLE_REG);
   //Disable Intr & enable touch pad
   WRITE_PERI_REG(SENS_SAR_TOUCH_ENABLE_REG,
           (v0 & ~((1 << (pad + SENS_TOUCH_PAD_OUTEN2_S)) | (1 << (pad + SENS_TOUCH_PAD_OUTEN1_S))))
           | (1 << (pad + SENS_TOUCH_PAD_WORKEN_S)));

   SET_PERI_REG_MASK(SENS_SAR_TOUCH_ENABLE_REG, (1 << (pad + SENS_TOUCH_PAD_WORKEN_S)));

   uint32_t rtc_tio_reg = RTC_IO_TOUCH_PAD0_REG + pad * 4;
   WRITE_PERI_REG(rtc_tio_reg, (READ_PERI_REG(rtc_tio_reg)
                     & ~(RTC_IO_TOUCH_PAD0_DAC_M))
                     | (7 << RTC_IO_TOUCH_PAD0_DAC_S)//Touch Set Slope
                     | RTC_IO_TOUCH_PAD0_TIE_OPT_M   //Enable Tie,Init Level
                     | RTC_IO_TOUCH_PAD0_START_M     //Enable Touch Pad IO
                     | RTC_IO_TOUCH_PAD0_XPD_M);     //Enable Touch Pad Power on

   //force oneTime test start
   SET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_START_EN_M|SENS_TOUCH_START_FORCE_M);

   SET_PERI_REG_BITS(SENS_SAR_TOUCH_CTRL1_REG, SENS_TOUCH_XPD_WAIT, 10, SENS_TOUCH_XPD_WAIT_S);

   while (GET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_MEAS_DONE) == 0) {};

   uint16_t touch_value = READ_PERI_REG(SENS_SAR_TOUCH_OUT1_REG + (pad / 2) * 4) >> ((pad & 1) ? SENS_TOUCH_MEAS_OUT1_S : SENS_TOUCH_MEAS_OUT0_S);

   //clear touch force ,select the Touch mode is Timer
   CLEAR_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_START_EN_M|SENS_TOUCH_START_FORCE_M);

   //restore previous value
   WRITE_PERI_REG(SENS_SAR_TOUCH_ENABLE_REG, v0);
   return touch_value;
}

Arduino core for ESP32には上記の**touchRead(pin)**関数があります。このピンの値を返してくれる関数です。

使用可能なピン

上の方で紹介したピン配置のうちT0~T9の機能が割り当てられているピンが使用可能です。
例えばGPIO14ピンにはTOUCH6が割り当てられているので、

value = touchRead(T6);

とするだけでvalueにその値を入れることができます。

センサの値を読み取る

実際にこのT6の値を読み取ってみて、どういうときにどのような変化をするのかを見てみましょう。

ソースコード

// ESP32 Touch Test
// TOUCH6(GPIO14)にジャンパワイヤなどの導体を接続

void setup()
{
  Serial.begin(115200);
  delay(1000); //シリアル通信準備待ち時間
  Serial.println("ESP32 Touch Test");
}

void loop()
{
  Serial.println(touchRead(T6));
  delay(100);
}

結果

上記のプログラムを書き込み、ジャンパワイヤの先を手でタッチしたときの変化をシリアルモニタで見てみました。

最初の47という値が出ているときは触っていない状態。
触った状態が23という値として検出されました。

触れたかどうかを検出する

センサーの値はその日の気温・湿度・触る人・ジャンパワイヤの形状によって変化します。したがって値の絶対値だけで判定するのはおすすめしません

完全とは言えませんが、何も触っていない状態の値からの割合を使って判断するのがいいと思います。

プログラム例


double default_value = 0;
double value_ratio = 0;

void setup()
{
  Serial.begin(115200);
  delay(1000);
  Serial.println("ESP32 Touch Test");
  default_value = touchRead(T6); //最初の値を記録
}

void loop()
{
  value_ratio = touchRead(T6)/default_value;
  Serial.print("value_ratio:");
  Serial.println(value_ratio);
  delay(100);
}

起動してすぐの値をdefault_valueに入れます。
この値に対するタッチセンサの割合をvalue_ratioに入れ、それを表示しているだけのプログラムです。

結果

これで閾値の判定として使える値が取り出せるようになりました。

今後の使用例

今回使用したタッチセンサの値を閾値としてタッチ式のスイッチを簡単に作ることができます。

導体であればなんでもセンサーとして使用できるため、今までにないような見た目のセンサーが作れるわけです。
たまに見かけるスイッチをタッチしただけで明かりのオンオフができるライトなんかも作れます。

私はこのセンサーを使ってLEDの点灯、それから9個あるセンサーを利用してタッチ式ピアノを作る予定です。twitterにて新記事投稿の通知を行っていますのでぜひフォローお願いいたしますm(__)m

>>ESP32チュートリアル一覧に戻る

「ESP32でタッチセンサーを使ってみた」に4件のコメントがあります

  1. ピンバック: ESP32でタッチセンサを使ってLチカする(スイッチとしての使用) | Wak-tech

  2. ピンバック: ESP32でタッチセンサを使ってピアノを作ってみた | Wak-tech

  3. ピンバック: ESP32で始めるIoT電子工作入門【20個のチュートリアル】 | Wak-tech

  4. ピンバック: ESP32のタッチセンサ3つでドレミファソラシまで鳴らせるピアノを作ってみた | Wak-tech

コメントする

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です