Skip to content

ESP32 ledc 1bit PWM Configuration is impossible #7067

Closed
@mhuttner

Description

@mhuttner

Board

ESP32

Device Description

ESP32-WROOM

Hardware Configuration

GPIO19 is LED PWM Pin

Version

v2.0.4

IDE Name

arduino-cli

Operating System

macOS 12.4

Flash frequency

40MHz

PSRAM enabled

no

Upload speed

921600

Description

ledcWrite makes it impossible to set the duty cycle to 50% for 1bit PWM because of this:

//Fixing if all bits in resolution is set = LEDC FULL ON
uint32_t max_duty = (1 << channels_resolution[chan]) - 1;
if(duty == max_duty){
duty = max_duty + 1;
}
ledc_set_duty(group, channel, duty);

when channels_resolution[chan] is 1 the possible duty cycles should be 0 (0%), 1 (50%) and 2(100%).
But for a duty of 1 max_duty will be 1 (1<<1 - 1) and since duty == max_duty the duty will be set to 2

Sketch

void setup() {
    uint8_t channel = 0;
    
    uint8_t bits = 1;
    uint8_t pin = 19;
    uint32_t freq = 40 * 1000 * 1000 // 40 MHz
    uint8_t duty = 1; // 50% duty

    ledcSetup(channel, freq, bits);
    ledcAttachPin(pin, channel);
    ledcWrite(channel, duty);
}

void loop(){}

Debug Message

None

Other Steps to Reproduce

No response

I have checked existing issues, online documentation and the Troubleshooting Guide

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.

Activity

mhuttner

mhuttner commented on Jul 31, 2022

@mhuttner
Author

Yes, but i can not manage to configure it to get output on the pin.

Removing the ledcWrite(channel, duty);results in no output.
If i comment out

if(duty == max_duty){ 
     duty = max_duty + 1; 
 } 

the example above works as expected and i get a PWM Signal.

P-R-O-C-H-Y

P-R-O-C-H-Y commented on Aug 1, 2022

@P-R-O-C-H-Y
Member

Hi @mhuttner, this part of code was added, because of a simple reason. If all bits from given resolution are set, then LEDC should be full on.

Quick example is on 8-bit resolution. The value is between 0-255, thats 8 bits. But without this piece of code the 255 won't be 100% on, you need to write 256 to be fully on, but it makes no sense.
According to @lbernstone mentioned link, I will make a PR to change 1-bit resolution to be 0 - fully off and 1 be 50%. It makes sense.
With 1 bit you can never set duty to 0% , 50% and 100%. Thats 3 values, you have only 2 available (0/1).

If you need to be able to set these, select 2 bits resolution.
Example using only 2 bits:
0 - always low
1 -> actually sets to 1 - 25% duty
2 -> actually sets to 2 - 50% duty
3 -> actually sets to 4 - always high (100% duty)

With this change, we loose the value 1 for all resolutions, but for most use cases, it affordable price.

P-R-O-C-H-Y

P-R-O-C-H-Y commented on Aug 1, 2022

@P-R-O-C-H-Y
Member

@mhuttner Can you please test your code with this change:

    if((duty == max_duty) && (max_duty != 1)) {
        duty = max_duty + 1;
    }

Thanks!

added this to the 2.0.5 milestone on Aug 1, 2022

6 remaining items

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

Status

Done

Relationships

None yet

Development

No branches or pull requests

Issue actions

    ESP32 ledc 1bit PWM Configuration is impossible · Issue #7067 · espressif/arduino-esp32