前回の記事の最後 でも少し触れましたが、Arduino コア開発の Issuesプルリクフォーラム などで活躍中の Delta-G 氏 による、UNO R4 静電容量式タッチセンシングユニット(Capacitive Touch Sensing Unit、略して CTSU)用ライブラリの R4_Touch を試した結果を共有します。

本記事では、フォーラムにおける次の3つのトピックスを参照しています。

CTSU の動作原理

CTSU の正確な解説は、Renesas RA4M1グループ ユーザーズマニュアル ハードウェア編 の P.1444「41.3.1 計測動作原理」に譲るとして、ここではマニュアルを読むのが面倒な人向けに :roll_eyes:、私の理解を解説をしたいと思います。

タッチの検出原理

By Mercury13 - Own work, CC BY-SA 3.0, Link

人体はコンデンサに例えることができ、その静電容量は 100pF 1 とも 200pF 2 とも言われています。

このためタッチ電極に指が近づくと、元々回路周辺にある静電容量(寄生容量)に人体の静電容量が加わります。この静電容量の変化を観測することでタッチを検出します。

一般にコンデンサの静電容量の測り方として、定電流で充電した時の基準電圧に達するまでの時間を測定するという方法がありますが 3、CTSU では、基準電圧で充放電を高速に繰り返した時の スイッチドキャパシタフィルタ に流れる電流量を ICO(電流制御発振器、Intensity of Current Controlled Oscillator)に供給し、同電流に比例した周波数で生成されたクロックパルスを一定時間カウンタ回路が数え、そのカウント値をレジスタに出力します。

つまり、直接的に静電容量を測定するのではなく、電極に指を置く前後のカウンタ値の差で、タッチを検出するワケです。

CTSU 計測回路 - スイッチドキャパシタフィルタとICO

スイッチドキャパシタフィルタは、一般にアナログ信号を帯域制限するローパスフィルタとして使われますが、CTSU では、「コンデンサへの充放電をスイッチで切り替えることで抵抗のような働きをする特性」(交流回路における容量性リアクタンス)を利用します。即ち、コンデンサへの電荷の移動を等価な抵抗に流れる電流に置き換えます。

この時の等価抵抗は R=12πfCR = \frac{1}{2 \pi fC} で表され、オームの法則より I=VR=2πfCVI = \frac{V}{R} = 2 \pi fCV となります(VV は基準電圧を、ff はスイッチング周波数を、CC は測定対象の容量を表す)。

つまり、電流 II と容量 CC は比例関係にあるため、静電容量 CC を求める代わりに、電流 II の変化を観測することでタッチを判定するワケです。

検出原理に基づく CTSU のポイント

ユーザーマニュアル には、初期設定フローや状態遷移、各計測モードの処理フローが説明されていますが、どれも相当に複雑ですし、CTSU のレジスタも多数あります。

一方、上記の測定原理からは、次の5つのパラメータがポイントとなることが推察されます。

  • タッチ電極を含む寄生容量の初期値
  • 充放電ためのセンサ駆動パルスの周波数
  • ICO による電流→周波数変換の比例係数
  • カウンタによるクロックパルスの計測時間
  • タッチの有無を判定するクロックパルスの変化量

これらの項目を押さえつつ、組み込まれた回路を正しく動作させる手順を辿れば、複雑な CTSU の処理フローとレジスタの関係を理解するのに役立つのではないかと考えています。

この想定が正しいか否かはまだ分かりませんが、何よりまず、実際に動作する回路を製作し、その後に マニュアル のフローに沿ってプログラミングされた R4_Touch の助けを借りて、CTSU の動作を紐解いていく、という手順で進めたいと思います。

試作した回路

CTSU では、個々のタッチ電極でタッチの有無を検出する「自己容量方式」と、マトリックス状に配置した2つの電極間の差を取ることで寄生容量をキャンセルする「相互容量方式」の2つの計測方式を含め、3つの計測モードが使用可能です。

  • 自己容量シングルスキャンモード
    1つのタッチセンシング端子に対し、センサ駆動パルスの High 期間に、自己容量方式で1回の計測を行うモード

  • 自己容量マルチスキャンモード
    全てのタッチセンシング端子に対し、センサ駆動パルスの High 期間に、自己容量方式で1回の計測を行うモード

  • 相互容量フルスキャンモード
    全てのタッチセンシング端子に対し、センサ駆動パルスの立ち上がり、立ち下がり両エッジで、相互容量方式の2回の計測を行うモード

