動作
analogWrite関数で指定する分解能(ビット数)を設定します。
「分解能(ビット数)」とは、analogWrite関数で指定できる値の細かさのような意味です。
analogWrite関数はデフォルトで8ビット(0〜255の256段階)でアナログ出力の値を指定します。これはArduinoボード間の差をなくすための仕様で、一番性能の低いボードに合わせています。
Arduino Uno R4やArduino Dueなどの高性能なボードでは、ハードウェアが8ビットより高い分解能に対応しています。analogWriteResolution関数を使用すると、これらのボードのハードウェア性能をフルに活用できます。
例えば、デフォルトの8ビット(0〜255)ではLEDの明るさは256段階ですが、12ビット(0〜4095)に変更すると4096段階になり、より滑らかに明るさを変化させることができます。
分解能の違いは次のようなイメージになります。上側が分解能8ビット、下側が分解能12ビットの場合です。左側のLEDを右側のスライダーで明るさ調整します。上側のスライダーは256段階なので目盛りも区別できてスライダーを動かすと少しカクカクします。下側のスライダーは4096段階なので、目盛りが細かくなり塗りつぶし状態に見え、スライダーは滑らかに動きます。
LEDの場合、人間の目は暗い部分が敏感に明るさの変化を判別します。もし、8ビット分解能で明るさ変化のステップが荒く感じる場合、analogWriteResolution関数で分解能を大きくすると滑らかな明るさ変化にすることができます。
analogWriteResolution関数は、主にAVRマイコン以外を搭載したボード(Arduino Uno R4、Arduino Due、Arduino Zero、Arduino MKRシリーズ、ESP32など)で使用できます。
AVRマイコンを搭載したボード(Arduino Uno R3、Arduino Nanoなど)のPWM分解能は8ビットに固定されています。これらのボードでanalogWriteResolutino関数を使用するとエラーになります(2026年時点)。
主な用途
analogWrite関数で指定する値の分解能を変更する場合に使用します。具体的には次のような場合です。
- LEDの明るさをより滑らかに変化させたい場合(特に暗い領域の変化を滑らかにしたい場合)
- DACピン(Digital-to-Analog Converter・デジタルアナログ変換器)の性能をフルに活用したい場合
analogRead関数の読み取り値をそのままanalogWrite関数に渡したい場合(analogReadとanalogWriteの分解能を揃えることで数値変換が不要になります)
書式
ESP32では書式が異なります。詳細はこのセクションの後半をご確認ください。
analogWriteResolution(value);| 引数 | value | 分解能をビット数で指定します。1〜32の整数値を指定できます。 指定した分解能はすべてのピンに適用されます。 |
| 戻り値 | なし | |
分解能はボードの性能にかかわらず設定できます(Arduino Uno R3などのAVR系を除く)。
例えばArduino Uno R4のハードウェア性能は分解能14ビットですが、それ以上の値を指定することができます。例えば分解能を16ビットに設定した場合、0〜65535(16ビット)を16383段階(14ビット)で使用することになります。
analogWriteResolutionで設定した分解能は、この関数以降に実行されるanalogWrite関数に有効です。ピンごとに分解能を変更したい場合、それぞれのピンに対するanalogWrite関数の前にanalogWriteResolution関数で分解能を指定します。
ESP32の書式
ESP32ではピンごとに分解能を指定できるため、書式は次のようになっています。
analogWriteResolution(pin, value);| 引数 | pin | 分解能を設定するピンを指定します。 |
value | 分解能をビット数で指定します。 無印シリーズ:1 〜 20 Sシリーズ・Cシリーズ:1 〜 14 | |
| 戻り値 | なし | |
ESP32では、すべてのピンで異なる分解能を設定できるわけではありません。
ESP32内部にはPWMモジュールが4基搭載されていて、PWM制御ピンが4ピンを超える場合はPWMモジュールが共有されます。そのため、例えば5ピンに対してそれぞれ異なる分解能を設定することはできません。
使用例
次のコードにより、analogWrite関数の分解能を変更することができます。
analogWriteResolution(8); // 8ビット(0〜255)に設定(デフォルト)
analogWriteResolution(10); // 10ビット(0〜1023)に設定
analogWriteResolution(12); // 12ビット(0〜4095)に設定サンプルスケッチ
次の回路とスケッチでは、23番ピンと19番ピンに接続したLEDを異なる分解能でアナログ制御しています。
このサンプルではピンごとに分解能を指定できるESP32を使用しています。ピンごとに指定できますので、setup関数内で最初に一度だけそれぞれのピンの分解能を指定しています。(一般的なArduinoボードのでは、ピンごとの分解能を変えたい場合、それぞれのanalogWrite関数の前に毎回分解能を指定する必要があります)
分解能の設定は、23番ピンの赤色LEDは分解能4ビット、19番ピンの緑色LEDは分解能8ビットとしています。
赤色LEDは分解能が低いため、明るさの変化がより荒くなります。点灯状態では違いが分かりづらいですが、消灯状態から点灯状態になる領域が特に違いが顕著になります。ボリュームをちょっとだけ右側に動かすと、分解能が高い緑色LEDはすぐに点灯しますが、赤色LEDは分解能が低いため、ボリュームをもう少し右側にずらさないと反応しません。
ボタンをクリックするとシミュレーターが動作します。スケッチを変更することもできます。変更した場合、シミュレーションを一度
ボタンをクリックして停止してから再度シミュレーターを開始してください。
一般的なArduinoボードでは、analogWriteResolutionで設定した分解能はすべてのピンに適用されますので、上のサンプルとは動作が異なります。
トラブルシューティング
analogWrite関数の値を変更したのに出力が思うように変わらない
analogWriteResolution関数で分解能を変更した場合、analogWrite関数に渡す値の範囲も変更する必要があります。
例えば、分解能を12ビットに指定した場合、analogWrite関数に渡す値の範囲は0〜4095になります。デフォルトの8ビットのつもりでanalogWrite(pin, 255);と指定すると、12ビットの最大値4095に対して255は約6%のデューティ比にしかならず、LEDがほとんど点灯しないように見えます。
分解能を変更した場合は必ずanalogWrite関数の指定値も変更するようにします。
analogWriteResolution(12); // 分解能を12ビットに変更
analogWrite(9, 255); // 分解能8ビット最大値255でも暗く点灯
analogWrite(9, 4095); // 分解能12ビット最大4095なので最大の明るさで点灯実践テクニック
analogWriteResolution関数を使ったテクニック集です。
analogReadとanalogWriteの分解能を揃える
analogRead関数の分解能とanalogWrite関数の分解能を揃えると、数値変換せずに読み取り値をそのまま出力値に使用することができます。
例えば、Arduino Uno R4ではanalogReadのデフォルト分解能は10ビットです。analogWrite関数の分解能も10ビットに揃えると、次のようにシンプルなスケッチになります。
#define SENSOR_PIN A0 // センサー接続ピン(アナログ電圧出力温度計など)
#define LED_PIN 9 // LED出力ピン
void setup() {
pinMode(LED_PIN, OUTPUT);
analogWriteResolution(10); // analogWriteの分解能を10ビットに変更
}
void loop() {
int value = analogRead(SENSOR_PIN); // 10ビット(0〜1023)で読み取り
analogWrite(LED_PIN, value); // そのまま出力(数値変換不要)
}分解能を変更しない場合、次のようにmap関数などで数値変換する必要があります。
// map関数を使用して数値変換する場合
int value = analogRead(SENSOR_PIN); // 0〜1023で読み取り
analogWrite(9, map(value, 0, 1023, 0, 255)); // 0〜255の範囲に変換して出力補足
代表的なボードのハードウェア分解能
主なArduinoボードのハードウェアの分解能は次のようになっています。
| ボード | PWM分解能 | DAC分解能 |
|---|---|---|
| Arduino Uno R3 Arduino Nano Arduino Mini | 8ビット※1 | - |
| Arduino Uno R4 | 12ビット | 12ビット |
| Arduino Mega | 8ビット※1 | - |
| Arduino Leonardo Arduino Micro | 8ビット※1 | - |
| Arduino MKRシリーズ | 12ビット | 10ビット |
| Arduino Zero | 12ビット | 10ビット |
| Arduino Due | 12ビット | 12ビット |
| ESP32 DevKitCシリーズ | 16ビット※2 | 8ビット |
| Raspberry Pi Pico | 16ビット | - |
なお、レジスタ直接操作により一部ピンで16ビットを指定することができます
※2:分解能を上げるとPWMの周波数が下がるというトレードオフがあります
(例:16ビット時は約1.2kHzが上限)
デフォルト値
analogWriteResolution関数で分解能を設定しない場合のデフォルト値は8ビットです。
これはAVRマイコン搭載ボードとの互換性を維持するためです。
PWM制御で使用しているAVRマイコンのタイマーが8ビット分解能であるため、Arduino言語のanalogWrite関数はデフォルトで0〜255の範囲(8ビット)で統一されています。
この仕様により、スケッチのボード間互換性が高くなっています。使用するボードの能力を最大限発揮したい場合は、analogWriteResolution関数で最大値を指定するようにします。
ボードのハードウェア分解能との関係
analogWriteResolution関数で指定したビット数と、ボードがサポートしているビット数が異なる場合、Arduinoが自動的に値を調整します(例えばArduino Uno R3は分解能8ビット固定ですが、10ビットを指定した場合、Arduinoが自動的に値を丸めます)。
指定したビット数がハードウェアの分解能より高い場合
ハードウェアが対応していない余分な下位ビットは切り捨てられます。
例えば、12ビットDACピンを持つArduino DueでanalogWriteResolution(16)と指定した場合、analogWrite関数に渡した値の上位12ビットだけが使用され、下位4ビットは切り捨てられます。

