vsergeev / python-periphery

A pure Python 2/3 library for peripheral I/O (GPIO, LED, PWM, SPI, I2C, MMIO, Serial) in Linux.
MIT License
519 stars 139 forks source link

PWM duty cycle is not kept when frequency is changed #68

Open niziak opened 6 months ago

niziak commented 6 months ago

As a user I assume that once set duty cycle to 50% (value 0.5) is kept when frequency is changed. Currently it is not possible to raise frequency over twice of initial value without zeroing duty cycle and setting it again to 0.5.

Exact issue was already described here: https://github.com/google-coral/edgetpu/issues/153

It will be nice to have interface which keeps duty cycle at initial percent level for any frequency without zeroing it and setting again every time.

vsergeev commented 6 months ago

There isn't an immediately obvious solution here because changes to both duty cycle and period / frequency can't be atomic. While it's true that python-periphery could preemptively update duty_cycle before changing period, this would also briefly drive the wrong duty cycle at the previous frequency until the period is updated. I don't think that's a good side effect for the library to have.

The most guidance we have from the sysfs documentation (https://docs.kernel.org/driver-api/pwm.html) is that the duty cycle "must be less than or equal to the period."

Perhaps one approach for frequency/period changes in the library would be to first disable PWM (through enable), update both duty cycle and period, and then re-enable PWM. Given that the most PWM applications are conveying information through the duty cycle, and frequency changes are atypical, this would probably address your concern and most use cases. However, it would be at the expense of a temporarily disabled output for frequency changes.