まずは、「自己容量方式マルチスキャンモード」で原理確認することとします。

I/O 端子仕様の確認

マニュアル の P.62「端子機能」から、CTSU に割り当てられたタッチセンシング端子(以下、TS 端子と表記)を確認します。

機能 TS 端子名 入出力 説明
CTSU TS00 ~ TS13, TS17 ~ TS22,
TS27 ~ TS31, TS34, TS35
入力 静電容量式タッチセンシング端子
^ TSCAP - タッチドライバ用の二次電源端子

同じく P.438「入出力端子機能のレジスタ設定」から、上記端子と Minima/WiFi のピン番号との対応を調べます。Dn はデジタルピンを、An はアナログピンを表します。

TS 端子と Minima/WiFi ピン番号の対応表

TS 端子 割り当てられた I/O 端子 Minima ピン番号 WiFi ピン番号
TS00 P204 LOVE -
TS02 P303 D9 D9
TS06 P410 - D12
TS07 P411 - D11
TS08 P302 D1 D1
TS09 P301 D0 D0
TS11 P304 D8 D8
TS12 P111 D13 D6
TS13 P104 D3 D2
TS21 P000 A1 A1
TS22 P001 A2 A2
TS27 P113 - LOVE
TS34 P105 D2 D3
TSCAP P203, P205, P112 D10 D7

また、どのピンがタッチセンサに使えるか一目で判るよう、逆引きの表も作ってみました。

Minima/WiFi のピン番号と TS 端子の対応表

デジタルピン アナログピン Minima TS 端子 WiFi TS 端子
D0 - TS09 TS09
D1 - TS08 TS08
D2 - TS34 TS13
D3 - TS13 TS34
D6 - - TS12
D7 - - TSCAP
D8 - TS11 TS11
D9 - TS02 TS02
D10 - TSCAP -
D11 - - TS07
D12 - - TS06
D13 - TS12 -
(D15) A1 TS21 TS21
(D16) A2 TS22 TS22

TSCAP には基準電圧を安定させるデカップリングキャパシタ(パスコン)を接続します。マニュアル P.1635 「48.11 CTSU 特性」の表から、10nF ± 10% のコンデンサを、Minima は D10 ピンと GND ピンの間に、WiFi では D7 ピンと GND ピンの間に外付けします。

項目 シンボル Min Typ Max 単位 条件
TSCAP 端子に接続された外付け容量 Ctscap 9 10 11 nF VCC = AVCC0 = 1.8~5.5V

タッチ電極部の試作

試作1回目:タッチセンサ部
試作1回目:タッチセンサ部

あまり深くは考えずに、ユニバーサル基板に厚さ 0.3mm、1cm 角の銅板を貼り付けてみました。これはコレで、電極に直接指を触れさせた時の動作を確認することは出来ましたが、カバーを付けることを考えなかったので… 失敗でした :sweat_smile:

試作2回目:タッチセンサ部パーツ
試作2回目:タッチセンサ部パーツ

気を取り直し、2回目の試作は、カバー(0.3mm 厚のプラ板)を取り付けた時のデコボコ感を減らすために学校教育工作用紙で銅板を囲い、写真のように試作してみました。

より実用的にするには、タッチ電極を含めてプリント基板を作っちゃうのが良いですね。

試作2回目:センサ基板 - 裏面 試作2回目:センサ基板 - 表面 試作2回目:センサ基板 - 組み上げ

デカップリングキャパシタは、手持ちの 10nF(0.01μF)セラミックコンデンサを、またタッチの確認用に6個の LED を外付けしました(LED に接続する抵抗値は、この記事 を参照すると良いですョ)。

ブレッドボード右上の小さなブレークアウト基板は、USBシリアル変換モジュール FT234X で、前の記事 で製作した PeripheralMonitor で CTSU レジスタを観察するためのものです。

