PR

ArduinoのanalogWrite()はPWM

なんだか当たり前のことを書いてしまったようなタイトルだけど、「analogWrite()はアナログ値が出てくるのではなくてPWMのデューティを指定するものなので、それを実測してみよう」という実験。

基礎実験(デューティ50%)

まず、analogWrite()のマニュアルはこちら。

analogWrite()の引数でデューティ比を指定する。0で0%、255で100%。

では、127を指定して50%デューティで出力してみる。Arduinoの3番ピンに出力し、そのまま観測(無負荷)。

周波数は490Hz(マニュアル通り)、デューティは49.8:50.2。ま、こんなものかな。

なお、ボードはArduino UNO互換のSeeeduino V4.2。

アナログ値に変換(CRフィルタ)

PWM出力をアナログ値に変換するにはCRフィルタ(LPF)を通すのが簡単。世の中には便利なものがあって、オンラインでPWMをCRフィルタに通したときのシミュレーションが行える。

これに条件を設定して計算してみる。Arduinoの出力を使うので、PWM信号は490Hz、5V(デューティは50%とする)。CR LPFの定数は100Ω、100μFでやってみる。

収束電圧は2.5V、リプルは約255mVpp。

では、実測してみる。CH1がPWM出力、CH2がCRフィルタの出力(無負荷)。なお、Arduinoの電源はDC入力から(USB供給ではない)。

CH2の平均値は2.48V、リプルはカーソルで上下を捉えると720mV。シミュレーション値より大きい。現実はシミュレーションよりは悪くなるってことだろう。

Cを10倍のの1000μFにすると、リプルはほとんど見えなくなる(Rは100Ωのまま)。

リプルを拡大(オシロのプローブをAC結合に)。カーソルで拾って44mV。

デューティ比とアナログ値

続いて、デューティ比を変えて、CRフィルタを通したときのアナログ値を見てみる。CRフィルタは、100Ω、1000μF。無負荷で。

analogWrite(3, 10)

3は出力ピン番号。10はデューティ比(255で100%)。

計算上は3.9%で0.195V。実測で160mV。

analogWrite(3, 30)

計算上は11.8%で0.59V。実測で559mV。

analogWrite(3, 63)

計算上は24.7%で1.235V。実測で1.228V。

analogWrite(3, 127)

計算上は49.8%で2.490V。実測で2.475V。

analogWrite(3, 191)

計算上は、74.9%で3.745V。実測で3.720V。

こうやって見比べていくと、デューティ比を上げるとPWM出力のLowレベルがじわじわ上ってくるみたい。

analogWrite(3, 255)

計算上は100%で5.0V。実測で4.96V。

なお、このときのCH1(Arduinoの出力端子側)は下のように、5.04V。無負荷とはいえ、CRフィルタを通すと現実的には多少のロスがあるってことかな?まぁ、オシロのプローブが負荷といえば負荷だけど。

負荷による出力電圧の変動

ここまでの測定は無負荷の場合。続いて、負荷を接続したときの様子を見ていく。出力電流の増加に伴って出力電圧は落ちていく。下はデータシートから引用したグラフ。20mA流すと0.5V程度落ちることがわかる。

ATmega328Pの端子出力電流の絶対定格は各ピン40.0mA。複数のピンの合計では150mA(引込みでは100mA)。詳細はデータシートを確認。

ここでの実験では、CRフィルタ(100Ω、1000μF)を通した状態での出力電圧を見ていく。負荷は単に抵抗をつなぐ。PWM出力のデューティ比は50%でやってみる(無負荷状態での出力電圧は、上の結果によると2.475V)。

10kΩ

出力電圧2.421V。

4.7kΩ

出力電圧2.400V。

1kΩ

出力電圧2.198V。

470Ω

出力電圧1.917V。

100Ω

出力電圧1.086V。

負荷が100Ωになると、CRフィルタの100Ωと1:1になるので、それだけで出力電圧は1/2になる。ATmega328Pからの出力電圧も下がっているはずなので(CH1のHighレベルが低下していることも観測できている)、ずいぶん低い電圧になってしまう。

CRフィルタのRを小さくすればそこでの電圧降下は小さく抑えられるが、当然ながらリプルは増加する(Cを増やせばリプルを低減できるけど)。

PWMの周波数による違い

Arduino UNOでは3、5、6、9、10、11ピンがPWN出力に対応している。3ピンなどはこれまで見てきたように周波数は約490Hzだけど、5ピンと6ピンは二倍の約980Hzが出力される。

3ピンは、これまで見てきたように、490Hzで、50%、無負荷の場合はこのような感じ。

5ピンでは約980Hzで、リプルは小さくなる。

まとめ

  • ArduinoのanalogWrite()の出力はPWM。アナログ電圧を得たいのなら、CRフィルタを通す。
    • CもRも大きい方がリプルは小さくなる
    • ただし、Rによる電圧降下に要注意。
  • 出力電流が多めだと電圧が下がる(ATmega328Pからの供給電圧も、CRフィルタによる電圧降下も)。
  • デューティ比にできるだけ合わせた出力電圧(計算通りのの出力電圧)を得たいなら、負荷は軽く抑える。
    • CRフィルタのRは小さくCは大きく。
    • 負荷には直接電流を供給せずに、ドライバをかませる。
  • PWMの周波数が高いほうが、リプルの点では有利。

【おまけのシミュレーション】

1Ω・1000μFのフィルタだと、リプルというよりほぼ三角波(490Hz・50%)。


自作
この記事のタイトルとURLをコピーする
スポンサーリンク
スポンサーリンク
スポンサーリンク

コメント