-
Notifications
You must be signed in to change notification settings - Fork 7.7k
Open
Labels
Status: In Progress ⚠️Issue is in progressIssue is in progress
Description
//Fixing if all bits in resolution is set = LEDC FULL ON
uint32_t max_duty = (1 << bus->channel_resolution) - 1;
if ((duty == max_duty) && (max_duty != 1)) {
duty = max_duty + 1;
If a user want to set resolution as 5 and set duty 31/32, it should be failed.
Duty ratio should be like as below.
channel_resolution = 5, duty = 0 → duty ratio = 0/32
channel_resolution = 5, duty = 1 → duty ratio = 1/32
channel_resolution = 5, duty = 2 → duty ratio = 2/32
...
channel_resolution = 5, duty = 30 → duty ratio = 30/32
channel_resolution = 5, duty = 31 → duty ratio = 31/32
channel_resolution = 5, duty = 32 → duty ratio = 32/32
However, current code makes it like below.
channel_resolution = 5, duty = 31 → duty ratio = 32/32 -> WRONG RATIO
channel_resolution = 5, duty = 32 → duty ratio = 32/32
The code on top just need to be deleted.
Metadata
Metadata
Assignees
Labels
Status: In Progress ⚠️Issue is in progressIssue is in progress
Type
Projects
Milestone
Relationships
Development
Select code repository
Activity
SuGlider commentedon Apr 7, 2025
Looking into the LEDC documentation, we can verify that the Duty goes from 0 to 2^resolution.
Using 5 buts resolution, duty goes from 0 to 32 (33 levels).
Duty 0 = 0% ... Duty = 32 = 100%.
But... Arduino API says that Duty shoud go from 0 to (2^resolution) - 1.
Therefore, for Arduino API compatibility, the resolution is 5 bits is like this:
Duty 0 = 0% ... Duty 31 = 100%.
Thus, we have a different metric for resolution.
In such case, ESP32 Arduino Core has decided to implement the Arduino API metric system.
channel_resolution = 5, duty = 31 → duty ratio = 32/32 -> Arduino API compatible
channel_resolution = 5, duty = 32 → duty ratio = 32/32 -> IDF comaptible
SuGlider commentedon Apr 7, 2025
@scrtrees - What we could change here is that
ledcWrite()
could act as IDF defines (0..32) andanalogWrite()
act as Arduino defines (0..31). In that case, duty = 31 would behave as 100%, mapping it to aledcWrite(pin, 32)
.In other words, the code you have pointed out shall be moved to
analogWrite()
and removed fromledcWrite()
.