【Raspberry Pi Pico入門 – 7】LEDの明るさを制御

2023年12月3日Raspberry Pi Pico入門,基本編

概要

今回はPWM制御という方式でLEDの明るさを制御してみます。

実行環境

IDE:Arduino IDE 2.1.1
MCU:Raspberry Pi Pico

今回のテーマ

  • アナログ出力(PWM制御)を使ってみる

回路

【Raspberry Pi Pico入門 – 3】と同じ回路を使用します。

コーディング

新しくスケッチを作成し、以下の内容をコピペしてください。
スターターキットとはコードが少し異なるので注意してください。

const int LED_PIN = 15;
int cnt = 0;

void setup() {
  analogWriteFreq(25000);
  analogWriteRange(1024);
  pinMode(LED_PIN, OUTPUT);
}

void loop() {
  if (cnt < 1024) {
    analogWrite(LED_PIN, cnt);
  } else {
    analogWrite(LED_PIN, 2048 - cnt);
  }

  cnt++;
  if (cnt > 2048) {
    cnt = 0;
  }

  delay(2);
}

動作確認

LEDがチカチカではなく蛍のように点滅すれば成功です。

解説

PWM制御

マイコンは基本的に電圧のHighかLowしか出力することが出来ません。そのマイコンでHighとLow以外の電圧を出力方法として一般的に使われているのがPWM制御(Pulse Width Modulation)です。これは周期的にHigh/Lowを繰り返し、Highの時間を増やしたり減らしたりすることによってHighとLowの中間の電圧を作り出しています。

今回の場合は25kHzの周波数(40[us]の周期)の矩形波を用いてHigh/Lowの時間を調整しています。HighとLowの比率については、「Duty」というものを使って表現します。この単位は矩形波の周期とHighになっている時間の比率をパーセントで表したものとなります。

$$Duty=\frac{ON時間}{周期}*100$$

言葉だけではわかりづらいので、Duty 20%、Duty80%の 電圧波形 を オシロスコープ で測定してみます。
横軸が時間(1目盛り10[us])、縦軸が電圧(1目盛り0.5[V])です。

Duty 20%
Duty 80%

プログラムではこのDutyを一定の値ではなく2[ms]ごとに変化させています。その結果、電圧波形は下の動画のように変化しています。
他の実験器具が大量に映り込んでいますが気にしないでもらえると嬉しいです。。。

ちなみにここまで解説したものは「ON Duty」と呼ばれており、逆に周期とOFF時間の比率である「OFF Duty」というものを使うこともあります。ICや電子部品によって使い分けるのですが、Dutyと言えばON Dutyのことを指すのが一般的です。

回路シミュレーション

ここまで解説した内容を実際に触って確認できるよう、シミュレーションを用意しました。
↓このリンク先にシミュレーション用の回路を作りました。「Duty Cycle」を動かすとLEDの明るさが変わります。(見た目で分かりやすいようにコンデンサを追加して変化スピードを遅くしています)

回路シミュレーション

コードの解説

analogWrite()という関数の第二引数でDutyの設定をすることが出来ます。通常のArduinoでは0~255の256段階で設定が可能です。
例) Duty 50% → 127
この何段階で表現するかをレンジと呼び、一般的にはbitで表現します。256段階の場合は8bitになります。
$$2^8=256$$

スターターキットに付属のサンプルコードとは異なり、analogWriteFreq()、analogWriteRange()という関数を使用しています。これは公式のボード情報ではなくArduino-Picoを使用している関係で使えるようになっている関数です。
公式では周波数は500Hz(ボードによって異なる)、レンジは8bitで固定ですが、Arduino-Picoを使用していれば自由に設定することが出来ます。

私自身は20~25kHz、10~12bitで使用することが多いです。周波数はモーター制御でよく使われる値で、レンジはこれ以上細かくしても誤差レベルしか変化しないのでこの辺りで使っています。10bitだと最大値が1024となり、数字が1変わるとDutyが約0.1%変わるのでイメージしやすいですね。