analogWrite() の解説と実装リファレンス

記事内には広告が含まれています。

【概要】

analogWrite() は、Arduinoプラットフォームにおいてデジタル出力ピンを用いて擬似的なアナログ電圧を生成するための関数である。この関数は、PWM(Pulse Width Modulation:パルス幅変調)という技術を利用しており、ピンの電圧を高速に「High」と「Low」の間で切り替えることで、平均的な電圧レベルを擬似的に制御する。

本関数は、実際に連続的な電圧を出力するのではなく、高速なパルス信号の「デューティ比(Duty Cycle)」を操作することで、LEDの輝度調整やDCモータの速度制御を実現する。

【仕様】

  • 関数シグネチャ: void analogWrite(uint8_t pin, int value)
  • 引数:
    • pin: PWM出力に対応しているデジタルピンの番号。
    • value: デューティ比を指定する数値。標準的な8ビット解像度の環境では、0から255の範囲で指定する。
  • 戻り値: void(戻り値なし)
  • データ型: pin は uint8_t、value は int として定義される。
  • 初期状態: 指定したピンがPWM対応の場合、analogWrite(pin, 0) はLow、analogWrite(pin, 255) はHigh(または最大デューティ比)として動作する。

【技術的特徴】

  • ハードウェアタイマーの活用:
    analogWrite() は、MCU(マイコン)内部のハードウェアタイマー(Timer0, Timer1, Timer2など)に紐付いて動作する。これにより、CPUが他の処理を実行している間も、ハードウェアがバックグラウンドでPWM信号を生成し続けることが可能である。
  • 解像度(Resolution):
    Arduino Unoなどの標準的なボードでは、PWMの解像度は8ビット(256段階)である。しかし、ESP32や一部のAVR/ARMマイコンでは、ハードウェア構成により10ビットやそれ以上の解像度が利用可能な場合があり、その場合は value の最大値が変化する可能性がある。
  • analogRead() との比較:
    analogRead() はADC(アナログ-デジタル変換器)を用いて「電圧を数値として読み取る」入力操作であるのに対し、analogWrite() は「数値をパルス信号として出力する」出力操作である。物理的な電圧を変化させるものではないことに注意が必要である。

【注意点】

  • ピンの制約:
    すべてのデジタルピンがPWMに対応しているわけではない。例えばArduino Unoでは、3, 5, 6, 9, 10, 11ピンのみがPWMに対応している。使用するボードのデータシートを確認することが不可欠である。
  • 周波数の変動:
    PWMの周波数は、ボードおよび使用するピンによって異なる。標準的なArduino環境では約490Hzまたは980Hzであることが多いが、高周波が必要な用途(高精細なLED制御や特定のモーター制御)では、標準の analogWrite() では不十分な場合がある。
  • 割り込みの影響:
    PWM生成自体はハードウェアタイマーによって制御されるため、CPUの割り込み処理によって信号が途切れることはない。ただし、analogWrite() の呼び出し自体はメインループ内で行われるため、呼び出しのタイミングによって次のデューティ比への更新に極微小な差異が生じる可能性がある。
  • 最大負荷への注意:
    PWM信号を直接大きな電流を消費するデバイス(高輝度LEDや大出力モータ)に接続することは避けなければならない。PWM出力ピンの電流許容範囲を超過する場合は、MOSFETやトランジスタ等のドライバ回路を介在させる必要がある。

【サンプルコード】

/* 
 * PWMを用いたLEDの輝度制御(フェード)の例 
 * ピン9がPWM対応であることを前提とする 
 */
const int ledPin = 9; 

void setup() {
  pinMode(ledPin, OUTPUT); 
}

void loop() {
  // 輝度を0から255まで徐々に上げる
  for (int brightness = 0; brightness <= 255; brightness++) {
    analogWrite(ledPin, brightness); 
    delay(10); 
  }

  // 輝度を255から0まで徐々に下げる
  for (int brightness = 255; brightness >= 0; brightness--) {
    analogWrite(ledPin, brightness); 
    delay(10); 
  }
}

【活用例】

  • LEDの調光: 複数のLEDの輝度を個別に制御し、環境光のシミュレーションやインジケータの視認性調整を行う。
  • DCモータの速度制御:
    PWM信号をモータードライバー(L298N等)に入力し、デューティ比を変化させることでモータの回転速度を任意に制御する。
  • サーボモータの駆動:
    (Servo.hライブラリを使用しない場合)特定のPWM信号(50Hzなど)とパルス幅を組み合わせることで角度を制御する。
  • スピーカーへの簡易的な音源出力:
    PWM信号を高速に変化させることで、単純な電子音や矩形波を生成する。

コメント

タイトルとURLをコピーしました