指定したビット数がハードウェアの分解能より低い場合
不足するビット分はゼロで埋められます。
例えば、12ビットDACピンを持つArduino Dueでは、analogWriteResolution(8)と指定した場合(デフォルト)、analogWrite関数に渡した8ビットの値の下位に4ビット分のゼロが追加されて12ビットに拡張されます。

ピンごとの設定
analogWriteResolution関数の設定は、その後のすべてのanalogWrite関数呼び出しに適用されます。ピンごとに異なる分解能を設定する場合、それぞれのピンに対するanalogWrite関数の前にanalogWriteResolutionで分解能を指定する必要があります。
なお、ESP32はピンごとに分解能を指定することができます。
Arduinoボード内部動作
Arduinoボードの内部動作は次のようになっています。次のイラストは、例としてArduino Uno R4の内部のようすを示しています。
analogWriteResolutionで分解能を10ビットに指定した場合、それ以降に呼び出されるanalogWriteのアナログ値は10ビットで解釈されます。
例えばanalogWrite(5, 500)の場合、アナログ値の「500」は分解能10ビット(0〜1023)に対して500、という意味になります。
しかし、Arduino Uno R4の内部PWMモジュールは分解能12ビットで動作していますので、分解能10ビットの「500」を分解能12ビットに変換、つまり4倍(2ビット左シフト)した「2000」がPWMモジュールのアナログ値として使用されます。

