デジタル信号を使ってアナログ的信号を生み出す「PWM機能」とは
単にLEDの点灯だけでは面白くないので、次は、タッチによってLEDの明るさを変更するようにしてみましょう。LEDの明るさを変化させるには、PWM方式を使うのが一般的です。
PWMとは
PWMとは、PWMはPulse Width Modulationの略で、日本語では「パルス幅変調」となります。パルス信号のONの時間(パルス幅)を長くしたり、短くすることで、平均電圧を変化させることができます。この仕組みは、デジタルな信号を使用してアナログ的な信号を生み出すための手法です。
このPWMの信号でLEDを点灯させると、非常に短い間隔で、点灯と消灯を繰り返すことになります。ただし人の目には、ずっと点灯しているように見えます。点灯と消灯との時間の割合(デューティ比)を変化させると、人の目には、明るさが変わったように見えるのです。
PWMを使うには
PWMを使うには、次のNuGetパッケージを追加します。
先ほどのプログラムを変更して、PWMを利用するようにしてみます。PWMでは、GPIOの設定は不要なのでGpioControllerは使わず、代わりに、nanoFramework.Hardware.Esp32.Configurationクラスを利用します。
public class Program
{
public static void Main()
{
// ピンにPWM機能を割り当てる(1)
Configuration.SetPinFunction(22, DeviceFunction.PWM1);
// PWMの設定(2)
var pwmPin = PwmChannel.CreateFromPin(22, 400, 0.5);
// PWM出力の開始(3)
pwmPin.Start();
Thread.Sleep(Timeout.Infinite);
}
}
まず、Configurationクラスの静的メソッドであるSetPinFunctionメソッドを使って、ピンにPWM機能を割り当てます。第2パラメータに設定しているDeviceFunction.PWM1は、複数のピンでPWMを利用する際の識別子となるものです。PWM1~PWM16まであり、複数のPWMを使用する時は、それぞれ別の値を指定します。
そして、System.Device.Pwm.PwmChannelクラスを用いて、個別のPWMの設定を行います。CreateFromPinメソッドで、ピン番号と、PWMの周波数とデューティ比を指定します(2)。PWMの周波数とは、1秒あたりのパルスの数を表し、デューティ比はパルスがオンになっている時間の割合を示します。ここでは、周波数を400㎐、デューティ比を0.5(50%)にしています(この値がパラメータのデフォルト値になります)。
波形の確認
Startメソッドで、PWM出力が開始されます。このプログラムを実行すると、デバッグ表示には何も出力されないものの、オシロスコープなどで22番ピンを測定すると、次のような波形が確認できます。多少誤差はありますが、周波数400㎐、デューティ比が50%になっています。
タッチセンサーでLEDの明るさを変える
それでは、タッチセンサーで明るさを変えてみましょう。プログラムを次のように書き換えます。LEDの接続は、いままでと同様に、抵抗を介して22番に接続します。
public static void Main()
{
Configuration.SetPinFunction(22, DeviceFunction.PWM1);
// デューティ比を0にしておく(1)
var pwmPin = PwmChannel.CreateFromPin(22,400, 0);
pwmPin.Start();
var TouchPadNumber = 0;
var touchpad = new TouchPad(TouchPadNumber);
var calib = touchpad.GetCalibrationData();
touchpad.Threshold = (uint)(touchpad.CalibrationData * 0.8);
TouchPad.MeasurementMode = MeasurementMode.Timer;
double duty = 0.0;
touchpad.ValueChanged += ( _, e) =>
{
if (e.Touched)
{
// デューティ比を0.01ずつ増加させる(最大1.0)(2)
duty += 0.01;
if (1 < duty) duty = 0.0;
pwmPin.DutyCycle = duty;
}
};
Thread.Sleep(Timeout.Infinite);
}
最初にデューティ比を0にして、消灯状態にしています(1)。タッチイベントのハンドラで、デューティ比を増加させています(2)。タッチするたびに、次第にLEDは明るくなるはずです。
