Skip to content

ledcWrite doesn't change duty cycle if duty cycle was changed less than one period ago and if using HS LEDC (channels 0-7) #5306

Closed
@joshua-8

Description

@joshua-8

I tried to search for an issue about this didn't find anything, but if this is a known issue, I apologize.

Hardware:

Board: ESP32 Dev Module (WROOM)
Core Installation version: 1.0.6
IDE name: Arduino IDE 1.8.13
Flash Frequency: 80MHz
PSRAM enabled: Disabled
Upload Speed: 921600
Computer OS: Windows 10
no additional hardware needed.

Description:

I found this issue when using LEDC to control a servo. Sometimes, seemingly randomly, the servo wouldn't go to the position I was telling it to.
ledcWrite was not always changing the duty cycle of the signal.

ledcWrite doesn't change the duty cycle if ledcWrite is used soon after it was just used (with a shorter delay than the period of the PWM wave) and if using an HS LEDC channel(0-7) (channels 8-15 work perfectly, with the duty cycle always changing)

I was able to make a sketch that could consistently reproduce the issue for me.

Sketch:

const int outputPin = 25; //pin to attach ledc to (ch1 on scope)
const int triggerPin = 27; //pin used to trigger oscilloscope at point of interest (ch2 on scope)

const int freq = 500;
const int ledChannel = 6; //0-7 have issue, 8-15 work fine
const int resolution = 10;

void setup() {
  pinMode(triggerPin, OUTPUT);
  digitalWrite(triggerPin, LOW);

  ledcSetup(ledChannel, freq, resolution);
  ledcAttachPin(outputPin, ledChannel);

  ledcWrite(ledChannel, 800); //start PWM output

  delayMicroseconds(2500); //wait until partway through first pulse

//  delay(2); // uncomment this line to wait until second pulse and the issue goes away

  digitalWrite(triggerPin, HIGH); //trigger oscilloscope
  ledcWrite(ledChannel, 200); //attempt to change duty cycle
}

void loop() {
}

This image shows that the PWM output keeps its duty cycle of 800/1023 instead of changing to 200/1023 as set later.

issue

Adding a delay to allow the first pulse to go by makes the duty cycle change on the next pulse. This is what I would expect to always happen

line19uncommented

The issue doesn't just appear when the "first pulse" is the first pulse since the program started. ledcWrite was used three times here, the first duty cycle runs for a while, then a second duty cycle is successfully set, and where the top blue line goes up, a third frequency was set, but doesn't appear.

three

Debug Messages:

none

Solutions:

Unfortunately, I don't know enough about ledc and esp32s to be able to fix this issue.

I did find a workaround that's good enough for my servo project: if I continuously use ledcWrite from within a loop, if one call of ledcWrite doesn't work, the next one (or how ever many it takes to wait for a new cycle) will.

I know I could just use channels 8-15 since they don't have the issue, but I have a project that uses 9 pwm signals

I was hoping that I could call ledcWrite only when I need to change the duty cycle, to optimize the speed of my program.

As a related note, ledcRead returns the value that was most recently set even if the duty cycle didn't change to the new value, so I can't use that to detect if ledcWrite needs to be used.

If anyone has an idea for a better workaround, or knows why this issue happens, I would be very interested in hearing it.

I would be happy to help with any testing, or provide more information if needed.

Thank you, esp32 community, for all your work!

Activity

stale

stale commented on Sep 19, 2021

@stale

[STALE_SET] This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 14 days if no further activity occurs. Thank you for your contributions.

removed their assignment
on Oct 6, 2021
stale

stale commented on Oct 6, 2021

@stale

[STALE_CLR] This issue has been removed from the stale queue. Please ensure activity to keep it openin the future.

removed
Status: StaleIssue is stale stage (outdated/stuck)
on Oct 6, 2021
oycq

oycq commented on Dec 1, 2021

@oycq

same Problem

P-R-O-C-H-Y

P-R-O-C-H-Y commented on Jan 17, 2022

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

Hi @joshua-8 and @oycq
Issue is currently being fixed on ESP-IDF side. Once the fix is merged and updated in Arduino I will let you know :)
Thanks for reporting the issue.

5 remaining items

added this to the 2.0.3 milestone on Feb 24, 2022
VojtechBartoska

VojtechBartoska commented on Mar 17, 2022

@VojtechBartoska
Contributor

Hello @joshua-8, this problem was fixed in ESP-IDF side, changes will take effect in upcoming Arduino core release 2.0.3.

moved this from In Progress to In Review in Arduino ESP32 Core Project Roadmapon Mar 23, 2022
P-R-O-C-H-Y

P-R-O-C-H-Y commented on Mar 31, 2022

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

Hi @joshua-8, can you test your issue with the 2.0.3-RC1 release? So we can close this ;)

joshua-8

joshua-8 commented on Mar 31, 2022

@joshua-8
Author

With 2.0.3-RC1, the issue is fixed!

I tested with the code I posted when I opened this issue, and the duty cycle now changes:
the frequency changes now

Thank you to everyone who worked on fixing this problem!

VojtechBartoska

VojtechBartoska commented on Apr 1, 2022

@VojtechBartoska
Contributor

@joshua-8 Perfect, thank you for testing and contribution!

Repository owner moved this from In Review to Done in Arduino ESP32 Core Project Roadmapon Apr 1, 2022
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

      Participants

      @oycq@joshua-8@VojtechBartoska@P-R-O-C-H-Y

      Issue actions

        ledcWrite doesn't change duty cycle if duty cycle was changed less than one period ago and if using HS LEDC (channels 0-7) · Issue #5306 · espressif/arduino-esp32