0.01μF パスコン 確認用 LED と USB シリアル変換モジュール UNO R4 + タッチセンサ

テストプログラムの実行

ライブラリのインストール

この記事を書いている最中にも R4_Touch がアップデートされ、正式版として 1.0 がリリース されました。作者である Delta-G 氏 はこのところ連チャンで投稿を続けていて、精力的な活動振りがよく分かります。

  1. 最新の .ZIP ファイル をダウンロードします。
  2. Arduino IDE メニューから「スケッチライブラリをインクルード.ZIP形式のライブラリをインストール…」を実行し、ダウンロードしたファイルを読み込ませます。

テストプログラムの実行

ライブラリ R4_Touch の例題 Simple Touch Example.ino を開くと、Minima あるいは WiFi の基板裏面にある LOVE ピンでの動作確認ができます。

静電気放電(ESD)でボードが逝かないよう、LOVE ピンには直に触れず、何かでカバーするよう注意が促されています。

僕は試作したタッチ電極と LED を使い、タッチの検出原理 で解説したカウンタ値を読み込む、次のようなコードで実験を行いました。Minima でも WiFi でも動作するピンを選んでいます。

#include "R4_Touch.h"

void setup() {
  Serial.begin(115200);
  while(!Serial);
#ifdef  ARDUINO_UNOR4_WIFI
  delay(1000); // UNO R4 WiFi needs at least 600 ms to complete Serial initialization.
#endif

  // LED の初期化
  pinMode(12, OUTPUT);
  pinMode(11, OUTPUT);
  ; // 以下、略

  // タッチセンサ部の初期化
  setTouchMode( 9);
  setTouchMode( 8);
  ; // 以下、略

  TouchSensor::start();
}

void loop() {
#if 0
  // 各タッチパッドの値を出力する
  Serial.print("   " + String(touchRead( 9)));
  Serial.print("   " + String(touchRead( 8)));
  ; // 以下、略
  Serial.println();
  delay(500);
#else
  // 各タッチパッドの値をに応じて LED を点灯/消灯させる
  digitalWrite(12, touchRead( 9) > 18500 ? HIGH : LOW);
  digitalWrite(11, touchRead( 8) > 19000 ? HIGH : LOW);
  ; // 以下、略
  delay(100);
#endif
}

見てお分かりの通り、loop() 前半の #if 文で、タッチ前後のカウンタ値を確認し、後半で各電極に閾値を設定して LED を光らせています。

次の図に、試作1回目のベアメタルでの状態と、試作2回目のカバーを被せた状態で、タッチ前後のカウンタ値の変化を観測した結果を示します。中央の2列はアナログピンのカウンタ値で、寄生容量に相当するタッチ前のカウンタ値が、明らかに他のピンと異なりました。

ベアメタルでのタッチ結果 カバー後のタッチ結果

また、デカップリングコンデンサの有無でもカウンタ値が大きく異なりました。

これらの結果から、次のことが推察できます。

  • タッチ電極や回路構成によって、カウンタ値が異なる
  • デジタルピンとアナログピンで、カウンタ値が異なる
  • カバーの厚みや材質によっても、カウンタ値が異なる

また人体の静電容量は個人差もあるハズなので、安定して検出するには、カウンタ値のベースラインと判定閾値のキャリブレーションが必要であることが分かりました。電極の経年劣化にも耐えられるよう、検出原理に基づく CTSU のポイントで推察したパラメータを自動で設定できる、セルフキャリブレーションが組めればベストですね。

とりあえず今回はここまでとし、次回以降、R4_Touch のソースコードとユーザーマニュアルに記載された CTSU の処理フローを見比べながら、CTSU レジスタの使い方を紐解いてみたいと思います :sunflower:

おまけ

タッチ電極部を作成した後になっちゃったんですが、次の2つのアプリケーションノートを読みました。

それらによると、TS 端子とタッチ電極間は、突入電流低減のためにダンピング抵抗を接続してくださいとのことです。また色々な電極や配線パターンのデザイン要件が載っているので、プリント基板を起こす際など、参考にすると良いと思います。

参考文献