ESP32 ledc channel bank semantics gotcha

ESP32 ledc timer channels for high and low frequency banks have some subtle differences

The ESP32 (as found in the SparkFun ESP32Thing board) has 16 PWM timers that can be used by the ledc (LED controller) channel setup API.

There are two banks of 8 PWM timer channels which can all be brought out to 16 different GPIO pins; not any set of pins, but 2, 4, 5, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 26, 27 worked for me on the Thing.

What tripped me up for quite some time was that, while both the low and high frequency banks worked fine on a 13 bit width and 5000 Hz, setting the output value to 0 on the upper bank (timer channel 8..15) would essentially be ignored, leaving the PWM output at whatever previous non-zero driving value, while the lower 8 channels (0..7) would reliably go to a 0 duty cycle.

I found a number of theories and fixes on a number of message boards, none of which really nailed the problem: the two banks can operate at the same frequency range, but have different interpretations for a zero input value, probably due to them using different types of hardware core components for the two banks on the SoC.

As a workaround, you can just set the output value to 1 (out of 8191). I am note sure if that gives you a zero duty cycle or an almost-zero, but it worked fine for my purpose which was to drive 16 solenoids via two ULN2803s.