
ArduinoのanalogWrite関数を使用せずに、digitalWriteでPWM出力を行う方法です。
概要
Arduino UNO R3にあるオンボードLED(13ピン)の明るさ制御を行おうとしたのですが、analogWrite関数は13ピンでは機能しないようです。仕様外なので当然です。が訳あってオンボードLEDの明るさ制御/PWM出力をしたかったので、analogWriteを使用せずにPWM出力を行ってみました。(R4ではanalogWrite関数でオンボードLEDの制御は可能でした)
オンボードLEDにanalogWriteをテスト
Arduino UNO R3にあるスケッチ例「Fade」のledピンを9ピン ⇒ 13ピンに変更して実行してみました。

なめらかにLEDが点滅するはずですが、単純な点滅になってしまいます。analogWriteが13ピンに対応していないようです。でも点滅はする??

同じスケッチでもR4ではなめらかに点滅。R4ではanalogWrite/PWMの対応ピンが多いようです。R3に比べてR4の方がLEDが随分明るいですね。
digitalWriteでPWM出力
時間監視でピンのHIGH/LOWを切り替えてPWM波形を作ってます。
//analogWriteを使わずにPWM出力
//2025/04/06 imo Lab.
//https://garchiving.com
uint32_t currentTime, LEDTimer, dutyTimer;
uint8_t duty;
int brightness = 0;
int fadeAmount = 5;
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
currentTime = micros();
if (digitalRead(LED_BUILTIN) == HIGH && currentTime - LEDTimer > 2000 * brightness / 100) {
LEDTimer = currentTime;
digitalWrite(LED_BUILTIN, LOW);
} else if (digitalRead(LED_BUILTIN) == LOW && currentTime - LEDTimer > 2000 * (100 - brightness) / 100) {
LEDTimer = currentTime;
digitalWrite(LED_BUILTIN, HIGH);
}
if (currentTime - dutyTimer > 50000) {
dutyTimer = currentTime;
brightness = brightness + fadeAmount;
if (brightness <= 0 || brightness >= 100) {
fadeAmount = -fadeAmount;
}
}
}
PWMの周波数は500Hz。デューティ比はスケッチ例の「Fade」と同様に徐々に変化するようにしてます。

さっそくプログラム書き込んでテスト。無事にオンボードLEDの明るさが制御できてそうです。

波形を確認してます。500Hzに対して若干低め。1000Hzで試したときは10~20Hzくらい低めに出ていました。ポーリングでは精度に限界はあるかもしれません。特にデューティ0%や100%付近では無理があるかも。正確さがそれほど必要ないならこの方法でもOKかと。
コメント