ESP32 Confusing behaviour of PWM after soft reset
Consider:
from machine import Pin, PWM
pin = Pin(23, Pin.OUT)
pwm = PWM(pin, freq=38000, duty=338)
This works as expected. If you issue ctrl-d the waveform on the pin continues unchanged. If you paste the above code again, you cause a low output with
pwm.duty(0)
Subsequently changing the duty value to a value > 0 has no effect. This is surprising.
There is a simple workround of issuing pwm.deinit() at the start. The current state could be confusing to newcomers. It should either be documented or changed so that a soft reset de-initialises any PWM instance.
ports/esp32/machine_pwm: Add support for all PWM timers and modes.
ESP32 has 16 PWM channels with 8 separate timers, but current PWM implementation
forces user to share single timer between all channels. This commit
allows to use all 8 timers and does not break backward compatibility.
API additions:
- PWM initializer takes two new optional keyword arguments:
pwm.init(..., timer=0, speed_mode=PWM.HIGH_SPEED_MODE) - PWM class defines two new constants:
PWM.HIGH_SPEED_MODEandPWM.LOW_SPEED_MODE
Example:
from machine import Pin, PWM
pwm1 = PWM(Pin(22), freq=440)
pwm2 = PWM(Pin(23), freq=880)
# old (unchanged) behaviour: pwm1 and pwm2 both share frequency 880hz as they
# share the same high speed timer #0
pwm3 = PWM(Pin(2), freq=440, timer=0, speed_mode=PWM.LOW_SPEED_MODE)
pwm4 = PWM(Pin(15), freq=880, timer=1, speed_mode=PWM.LOW_SPEED_MODE)
# pwm3 has frequency 440hz and pwm4 880hz running on different timers
There are 4 low speed timers and 4 high speed timers on ESP32.