対象読者
IoTに興味があり、C#と電子工作の基本的な知識がある方を対象とします。C#や電子工作のごく初歩的な説明は割愛していますので、「C#ではじめるラズパイIoTプログラミング」の記事なども併せて参照してください。
はじめに
連載第3回の今回は、ESP32のタッチセンサーとPWM機能を使ったプログラムを紹介します。
電荷でタッチイベントを検出、ESP32のタッチセンサーとは
ESP32は、静電容量式のタッチセンサーが内蔵されており、ESP32のピン端子がそのままセンサーとして利用できます。前回のピンレイアウトの表にも書いているとおり、タッチセンサーとして使えるピンは10個あります。ただし、ESP32-WROVER開発ボードと現状の.NET nanoFrameworkの組み合わせでは、10個のタッチセンサーのうち、3個はうまく動作しないようです。
静電容量式タッチセンサー
静電容量式のタッチセンサーは、コンデンサの原理を利用して、導体の接近を検出するセンサーです。ESP32では、ピンに接続されたコンデンサに電荷を貯めて、ピンの電荷を測定しています。ピンに触れるなどすると、電荷がピンから移動することで電荷が減るため、その変化をタッチイベントとして検出します。電荷の値は、ESP32の個体差や環境によって変わりますので、値の変化量でタッチされたかどうかを判定します。
タッチセンサーの基本的な使い方
では、ESP32のタッチセンサー機能を確かめてみましょう。Visual Studioで、まずはBlank Applicationプロジェクトを作成し、それから、次のNuGetパッケージを追加します。
そして、Mainメソッドを次のように書き換えます。ここでは、タッチセンサー番号として0を指定しています(1)。ESP32-WROVER開発ボードでは、GPIO4番がタッチセンサー0になりますので、GPIO4番につながるようにジャンパー線を接続しておきます。
プログラムをデバッグ実行します。ジャンパー線の端子に直接触れると、タッチイベントが発火します。ジャンパー線をつかんだり離したりするたびに、ON、OFFの文字列がVisual Studioのデバッグ出力に表示されるはずです。
public class Program { public static void Main() { // タッチセンサー番号の指定(1) var TouchPadNumber = 0; // TouchPadインスタンスの生成(2) var touchpad = new TouchPad(TouchPadNumber); // 基準値の取得(3) touchpad.GetCalibrationData(); // しきい値の設定(4) touchpad.Threshold = (uint)(touchpad.CalibrationData * 0.8); // 測定モードをタイマーに設定する(5) TouchPad.MeasurementMode = MeasurementMode.Timer; // イベントハンドラの定義(6) touchpad.ValueChanged += (_, e) => Console.WriteLine(e.Touched? "OFF":"ON"); Thread.Sleep(Timeout.Infinite); } }
タッチセンサーは、TouchPadクラスを利用します。インスタンスを生成して(2)、まずは、最初に基準となる値を取得します(3)。そして、タッチイベントを発生させる、しきい値として、基準値(CalibrationDataプロパティ)の80%を設定します(4)。基準値の2/3程度を設定するのが標準的ですが、実際に試して調整するようにします。
タッチセンサーに触れると、タッチセンサーから読み取れる値が下がります。しきい値を下回れば、タッチイベントが発生することになります。タッチセンサー値は、そのときの状況によって変化しますので、しきい値の設定は初期の値を元に計算するようにします。
次に、測定モードを設定しています(5)。ここでは、タイマーとしていますが、設定できるモードは、次の2つです。
MeasurementMode.Timer | バックグラウンドで値が自動的に取得される |
MeasurementMode.Software | 手動で値を取得する必要がある |
MeasurementMode.Timerでは、バックグラウンドで値が自動的に取得されてイベントが発生します。MeasurementMode.Softwareでは、手動で定期的に値を取得する必要があります。取得したときに、値がしきい値を下回れば、イベントが発生します。今回はセンサーの値は特に必要ないので、MeasurementMode.Timerに設定しています。
(6)行では、ValueChangedイベントに、デバッグ出力するようにイベントハンドラを定義しています。イベントの2つめのパラメータは、TouchPadEventArgsオブジェクトになっています。このオブジェクトのTouchedプロパティが、タッチされたかどうかの状態を示します。ここでは、タッチされた時にON、その後に離れたときにOFFと表示します。
タッチセンサーでLEDをON、OFF
前回は、LEDの点灯制御をタクトスイッチで行いましたが、これをタッチセンサーで置き換えてみましょう。
次のように、Mainメソッドを書き換えます。
using var controller = new GpioController(); // GPIO22番の初期化、設定 var led = controller.OpenPin(22); led.SetPinMode(PinMode.Output); led.Write(PinValue.Low); var TouchPadNumber = 0; var touchpad = new TouchPad(TouchPadNumber); touchpad.GetCalibrationData(); touchpad.Threshold = (uint)(touchpad.CalibrationData * 0.8); TouchPad.MeasurementMode = MeasurementMode.Timer; touchpad.ValueChanged += ( _, e) => { if (e.Touched) { led.Toggle(); // GPIOの値の反転 } }; Thread.Sleep(Timeout.Infinite);
前回のGPIOのプログラムで、タクトスイッチ用のGPIO部分を、タッチセンサーの処理に変更しています。これを実行すると、ジャンパー線に触れるたびに、LEDが点いたり消えたりするはずです。