3.13. PWM と RC フィルタでアナログ信号を生成する¶
ADC はピン上の電圧を読み取ります。その逆、つまりピン上に 0 V と Vcc の間の中間電圧を生成することはより困難です。なぜなら GPIO 出力は 2 つのレールを駆動する方法しか知らないからです。標準的な代替手段は、平均電圧が目的の値になるよう、ピンをレール間で十分高速に切り替えることです。
3.13.1. パルス幅変調¶
パルス幅変調(PWM)信号は固定周波数の方形波で、そのハイ時間、つまり各周期のうちグランドではなく Vcc で過ごす割合がソフトウェアで設定されます。その割合がデューティサイクルです。波形の平均電圧はデューティサイクルと Vcc の積になります:
V_avg = duty × Vcc
デューティサイクル 25 % は平均で Vcc / 4、デューティサイクル 50 % は Vcc / 2、デューティサイクル 75 % は 3 × Vcc / 4 になります。
デューティサイクル 25 %、50 %、75 % の PWM。平均電圧はデューティサイクルに追従します。¶
周波数は PWM の設定時に決められ、デューティサイクルはソフトウェアが動作中に変更するものです。machine.PWM クラスは、CPU の介入なしに波形を生成するハードウェアタイマーチャネルをラップします。一度設定すれば、変更されるまで選択した周波数とデューティサイクルで信号が継続します。
3.13.2. machine.PWM クラス¶
ピンと初期の周波数およびデューティを指定して PWM インスタンスを生成します:
from machine import PWM, Pin
pwm = PWM(Pin("P7"), freq=20_000, duty_u16=32768)
これにより P7 上でデューティ 50 % の 20 kHz 方形波が開始されます。2 つのメソッドで出力を動作中に変更できます:
pwm.duty_u16(16384) # change to 25 % (16384 / 65535)
pwm.freq(5_000) # change to 5 kHz
duty_u16() は符号なし 16 ビット整数を取り、0 を「常にロー」に、65535 を「常にハイ」に対応付けます。freq() はキャリア周波数をヘルツ単位で設定します。
注釈
同じハードウェアタイマー上のすべての PWM チャネルは周波数を共有します。1 つのチャネルで freq() を呼び出すと、そのタイマーに接続された他のすべてのチャネルも変更されます。出力を異なる周波数で動作させる必要がある場合は、別々のタイマーのチャネルを使用してください。
出力が不要になったら deinit() を呼び出してタイマーチャネルを解放します。
3.13.3. RC ローパスフィルタによる平均化¶
生の PWM は滑らかな電圧ではなく、その平均が目的の値である方形波です。その平均を取り出すには、PWM をローパスフィルタに通します。これは デバウンス でスイッチのデバウンスに使用したのと同じ抵抗とコンデンサの組み合わせです。
RC ローパスフィルタを通した PWM: コンデンサが方形波を平均化し、デューティサイクルに比例した直流電圧に変えます。¶
フィルタのカットオフ周波数、つまり通過させる周波数と遮断する周波数の境界は、デバウンス回路の時定数を与えたのと同じ RC の積によって決まります:
f_c = 1 / (2π × R × C)
フィルタが PWM 入力からクリーンな直流電圧を取り出すには、カットオフ周波数が PWM 周波数自体よりもはるかに低くなければなりません。直流成分(周波数 0)はそのまま通過し、PWM の基本高調波(PWM 周波数)はおよそ f_c / f_PWM だけ減衰します。1 / 200 の比では、出力に残るリップルが入力振幅の約 0.5 % まで低減されます。
ゆっくり変化する設定値に対する妥当な出発点:
PWM 周波数
f_PWM = 20 kHz-- 可聴域を十分に上回り、タイマーがクリーンに生成しやすい値です。フィルタ値
R = 1.6 kΩ、C = 1 µF-- これによりf_c = 1 / (2π × 1.6 kΩ × 1 µF) ≈ 100 Hzとなります。
キャリアにおける 200 倍の抑制により、PWM のフルスイングは V_out における残留リップルのおよそ Vcc / 200 まで低減されます。3.3 V では約 16 mV です。
2 つの実用的な注意点:
フィルタの出力インピーダンスはおよそ
Rです。電流を引き出す下流の負荷があると、Rとその負荷が分圧回路を形成し、ADC でアナログ信号を読み取る ページの分圧回路とまったく同じようにV_outを理想的な平均値より下に引き下げます。ミリアンペア単位の電流を吸い込む負荷ではなく、ADC ピンや高インピーダンスのバッファに供給してください。デューティサイクルが変化したとき、コンデンサが安定するまでには約
5 × R × C ≈ 8 msかかります。V_outはその分だけデューティ設定に遅れて追従します。より速く更新する必要のある設定値の場合は、カットオフを上げ(RかCを小さく)、より多くのリップルを許容してください。