Same LED and the same 220 Ω on D9 as
External LED. Nothing rewired.
analogWrite instead of digitalWrite, a counter running 0 to 255 and back, 8ms
a step. A full sweep is 2 × 256 × 8, so about 4.1 seconds.
The LED is never dim
It is fully on or fully off the entire time. There is no in between at the LED, and no pin on this board can output 3 V.
What changes is the fraction of each period the pin spends HIGH, which is the duty cycle. On D9 that switching happens at about 490 Hz, far faster than a photoreceptor resolves, so the eye adds it up and calls the result a brightness. The dimming happens in my retina, not on the breadboard.
That also decides where PWM works and where it does not. It needs something downstream that averages. The eye averages light, a motor's mass averages torque, a speaker cone averages pressure. No averager, no analog behaviour. A multimeter is an averager too, which is why it reads 2.51 V at duty 128 instead of flicking between 0 and 5.
What I learned
analogWriteis not analog. Only the~pins do it, D3 D5 D6 D9 D10 D11. Everything else takes the call and ignores the number- Underneath it is three hardware timers. D5 and D6 run about 980 Hz off Timer0, D9 and D10 about 490 Hz off Timer1
- Timer0 also drives
millis(),micros()anddelay(). Retune it for a smoother PWM frequency and every timing in the sketch quietly changes with it - Mean voltage is Vcc × duty / 255. Duty 128 reads 2.51 V, and the meter is the thing doing the averaging
- A servo is the exception. It averages nothing, it decodes pulse width as an angle, so duty cycle means nothing to it
- When nothing downstream averages, an RC low pass filter does it deliberately. Real analog voltage out the other side
- The sketch above is the blocking version,
forloop anddelay(8). I wrote themillis()one too and on the bench they are indistinguishable - Which is the point. Same output, and only one of them has room left in the loop to read a sensor. That gap is the only reason Part 2 works